Overall Statistics
Total Trades
6
Average Win
2.23%
Average Loss
-0.60%
Compounding Annual Return
7.862%
Drawdown
1.100%
Expectancy
2.137
Net Profit
3.881%
Sharpe Ratio
2.712
Probabilistic Sharpe Ratio
90.296%
Loss Rate
33%
Win Rate
67%
Profit-Loss Ratio
3.71
Alpha
0
Beta
0
Annual Standard Deviation
0.03
Annual Variance
0.001
Information Ratio
2.712
Tracking Error
0.03
Treynor Ratio
0
Total Fees
$6.00
Estimated Strategy Capacity
$66000000.00
import pandas as pd
import datetime
from datetime import timedelta

class OptionIssue(QCAlgorithm):
    def __init__(self):
        self.buyTicket = None
        self.sellTicket = None
        self.buyTicketTime = None
        self.symbol = None
        self.expiry = None
    
    def Initialize(self):
        
        self.SetStartDate(2019, 12, 1)  # Set Start Date
        self.SetEndDate(2020, 6, 1)
        self.SetCash(100000)  # Set Strategy Cash
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Cash)

        self.aapl = self.AddEquity("AAPL", Resolution.Minute)
        self.aapl.SetDataNormalizationMode(DataNormalizationMode.Raw)
        option = self.AddOption("AAPL", Resolution.Minute)
        self.option_symbol = option.Symbol
        option.SetFilter(lambda universe: universe.Strikes(-2, 2).Expiration(timedelta(14), timedelta(17)))
        self.rsi = self.RSI("AAPL", 14)
        
        # Check Option Expiry
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(9, 31), Action(self.CheckExpiry))
        
        # Check Order Time
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(9, 31), Action(self.CheckOrderTime))
        
    
    def CheckOrderTime(self):
        if self.buyTicketTime is not None:
            if self.UtcTime > self.buyTicketTime + timedelta(2):
                self.buyTicket = None
        
    def CheckExpiry(self):
        option_invested = [x.Key.Value for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.Option]
        for contract in option_invested:
            
            symbolValue = self.Portfolio[contract].Symbol.Value
            symbol = self.Portfolio[contract].Symbol
            symbolID = self.Portfolio[contract].Symbol.ID
            quantity = self.Portfolio[contract].Quantity
            lastPrice = self.Securities[contract].Price
            self.expiry = self.Securities[contract].Expiry
            self.dt = self.Time.date()
            if self.Portfolio[contract].Invested:
                if (self.expiry - self.Time) < timedelta(2):
                    self.sellTicket = self.MarketOrder(symbol, -quantity)
                    self.Debug("Selling Contract: " + str(symbol) + " Quantity: " + str(-quantity) + " At Price: " + str(round(lastPrice, 2)))
                    self.buyTicket = None
                    return(option_invested)
    
    def OnOrderEvent(self, orderEvent):
        
        if orderEvent.Status == OrderStatus.Canceled:
            openOrders = self.Transactions.GetOpenOrders()
            if len(openOrders)> 0:
                for x in openOrders:
                    self.Transactions.CancelOrder(x.Id)
            self.buyTicket = None
            
        if orderEvent.Status == OrderStatus.Filled:
        
            order = self.Transactions.GetOrderById(orderEvent.OrderId)
            self.buyTicketTime = order.Time
    
    def OnData(self, slice):
        
        if not self.IsMarketOpen(self.option_symbol):
            return
        
        if not self.rsi.IsReady:
            return
            
        invested = [ x.Symbol.Value for x in self.Portfolio.Values if x.Invested ]

        for i in slice.OptionChains:
            if i.Key != self.option_symbol: continue
            optionchain = i.Value
            df = pd.DataFrame([[x.Right,float(x.Strike),x.Expiry,float(x.BidPrice),float(x.AskPrice),float(x.Volume)] for x in optionchain],
                       index=[x.Symbol.Value for x in optionchain],
                       columns=['type(call 0, put 1)', 'strike', 'expiry', 'ask price', 'bid price', 'volume'])
            
            call = [x for x in optionchain if x.Right == 0]
            put = [x for x in optionchain if x.Right == 1]
            
            contracts = [x for x in call if x.UnderlyingLastPrice - x.Strike < 0]
            
            contracts = sorted(contracts, key = lambda x:x.BidPrice, reverse = False)
            
            if len(contracts) == 0:
                return
        
            valuesymbol = contracts[0].Symbol.Value
            bidPrice = contracts[0].BidPrice
            askPrice = contracts[0].AskPrice
            self.expiry = contracts[0].Expiry
            symbol = contracts[0].Symbol
            symbolID = contracts[0].Symbol.ID
            aaplPrice = self.Securities["AAPL"].Close
            
            if symbol.Contains("X"):
                self.Debug("Symbol Contains X")
                return
            
            RSI = self.rsi.Current.Value
            
            if self.buyTicket is not None:
                return
            
            if self.Securities[symbol].Invested:
                return
            
            stop_time = self.Time.replace(hour=11, minute=30)
        
            if self.Time > stop_time:
                return
            
            if not self.Portfolio[symbol].Invested and RSI < 20:
                
                security = self.Securities[symbol]
            
                istrade = security.IsTradable
            
                if not security.IsTradable:
                    self.Debug("Contract not tradable. Symbol: " + str(symbol))
                    return
                
                self.Debug("RSI: " + str(RSI))
                self.buyTicket = self.MarketOrder(symbol, self.CalculateOrderQuantity(symbol, 0.01), False, "Buy Ticket")
                self.Debug("Order was placed")
                self.Debug("Symbol: " + str(symbol) + " Bid Price: " + str(bidPrice) + " Ask Price: " + str(askPrice) + " Expiry Date: " + str(self.expiry))
                self.Debug("Symbol Value: " + str(valuesymbol) + " Symbol ID: " + str(symbolID) + " Is Tradeable: " + str(istrade))
                self.Debug("AAPL Price: " + str(aaplPrice))