🚀 AI One-Click Generation of quantconnect Strategy Code

How to Use `SetExecution(ImmediateExecutionModel())` in Your QuantConnect Strategy

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

Problem Description

How do I make my algorithm place trades immediately after a signal is generated?

Solution

To ensure your algorithm places trades immediately after a signal is generated in QuantConnect, you must address three specific areas: Data Resolution, Order Type, and (if using the Algorithm Framework) the Execution Model.

Key Concepts for Immediate Execution

  1. Data Resolution:

    • If you use Resolution.Daily, OnData triggers after the market closes (e.g., 16:00 or 00:00). A MarketOrder placed then will fill at the next day's open.
    • Solution: Use Resolution.Minute or Resolution.Second. This allows OnData to trigger during market hours, enabling immediate execution.
  2. Scheduled Events (For Daily Strategies):

    • If you require Daily data logic but want to trade before the day closes (effectively "immediately" on the current bar), do not wait for OnData.
    • Solution: Use self.schedule.on with time_rules.before_market_close.
  3. Algorithm Framework:

    • If using the framework (Alphas), the default execution model might batch orders.
    • Solution: Use self.set_execution(ImmediateExecutionModel()).

Implementation Examples

Below are two examples. Example 1 is for standard algorithms using Resolution.Minute for instant reaction. Example 2 is for the Algorithm Framework ensuring immediate execution.

Example 1: Standard Algorithm (Minute Resolution)

This strategy uses Minute resolution data. As soon as the RSI crosses a threshold inside on_data, a Market Order is placed immediately.

# region imports
from AlgorithmImports import *
# endregion

class ImmediateExecutionAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2023, 1, 1)
        self.set_end_date(2023, 6, 1)
        self.set_cash(100000)

        # 1. Set Resolution to MINUTE (or SECOND) for immediate intraday execution.
        # If this were DAILY, the trade would not happen until the next day.
        self.symbol = self.add_equity("SPY", Resolution.MINUTE).symbol

        # Indicators
        self.rsi = self.RSI(self.symbol, 14, MovingAverageType.WILDERS, Resolution.MINUTE)
        
        # Warm up indicator
        self.set_warm_up(14)

    def on_data(self, data: Slice):
        if self.is_warming_up or not self.rsi.is_ready:
            return

        # 2. Logic triggers during the day
        if not self.portfolio.invested:
            if self.rsi.current.value < 30:
                # 3. MarketOrder executes immediately at current market price
                self.market_order(self.symbol, 100)
                self.debug(f"Bought immediately at {self.time}")
        
        elif self.portfolio.invested:
            if self.rsi.current.value > 70:
                self.liquidate(self.symbol)
                self.debug(f"Sold immediately at {self.time}")

Example 2: Algorithm Framework (Immediate Execution Model)

If you are using the AddAlpha or SetAlpha structure, you must explicitly set the Execution Model to ImmediateExecutionModel. Without this, some models may delay trading to reduce transaction costs or impact.

# region imports
from AlgorithmImports import *
from QuantConnect.Algorithm.Framework.Alphas import *
from QuantConnect.Algorithm.Framework.Portfolio import *
from QuantConnect.Algorithm.Framework.Execution import *
from QuantConnect.Algorithm.Framework.Selection import *
# endregion

class FrameworkImmediateExecution(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2023, 1, 1)
        self.set_end_date(2023, 6, 1)
        self.set_cash(100000)

        # Universe Selection
        self.set_universe_selection(ManualUniverseSelectionModel([Symbol.create("SPY", SecurityType.EQUITY, Market.USA)]))

        # Alpha Model: Generates signals (Insights)
        self.set_alpha(RsiAlphaModel())

        # Portfolio Construction: Determines target quantities
        self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())

        # CRITICAL STEP: Set Execution to Immediate
        # This ensures that as soon as the Alpha generates an Insight, 
        # and Portfolio Construction creates a target, the order is sent.
        self.set_execution(ImmediateExecutionModel())

class RsiAlphaModel(AlphaModel):
    def __init__(self, period=14, resolution=Resolution.MINUTE):
        self.period = period
        self.resolution = resolution
        self.rsi_dictionary = {}

    def update(self, algorithm, data):
        insights = []
        for symbol, rsi in self.rsi_dictionary.items():
            if rsi.is_ready:
                if rsi.current.value < 30:
                    insights.append(Insight.price(symbol, timedelta(minutes=20), InsightDirection.UP))
                elif rsi.current.value > 70:
                    insights.append(Insight.price(symbol, timedelta(minutes=20), InsightDirection.DOWN))
        return insights

    def on_securities_changed(self, algorithm, changes):
        for security in changes.added_securities:
            self.rsi_dictionary[security.symbol] = algorithm.RSI(security.symbol, self.period, MovingAverageType.WILDERS, self.resolution)
        for security in changes.removed_securities:
            self.rsi_dictionary.pop(security.symbol, None)

Summary of Best Practices

  1. Use Resolution.Minute: This is the most reliable way to ensure logic runs and trades execute during market hours.
  2. Avoid LimitOrder for immediacy: Limit orders may sit in the order book waiting for a price match. Use MarketOrder for guaranteed immediate execution (though potentially at a slightly worse price due to slippage).
  3. Check IsWarmingUp: Ensure your algorithm doesn't try to trade before indicators are ready, which can cause errors, but once ready, the trade logic should be unhindered.

Q&A

Q: Why does my Daily Resolution algorithm trade the next day?
A: In QuantConnect, OnData for Resolution.Daily is triggered after the bar closes (e.g., 4:00 PM ET). Since the market is closed, any Market Order placed then will be queued and filled at the Market Open of the next trading day.

Q: How can I trade the "Close" of the current day?
A: Use self.schedule.on(self.date_rules.every_day(), self.time_rules.before_market_close("SPY", 1), self.my_rebalance_method). This runs your logic 1 minute before the market closes, allowing you to fill orders at prices very close to the daily closing price.

Q: Does ImmediateExecutionModel work with Limit Orders?
A: No. The ImmediateExecutionModel specifically uses Market Orders to ensure the portfolio targets are met instantly. If you need Limit Orders, you must write a custom Execution Model or use the StandardDeviationExecutionModel.