-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Open
Labels
Description
Expected Behavior
- Warmup does not trigger
FillForwardEnumerator received data out of order
Actual Behavior
- FF triggering
FillForwardEnumerator received data out of order
Potential Solution
N/A
Reproducing the Problem
class BasicTemplateAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 1)
self.spy = self.add_equity("SPY", Resolution.MINUTE).symbol
option = self.add_option("SPY", Resolution.MINUTE)
self.spy_option = option.symbol
option.set_filter(lambda u: u.strikes(-5, 5).expiration(20, 45))
self.set_warm_up(200, Resolution.DAILY)
self.current_contract = None
self.days_to_expiration_threshold = 5
self.schedule.on(self.date_rules.every_day("SPY"),
self.time_rules.after_market_open("SPY", 30),
self.manage_options)
def manage_options(self):
if self.current_contract is not None:
if self.current_contract in self.securities:
days_to_expiry = (self.current_contract.id.date - self.time).days
if days_to_expiry <= self.days_to_expiration_threshold:
self.liquidate(self.current_contract)
self.current_contract = None
return
if self.portfolio[self.current_contract].invested:
unrealized_profit_pct = self.portfolio[self.current_contract].unrealized_profit_percent
if unrealized_profit_pct >= 0.5 or unrealized_profit_pct <= -2.0:
self.liquidate(self.current_contract)
self.current_contract = None
return
if self.current_contract is None or not self.portfolio[self.current_contract].invested:
self.sell_put()
def sell_put(self):
chain = self.current_slice.option_chains.get(self.spy_option)
if chain is None or len(chain) == 0:
return
# Filter for put options
puts = [x for x in chain if x.right == OptionRight.PUT]
if len(puts) == 0:
return
# Get current SPY price
spy_price = self.securities[self.spy].price
# Select put with strike around 5-10% out of the money
target_strike = spy_price * 0.95
# Find the put closest to our target strike with 30-45 DTE
selected_put = sorted(puts,
key=lambda x: abs(x.strike - target_strike) + abs((x.expiry - self.time).days - 35))
if len(selected_put) == 0:
return
contract = selected_put[0]
# Sell 1 put contract (100 shares per contract)
# Use margin carefully - each contract requires cash/margin equal to strike * 100
quantity = 1
self.market_order(contract.symbol, -quantity)
self.current_contract = contract.symbol
self.debug(f"Sold put: {contract.symbol}, Strike: {contract.strike}, "
f"Expiry: {contract.expiry}, Premium: {contract.bid_price}")
def on_data(self, data: Slice):
# Store slice for access in scheduled functions
self.current_slice = dataSystem Information
N/A
Checklist
- I have completely filled out this template
- I have confirmed that this issue exists on the current
masterbranch - I have confirmed that this is not a duplicate issue by searching issues
- I have provided detailed steps to reproduce the issue