Generate code in 3 minutes
Enter your idea and AI generates runnable code.
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.
Data Resolution:
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.Resolution.Minute or Resolution.Second. This allows OnData to trigger during market hours, enabling immediate execution.Scheduled Events (For Daily Strategies):
OnData.self.schedule.on with time_rules.before_market_close.Algorithm Framework:
self.set_execution(ImmediateExecutionModel()).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.
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}")
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)
Resolution.Minute: This is the most reliable way to ensure logic runs and trades execute during market hours.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).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: 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.