Exclusive 22% OFF All Quantra by QuantInsti Courses for IBridgePy Users Master algorithmic trading from beginner to advanced — Python for trading, machine learning strategies, options trading, and more.
HUI22 Use HUI22 for 22% off
HUI7 Stack HUI7 for an additional 7% off
Browse Courses →
← Back to Blog

Trading Futures with IBridgePy: ES, MES, and NQ Complete Guide

June 15, 2026 · Tutorials

Why Trade Futures with Python?

Futures contracts like ES (S&P 500 E-mini), MES (Micro E-mini S&P 500), and NQ (Nasdaq 100 E-mini) are among the most liquid instruments in the world. With IBridgePy, you can automate futures trading strategies using Python and execute them through Interactive Brokers with just a few lines of code.

Defining Futures Contracts in IBridgePy

Unlike stocks, futures require additional parameters: the expiry date and the exchange. IBridgePy uses superSymbol() to define futures contracts:

# Define an ES futures contract (December 2026 expiry)
es_contract = superSymbol(secType='FUT', symbol='ES', currency='USD',
                          exchange='CME', expiry='20261218')

# Define an MES micro futures contract
mes_contract = superSymbol(secType='FUT', symbol='MES', currency='USD',
                           exchange='CME', expiry='20261218')

# Define an NQ futures contract
nq_contract = superSymbol(secType='FUT', symbol='NQ', currency='USD',
                          exchange='CME', expiry='20261218')

The expiry parameter uses the format YYYYMMDD and should match the contract expiration date on the CME.

Placing Futures Orders

Once you have defined the contract, placing orders works the same as with stocks:

def handle_data(context, data):
    mes = superSymbol(secType='FUT', symbol='MES', currency='USD',
                      exchange='CME', expiry='20261218')

    # Buy 1 MES contract at market
    order_id = order(mes, 1)
    order_status_monitor(order_id, 'Filled', waitingTimeInSeconds=30)

    fill_price = get_order(order_id).avgFillPrice
    print(f'Bought 1 MES at {fill_price}')

Understanding cost_basis for Futures Positions

A critical difference between stocks and futures in IBridgePy is how get_position().cost_basis works. For futures, Interactive Brokers returns the dollar-multiplied value, not the raw price.

ContractMultiplierFill Pricecost_basis Value
MES$55,40027,000
ES$505,400270,000
MNQ$219,50039,000
NQ$2019,500390,000

To convert cost_basis back to the actual entry price, divide by the multiplier:

# Get entry price for MES position
mes_position = get_position(mes_contract)
entry_price = mes_position.cost_basis / 5  # MES multiplier is 5
print(f'MES entry price: {entry_price}')

# For ES
es_position = get_position(es_contract)
es_entry = es_position.cost_basis / 50  # ES multiplier is 50

Complete Strategy Example: MES with Stop Loss and Profit Target

def initialize(context):
    context.mes = superSymbol(secType='FUT', symbol='MES', currency='USD',
                              exchange='CME', expiry='20261218')
    context.in_position = False

def handle_data(context, data):
    if not context.in_position:
        # Enter long position
        order_id = order(context.mes, 1)
        order_status_monitor(order_id, 'Filled', waitingTimeInSeconds=30)

        # Use avgFillPrice for precise stop/target levels
        fill_price = get_order(order_id).avgFillPrice

        # Place bracket: 20-point stop, 40-point target
        stop_price = fill_price - 20
        target_price = fill_price + 40

        order(context.mes, -1, style=StopOrder(stop_price))
        order(context.mes, -1, style=LimitOrder(target_price))

        context.in_position = True
        print(f'Entry: {fill_price} | Stop: {stop_price} | Target: {target_price}')

Important Tips for Futures Trading with IBridgePy

  • Roll dates: Futures expire quarterly. Update the expiry parameter before the contract rolls (typically the Thursday before the third Friday of March, June, September, or December for index futures).
  • Market hours: CME futures trade nearly 24 hours (Sunday 6pm to Friday 5pm ET with a daily halt from 5pm-6pm ET). Your strategy's scheduling should account for this.
  • Margin: Futures require margin, not the full notional value. Check your account's available margin before placing orders.
  • Position size: get_position(contract).amount returns the number of contracts held, positive for long and negative for short.

For more on order types and position management, visit the IBridgePy documentation or explore our tutorials.