Overall Statistics Total Orders2Average Win0%Average Loss0%Compounding Annual Return0%Drawdown0%Expectancy0Start Equity100000End Equity99958Net Profit0%Sharpe Ratio0Sortino Ratio0Probabilistic Sharpe Ratio0%Loss Rate0%Win Rate0%Profit-Loss Ratio0Alpha0Beta0Annual Standard Deviation0Annual Variance0Information Ratio0Tracking Error0Treynor Ratio0Total Fees$2.00Estimated Strategy Capacity$0Lowest Capacity AssetGOOCV W78ZERHAOVVQ|GOOCV VP83T1ZUHROLPortfolio Turnover3.11%
# region imports
from AlgorithmImports import *
import itertools
# endregion

class ComboLegLimitOrderDemoAlgorithm(QCAlgorithm):

def initialize(self):
self.set_start_date(2015, 12, 24)
self.set_end_date(2015, 12, 24)
self.set_cash(100000)
option.set_filter(min_strike=-2, max_strike=2, min_expiry=timedelta(days=0), max_expiry=timedelta(days=180))

self.tickets = []

def on_data(self, slice: Slice):
if len(self.tickets) == 0:
for canonical_symbol, chain in slice.option_chains.items():
# Select contracts
contracts = [contract for contract in chain if contract.right == OptionRight.CALL]
contracts = [(key, list(group)) for key, group in itertools.groupby(contracts, key=lambda x: x.expiry)]
contracts.sort(key=lambda x: x[0])
contracts = contracts[0][1]
contracts.sort(key=lambda x: x.strike)

if len(contracts) < 2:
return

# Create order legs
quantities = [1, -1]
legs = []
for i, contract in enumerate(contracts[:2]):
legs.append(Leg.create(contract.symbol, quantities[i]))

# Calculate limit price
self.limit_price = round((slice.quote_bars[contracts[0].symbol].ask.low - slice.quote_bars[contracts[1].symbol].bid.low) * 0.75, 2)

# Place order
self.tickets = self.combo_limit_order(legs, 1, self.limit_price)
else:
if self.time.hour == 9 and self.time.minute == 37:
self.quit()
return

price = 0
for ticket in self.tickets:
quote_bar = slice.quote_bars[ticket.symbol]
price += ((quote_bar.ask if ticket.quantity > 0 else quote_bar.bid).low * np.sign(ticket.quantity))
self.log(f"{self.time}. Limit price: {self.limit_price}; Aggregate price: {round(price, 2)}; Ready to fill: {price < self.limit_price}")

def on_order_event(self, orderEvent: OrderEvent) -> None:
if orderEvent.status == OrderStatus.FILLED:
self.log(f"{self.time} -- Order {orderEvent.order_id} filled at {orderEvent.fill_price}")