Skip to content
dukascopy-node

Download free forex tick data for backtesting

Download free historical forex tick data and 1-minute candles as CSV for backtesting, for EUR/USD, gold and hundreds of other currency pairs.

Backtesting a forex strategy needs clean historical data: every tick with its bid and ask price, or candles at the timeframe your strategy trades on. dukascopy-node downloads both for free, as CSV files you can load into Python, R, Excel or your own backtester. This guide builds a typical dataset for EUR/USD.

Every pair has an id that you pass with -i in the CLI or instrument in Node.js: eurusd, gbpusd, usdjpy, or xauusd for gold. Browse the forex majors, crosses and metals. Each instrument page shows how far back its data goes for every timeframe.

Ticks are every price change, with the best bid and ask price at that moment. They are the most detailed data you can backtest on, and the right choice when spreads or execution timing matter:

Terminal window
npx dukascopy-node -i eurusd -from 2020-03-30 -to 2020-03-31 -t tick -f csv -v
import { getHistoricalRates } from 'dukascopy-node';
const ticks = await getHistoricalRates({
instrument: 'eurusd',
dates: { from: '2020-03-30', to: '2020-03-31' },
timeframe: 'tick',
format: 'csv'
});

The CLI saves the result to download/eurusd-tick-2020-03-30-2020-03-31.csv:

Output
timestamp,askPrice,bidPrice,askVolume,bidVolume
1585526400104,1.11369,1.11361,0.75,0.75
1585526400256,1.11371,1.11361,0.94,1.5

Timestamps are Unix milliseconds in UTC, and volumes are in millions of units.

Tip

Tick data is large: a month of one pair can take hundreds of megabytes. Start with a day, check the output, then extend the range. See large downloads.

Many strategies trade on bars rather than ticks, and candles are much smaller. Pick the timeframe your strategy uses: s1 (one second), m1, m5, m15, m30, h1, h4, d1 or mn1. A year of 1-minute EUR/USD candles:

Terminal window
npx dukascopy-node -i eurusd -from 2023-01-01 -to 2024-01-01 -t m1 -f csv -v
const candles = await getHistoricalRates({
instrument: 'eurusd',
dates: { from: '2023-01-01', to: '2024-01-01' },
timeframe: 'm1',
format: 'csv'
});

The file, download/eurusd-m1-bid-2023-01-01-2024-01-01.csv, starts with the header timestamp,open,high,low,close,volume. Candles use bid prices by default. Add -p ask (priceType: 'ask' in Node.js) for ask candles, or download both if your backtest models the spread.

The CSV works with any tool. In Python with pandas:

import pandas as pd
df = pd.read_csv('download/eurusd-m1-bid-2023-01-01-2024-01-01.csv')
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms', utc=True)
df = df.set_index('timestamp')

For a spreadsheet, write readable dates instead of Unix timestamps with --date-format "YYYY-MM-DD HH:mm:ss", and convert them to your time zone with --time-zone. See date formats and time zones.

In Node.js you can skip the file: use format: 'array' or format: 'json' and pass the data straight to your backtesting code. See output formats.

  • Weekends have no data. The forex market closes from Friday evening to Sunday evening (UTC), so there are no ticks or candles for those hours, and holidays can be quiet too. That is expected, not a gap to fill.
  • Each pair starts at a different date, and finer timeframes often start later than daily candles. Check the instrument page before choosing a start date. A range that starts earlier begins at the first available data.
  • Bid and ask differ. Ticks include both prices. For candles, choose bid or ask, or download both to model the spread.
  • Timestamps are UTC unless you convert them, which matters for strategies built around trading sessions.
  • Make long downloads resilient. Add --retries 3 to retry failed requests, and --cache so that extending the range later does not download the same data again. See errors and empty data and using the cache.