🚀 AI One-Click Generation of quantconnect Strategy Code

A Step-by-Step Guide to Adding and Using Forex Data in QuantConnect with Python

quantconnect | Published on: 2025/12/9
The following content is generated by EasyQuant .

Problem Description

How do I get historical and live data for the EUR/USD pair for my trading bot?

Solution

To access historical and live data for EUR/USD in QuantConnect, you must first subscribe to the Forex pair in the initialize method. Once subscribed, you can request historical data using self.history and access real-time data streams via the on_data event handler.

Below is a complete, runnable algorithm demonstrating how to initialize the asset, fetch a pandas DataFrame of historical data, and read live price updates.

QuantConnect Strategy Code

# region imports
from AlgorithmImports import *
# endregion

class EurUsdDataAlgorithm(QCAlgorithm):

    def initialize(self):
        # 1. Set Strategy Settings
        self.set_start_date(2023, 1, 1)
        self.set_end_date(2023, 12, 31)
        self.set_cash(100000)

        # 2. Subscribe to EURUSD data
        # We save the Symbol object to a variable for easy reference later
        # Resolution.MINUTE provides 1-minute bars. Options: TICK, SECOND, MINUTE, HOUR, DAILY
        self.eurusd = self.add_forex("EURUSD", Resolution.MINUTE, Market.OANDA).symbol

        # 3. Get Historical Data
        # This requests the last 60 bars of data at the resolution defined above (Minute)
        # The result is a pandas DataFrame
        history_df = self.history(self.eurusd, 60, Resolution.MINUTE)

        # Check if history is not empty and log the last historical close
        if not history_df.empty:
            last_historical_close = history_df.loc[self.eurusd].iloc[-1]['close']
            self.debug(f"History loaded. Last historical close: {last_historical_close}")
        
        # Example: Get Daily history even if the subscription is Minute
        daily_history = self.history(self.eurusd, 5, Resolution.DAILY)
        self.debug(f"Daily history rows: {len(daily_history)}")

    def on_data(self, slice: Slice):
        # 4. Access Live/Current Data
        # The 'slice' object contains all data for the current moment
        
        # Check if EURUSD data is available in this time slice
        if self.eurusd in slice.quote_bars:
            quote_bar = slice.quote_bars[self.eurusd]
            
            # Forex data usually relies on Bid/Ask rather than just 'Close' (which is the mid-point)
            bid_price = quote_bar.bid.close
            ask_price = quote_bar.ask.close
            mid_price = quote_bar.close

            self.plot("Trade Plot", "Price", mid_price)
            
            # Example logic: Log price every 100th bar to avoid log flooding
            if self.time.minute % 10 == 0:
                self.log(f"{self.time} :: Bid: {bid_price} | Ask: {ask_price} | Mid: {mid_price}")

Implementation Details

  1. add_forex: This method subscribes your algorithm to the data feed. It returns a Forex object, from which we extract the .symbol. This symbol is the unique identifier used throughout the algorithm.
  2. self.history: This method is used to get past data.
    • Arguments: It accepts the symbol (or list of symbols), the lookback period (integer for number of bars, or timedelta for a period of time), and the resolution.
    • Return Type: It returns a pandas DataFrame indexed by Symbol and Time. You can manipulate this using standard pandas techniques (e.g., .loc, .iloc, .mean()).
  3. on_data: This is the event handler for real-time data.
    • slice: The Slice object groups data packets. For Forex, data usually comes in as QuoteBars (containing Bid and Ask data) rather than TradeBars (which are for assets that trade on centralized exchanges like Equities).
    • Accessing Price: slice[symbol].close gives the mid-price. To get specific bid or ask prices, use slice.quote_bars[symbol].bid.close or slice.quote_bars[symbol].ask.close.

Q&A: Forex Data in QuantConnect

Q: Why do I get QuoteBars instead of TradeBars for EURUSD?
A: Forex is an Over-The-Counter (OTC) market. There is no centralized exchange recording single "trades." Instead, you receive "Quotes" (Bid and Ask prices) from liquidity providers. Therefore, QuantConnect provides QuoteBars for Forex, which contain the Open, High, Low, and Close for both the Bid and the Ask sides.

Q: Can I get Tick data for EURUSD?
A: Yes. You can change the resolution in the subscription to Resolution.TICK:
self.add_forex("EURUSD", Resolution.TICK).
Be aware that tick data is very high volume and will significantly slow down backtests compared to Minute or Hour resolution.

Q: How do I handle different time zones?
A: By default, QuantConnect converts all data to the time zone specified in set_time_zone (default is New York, Eastern Time). The self.time property in your algorithm will reflect this time zone. You do not need to manually convert data timestamps unless you have specific external requirements.

Q: What happens if I request history for a resolution different from my subscription?
A: QuantConnect allows this. As shown in the example code, you can subscribe to Resolution.MINUTE but request Resolution.DAILY history. The engine will automatically aggregate the data for you.