Overall Statistics
Total Orders
2
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Start Equity
100000
End Equity
99958
Net Profit
0%
Sharpe Ratio
0
Sortino Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$2.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
GOOCV W78ZERHAOVVQ|GOOCV VP83T1ZUHROL
Portfolio Turnover
3.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 = self.add_option("GOOG")
        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}")