Overall Statistics
Total Trades
2
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe 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
# region imports
from AlgorithmImports import *
import itertools
# endregion

class ComboLegLimitOrderDemoAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2015, 12, 24) 
        self.SetEndDate(2015, 12, 24)
        self.SetCash(100000) 
        option = self.AddOption("GOOG")
        option.SetFilter(minStrike=-2, maxStrike=2, minExpiry=timedelta(days=0), maxExpiry=timedelta(days=180))
        
        self.tickets = []

    def OnData(self, slice: Slice):
        if len(self.tickets) == 0:
            for canonical_symbol, chain in slice.OptionChains.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.QuoteBars[contracts[0].Symbol].Ask.Low - slice.QuoteBars[contracts[1].Symbol].Bid.Low) * 0.75, 2) 

                # Place order
                self.tickets = self.ComboLimitOrder(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.QuoteBars[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 OnOrderEvent(self, orderEvent: OrderEvent) -> None:
        if orderEvent.Status == OrderStatus.Filled:
            self.Log(f"{self.Time} -- Order {orderEvent.OrderId} filled at {orderEvent.FillPrice}")