Datasets

Forex

Introduction

This page explains how to request, manipulate, and visualize historical Forex data.

Create Subscriptions

Follow these steps to subscribe to a Forex security:

  1. Load the assembly files and data types in their own cell.
  2. #load "../Initialize.csx"
  3. Import the data types.
  4. #load "../QuantConnect.csx"
    #r "../Microsoft.Data.Analysis.dll"
    
    using QuantConnect;
    using QuantConnect.Data;
    using QuantConnect.Algorithm;
    using QuantConnect.Research;
    using QuantConnect.Indicators;
    using QuantConnect.Securities.Forex;
    using Microsoft.Data.Analysis;
  5. Create a QuantBook.
  6. var qb = new QuantBook();
    qb = QuantBook()
  7. (Optional) Set the time zone to the data time zone.
  8. qb.set_time_zone(TimeZones.UTC);
    qb.set_time_zone(TimeZones.UTC)
  9. Call the AddForexadd_forex method with a ticker and then save a reference to the Forex Symbol.
  10. var eurusd = qb.AddForex("EURUSD").Symbol;
    var gbpusd = qb.AddForex("GBPUSD").Symbol;
    eurusd = qb.add_forex("EURUSD").symbol
    gbpusd = qb.add_forex("GBPUSD").symbol

To view all of the available Forex pairs, see Supported Assets.

Get Historical Data

You need a subscription before you can request historical data for a security. On the time dimension, you can request an amount of historical data based on a trailing number of bars, a trailing period of time, or a defined period of time. On the security dimension, you can request historical data for a single Forex pair, a subset of the pairs you created subscriptions for in your notebook, or all of the pairs in your notebook.

Trailing Number of Bars

To get historical data for a number of trailing bars, call the Historyhistory method with the Symbol object(s) and an integer.

// Slice objects
var singleHistorySlice = qb.History(eurusd, 10);
var subsetHistorySlice = qb.History(new[] {eurusd, gbpusd}, 10);
var allHistorySlice = qb.History(10);

// QuoteBar objects
var singleHistoryQuoteBars = qb.History<QuoteBar>(eurusd, 10);
var subsetHistoryQuoteBars = qb.History<QuoteBar>(new[] {eurusd, gbpusd}, 10);
var allHistoryQuoteBars = qb.History<QuoteBar>(qb.Securities.Keys, 10);
# DataFrame
single_history_df = qb.history(eurusd, 10)
subset_history_df = qb.history([eurusd, gbpusd], 10)
all_history_df = qb.history(qb.securities.keys, 10)

# Slice objects
all_history_slice = qb.history(10)

# QuoteBar objects
single_history_quote_bars = qb.history[QuoteBar](eurusd, 10)
subset_history_quote_bars = qb.history[QuoteBar]([eurusd, gbpusd], 10)
all_history_quote_bars = qb.history[QuoteBar](qb.securities.keys, 10)

The preceding calls return the most recent bars, excluding periods of time when the exchange was closed.

Trailing Period of Time

To get historical data for a trailing period of time, call the Historyhistory method with the Symbol object(s) and a TimeSpantimedelta.

// Slice objects
var singleHistorySlice = qb.History(eurusd, TimeSpan.FromDays(3));
var subsetHistorySlice = qb.History(new[] {eurusd, gbpusd}, TimeSpan.FromDays(3));
var allHistorySlice = qb.History(10);

// QuoteBar objects
var singleHistoryQuoteBars = qb.History<QuoteBar>(eurusd, TimeSpan.FromDays(3), Resolution.Minute);
var subsetHistoryQuoteBars = qb.History<QuoteBar>(new[] {eurusd, gbpusd}, TimeSpan.FromDays(3), Resolution.Minute);
var allHistoryQuoteBars = qb.History<QuoteBar>(qb.Securities.Keys, TimeSpan.FromDays(3), Resolution.Minute);

// Tick objects
var singleHistoryTicks = qb.History<Tick>(eurusd, TimeSpan.FromDays(3), Resolution.Tick);
var subsetHistoryTicks = qb.History<Tick>(new[] {eurusd, gbpusd}, TimeSpan.FromDays(3), Resolution.Tick);
var allHistoryTicks = qb.History<Tick>(qb.Securities.Keys, TimeSpan.FromDays(3), Resolution.Tick);
# DataFrame of quote data (Forex data doesn't have trade data)
single_history_df = qb.history(eurusd, timedelta(days=3))
subset_history_df = qb.history([eurusd, gbpusd], timedelta(days=3))
all_history_df = qb.history(qb.securities.keys, timedelta(days=3))

# DataFrame of tick data
single_history_tick_df = qb.history(eurusd, timedelta(days=3), Resolution.TICK)
subset_history_tick_df = qb.history([eurusd, gbpusd], timedelta(days=3), Resolution.TICK)
all_history_tick_df = qb.history(qb.securities.keys, timedelta(days=3), Resolution.TICK)

# Slice objects
all_history_slice = qb.history(timedelta(days=3))

# QuoteBar objects
single_history_quote_bars = qb.history[QuoteBar](eurusd, timedelta(days=3), Resolution.MINUTE)
subset_history_quote_bars = qb.history[QuoteBar]([eurusd, gbpusd], timedelta(days=3), Resolution.MINUTE)
all_history_quote_bars = qb.history[QuoteBar](qb.securities.keys, timedelta(days=3), Resolution.MINUTE)

# Tick objects
single_history_ticks = qb.history[Tick](eurusd, timedelta(days=3), Resolution.TICK)
subset_history_ticks = qb.history[Tick]([eurusd, gbpusd], timedelta(days=3), Resolution.TICK)
all_history_ticks = qb.history[Tick](qb.securities.keys, timedelta(days=3), Resolution.TICK)

The preceding calls return the most recent bars or ticks, excluding periods of time when the exchange was closed.

Defined Period of Time

To get historical data for a specific period of time, call the History method with the Symbol object(s), a start DateTimedatetime, and an end DateTimedatetime. The start and end times you provide are based in the notebook time zone.

var startTime = new DateTime(2021, 1, 1);
var endTime = new DateTime(2021, 2, 1);

// Slice objects
var singleHistorySlice = qb.History(eurusd, startTime, endTime);
var subsetHistorySlice = qb.History(new[] {eurusd, gbpusd}, startTime, endTime);
var allHistorySlice = qb.History(qb.Securities.Keys, startTime, endTime);

// QuoteBar objects
var singleHistoryQuoteBars = qb.History<QuoteBar>(eurusd, startTime, endTime, Resolution.Minute);
var subsetHistoryQuoteBars = qb.History<QuoteBar>(new[] {eurusd, gbpusd}, startTime, endTime, Resolution.Minute);
var allHistoryQuoteBars = qb.History<QuoteBar>(qb.Securities.Keys, startTime, endTime, Resolution.Minute);

// Tick objects
var singleHistoryTicks = qb.History<Tick>(eurusd, startTime, endTime, Resolution.Tick);
var subsetHistoryTicks = qb.History<Tick>(new[] {eurusd, gbpusd}, startTime, endTime, Resolution.Tick);
var allHistoryTicks = qb.History<Tick>(qb.Securities.Keys, startTime, endTime, Resolution.Tick);
start_time = datetime(2021, 1, 1)
end_time = datetime(2021, 2, 1)

# DataFrame of quote data (Forex data doesn't have trade data)
single_history_df = qb.history(eurusd, start_time, end_time)
subset_history_df = qb.history([eurusd, gbpusd], start_time, end_time)
all_history_df = qb.history(qb.securities.keys, start_time, end_time)

# DataFrame of tick data
single_history_tick_df = qb.history(eurusd, start_time, end_time, Resolution.TICK)
subset_history_tick_df = qb.history([eurusd, gbpusd], start_time, end_time, Resolution.TICK)
all_history_tick_df = qb.history(qb.securities.keys, start_time, end_time, Resolution.TICK)

# QuoteBar objects
single_history_quote_bars = qb.history[QuoteBar](eurusd, start_time, end_time, Resolution.MINUTE)
subset_history_quote_bars = qb.history[QuoteBar]([eurusd, gbpusd], start_time, end_time, Resolution.MINUTE)
all_history_quote_bars = qb.history[QuoteBar](qb.securities.keys, start_time, end_time, Resolution.MINUTE)

# Tick objects
single_history_ticks = qb.history[Tick](eurusd, start_time, end_time, Resolution.TICK)
subset_history_ticks = qb.history[Tick]([eurusd, gbpusd], start_time, end_time, Resolution.TICK)
all_history_ticks = qb.history[Tick](qb.securities.keys, start_time, end_time, Resolution.TICK)

The preceding calls return the bars or ticks that have a timestamp within the defined period of time.

Resolutions

The following table shows the available resolutions and data formats for Forex subscriptions:

ResolutionTradeBarQuoteBarTrade TickQuote Tick
TickTICKgreen check
SecondSECOND
green check
MinuteMINUTE
green check
HourHOUR
green check
DailyDAILY
green check

Markets

The only market available for Forex pairs is Market.OandaMarket.OANDA.

Data Normalization

The data normalization mode doesn't affect data from history request. If you change the data normalization mode, it won't change the outcome.

Wrangle Data

You need some historical data to perform wrangling operations. The process to manipulate the historical data depends on its data type. To display pandas objects, run a cell in a notebook with the pandas object as the last line. To display other data formats, call the print method.

You need some historical data to perform wrangling operations. Use LINQ to wrangle the data and then call the Console.WriteLine method in a Jupyter Notebook to display the data. The process to manipulate the historical data depends on its data type.

DataFrame Objects

If the Historyhistory method returns a DataFrame, the first level of the DataFrame index is the encoded Forex Symbol and the second level is the EndTimeend_time of the data sample. The columns of the DataFrame are the data properties.

DataFrame of two Forex pairs

To select the historical data of a single Forex, index the loc property of the DataFrame with the Forex Symbol.

all_history_df.loc[eurusd]  # or all_history_df.loc['EURUSD']
DataFrame of one Forex

To select a column of the DataFrame, index it with the column name.

all_history_df.loc[eurusd]['close']
Series of close values

If you request historical data for multiple Forex pairs, you can transform the DataFrame so that it's a time series of close values for all of the Forex pairs. To transform the DataFrame, select the column you want to display for each Forex pair and then call the unstack method.

all_history_df['close'].unstack(level=0)

The DataFrame is transformed so that the column indices are the Symbol of each Forex pair and each row contains the close value.

DataFrame of one Forex

The historical data methods don't return DataFrame objects, but you can create one for efficient vectorized data wrangling.

using Microsoft.Data.Analysis; 

var columns = new DataFrameColumn[] {
    new PrimitiveDataFrameColumn("Time", history.Select(x => x[eurusd].EndTime)),
    new DecimalDataFrameColumn("EURUSD Open", history.Select(x => x[eurusd].Open)),
    new DecimalDataFrameColumn("EURUSD High", history.Select(x => x[eurusd].High)),
    new DecimalDataFrameColumn("EURUSD Low", history.Select(x => x[eurusd].Low)),
    new DecimalDataFrameColumn("EURUSD Close", history.Select(x => x[eurusd].Close))
};
var df = new DataFrame(columns);
df
Historical C# dataframe

To select a particular column of the DataFrame, index it with the column name.

df["EURUSD close"]
Historical C# dataframe column

Slice Objects

If the Historyhistory method returns Slice objects, iterate through the Slice objects to get each one. The Slice objects may not have data for all of your Forex subscriptions. To avoid issues, check if the Slice contains data for your Forex pair before you index it with the Forex Symbol.

foreach (var slice in allHistorySlice) {
    if (slice.QuoteBars.ContainsKey(eurusd))
    {
        var quoteBar = slice.QuoteBars[eurusd];
    }
}
for slice in all_history_slice:
        if slice.quote_bars.contains_key(eurusd):
        quote_bar = slice.quote_bars[eurusd]

You can also iterate through each QuoteBar in the Slice.

foreach (var slice in allHistorySlice)
{
    foreach (var kvp in slice.QuoteBars)
    {
        var symbol = kvp.Key;
        var quoteBar = kvp.Value;
    }
}
for slice in all_history_slice:
    for kvp in slice.quote_bars:
        symbol = kvp.key
        quote_bar = kvp.value

You can also use LINQ to select each QuoteBar in the Slice for a given Symbol.

var quoteBars = allHistorySlice.Where(slice => slice.QuoteBars.ContainsKey(eurusd)).Select(slice => slice.QuoteBars[eurusd]);

QuoteBar Objects

If the Historyhistory method returns QuoteBar objects, iterate through the QuoteBar objects to get each one.

foreach (var quoteBar in singleHistoryQuoteBars)
{
    Console.WriteLine(quoteBar);
}
for quote_bar in single_history_quote_bars:
    print(quote_bar)

If the Historyhistory method returns QuoteBars, iterate through the QuoteBars to get the QuoteBar of each Forex pair. The QuoteBars may not have data for all of your Forex subscriptions. To avoid issues, check if the QuoteBars object contains data for your security before you index it with the Forex Symbol.

foreach (var quoteBars in allHistoryQuoteBars)
{
    if (quoteBars.ContainsKey(eurusd))
    {
        var quoteBar = quoteBars[eurusd];
    }
}
for quote_bars in all_history_quote_bars:
    if quote_bars.contains_key(eurusd):
        quote_bar = quote_bars[eurusd]

You can also iterate through each of the QuoteBars.

foreach (var quoteBars in allHistoryQuoteBars)
{
    foreach (var kvp in quoteBars)
    {
        var symbol = kvp.Key;
        var quoteBar = kvp.Value;
    }
}
for quote_bars in all_history_quote_bars:
    for kvp in quote_bars:
        symbol = kvp.key
        quote_bar = kvp.value

Tick Objects

If the Historyhistory method returns TickTICK objects, iterate through the TickTICK objects to get each one.

foreach (var tick in singleHistoryTicks)
{
    Console.WriteLine(tick);
}
for tick in single_history_ticks:
    print(tick)

If the Historyhistory method returns Ticks, iterate through the Ticks to get the TickTICK of each Forex pair. The Ticks may not have data for all of your Forex subscriptions. To avoid issues, check if the Ticks object contains data for your security before you index it with the Forex Symbol.

foreach (var ticks in allHistoryTicks)
{
    if (ticks.ContainsKey(eurusd))
    {
        var tick = ticks[eurusd];
    }
}
for ticks in all_history_ticks:
    if ticks.contains_key(eurusd):
        ticks = ticks[eurusd]

You can also iterate through each of the Ticks.

foreach (var ticks in allHistoryTicks)
{
    foreach (var kvp in ticks)
    {
        var symbol = kvp.Key;
        var tick = kvp.Value;
    }
}
for ticks in all_history_ticks:
    for kvp in ticks:
        symbol = kvp.key
        tick = kvp.value

The Ticks objects only contain the last tick of each security for that particular timeslice

Plot Data

You need some historical Forex data to produce plots. You can use many of the supported plotting librariesPlot.NET package to visualize data in various formats. For example, you can plot candlestick and line charts.

Candlestick Chart

Follow these steps to plot candlestick charts:

  1. Get some historical data.
  2. history = qb.history(eurusd, datetime(2021, 11, 26), datetime(2021, 12, 8), Resolution.DAILY).loc[eurusd]
    var history = qb.History<QuoteBar>(eurusd, new DateTime(2021, 11, 26), new DateTime(2021, 12, 8), Resolution.Daily);
  3. Import the plotlyPlot.NET library.
  4. import plotly.graph_objects as go
    #r "../Plotly.NET.dll"
    using Plotly.NET;
    using Plotly.NET.LayoutObjects;
  5. Create a Candlestick.
  6. candlestick = go.Candlestick(x=history.index,
                                 open=history['open'],
                                 high=history['high'],
                                 low=history['low'],
                                 close=history['close'])
    var chart = Chart2D.Chart.Candlestick<decimal, decimal, decimal, decimal, DateTime, string>(
        history.Select(x => x.Open),
        history.Select(x => x.High),
        history.Select(x => x.Low),
        history.Select(x => x.Close),
        history.Select(x => x.EndTime)
    );
  7. Create a Layout.
  8. layout = go.Layout(title=go.layout.Title(text='EURUSD OHLC'),
                       xaxis_title='Date',
                       yaxis_title='Price',
                       xaxis_rangeslider_visible=False)
    LinearAxis xAxis = new LinearAxis();
    xAxis.SetValue("title", "Time");
    LinearAxis yAxis = new LinearAxis();
    yAxis.SetValue("title", "Price ($)");
    Title title = Title.init($"{eurusd} OHLC");
    
    Layout layout = new Layout();
    layout.SetValue("xaxis", xAxis);
    layout.SetValue("yaxis", yAxis);
    layout.SetValue("title", title);
  9. Create the Figure.
  10. fig = go.Figure(data=[candlestick], layout=layout)
  11. Assign the Layout to the chart.
  12. chart.WithLayout(layout);
  13. Show the Figure.
  14. fig.show()
    HTML(GenericChart.toChartHTML(chart))

    Candlestick charts display the open, high, low, and close prices of the security.

Candlestick plot of EURUSD OHLC Candlestick plot of EURUSD OHLC

Line Chart

Follow these steps to plot line charts using built-in methodsPlotly.NET package:

  1. Get some historical data.
  2. history = qb.history([eurusd, gbpusd], datetime(2021, 11, 26), datetime(2021, 12, 8), Resolution.DAILY)
    var history = qb.History<QuoteBar>(new [] {eurusd, gbpusd}, new DateTime(2021, 11, 26), new DateTime(2021, 12, 8), Resolution.Daily);
  3. Select the data to plot.
  4. pct_change = history['close'].unstack(0).pct_change().dropna()
  5. Call the plot method on the pandas object.
  6. pct_change.plot(title="Close Price %Change", figsize=(15, 10))
  7. Create Line charts.
  8. var chart1 = Chart2D.Chart.Line<DateTime, decimal, string>(
        history.Select(x => x[eurusd].EndTime),
        history.Select(x => x[eurusd].Close),
        Name: "EURUSD"
    );
    var chart2 = Chart2D.Chart.Line<DateTime, decimal, string>(
        history.Select(x => x[gbpusd].EndTime),
        history.Select(x => x[gbpusd].Close),
        Name: "GBPUSD"
    );
  9. Create a Layout.
  10. LinearAxis xAxis = new LinearAxis();
    xAxis.SetValue("title", "Time");
    LinearAxis yAxis = new LinearAxis();
    yAxis.SetValue("title", "Price ($)");
    Title title = Title.init("EURUSD & GBPUSD Close Price");
    
    Layout layout = new Layout();
    layout.SetValue("xaxis", xAxis);
    layout.SetValue("yaxis", yAxis);
    layout.SetValue("title", title);
  11. Combine the charts and assign the Layout to the chart.
  12. var chart = Plotly.NET.Chart.Combine(new []{chart1, chart2});
    chart.WithLayout(layout);
  13. Show the plot.
  14. plt.show()
    HTML(GenericChart.toChartHTML(chart))

    Line charts display the value of the property you selected in a time series.

Line chart of Forex close price return% Line chart of Forex close price

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: