Overall Statistics
Total Trades
92
Average Win
0.97%
Average Loss
-0.60%
Compounding Annual Return
-12.640%
Drawdown
12.800%
Expectancy
-0.487
Net Profit
-12.629%
Sharpe Ratio
-1.425
Probabilistic Sharpe Ratio
0.025%
Loss Rate
80%
Win Rate
20%
Profit-Loss Ratio
1.62
Alpha
-0.089
Beta
0.007
Annual Standard Deviation
0.061
Annual Variance
0.004
Information Ratio
-1.074
Tracking Error
0.241
Treynor Ratio
-12.878
Total Fees
$546.00
Estimated Strategy Capacity
$16000.00
Lowest Capacity Asset
MSFT WYTI0XB8YIJQ|MSFT R735QTJ8XC9X
class BreakoutCallBuy(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2018, 1, 1)
        self.SetEndDate(2019, 1, 1)
        self.SetCash(100000)
        equity = self.AddEquity("MSFT", Resolution.Minute)
        equity.SetDataNormalizationMode(DataNormalizationMode.Raw)
        self.equity = equity.Symbol
        self.SetBenchmark(self.equity)
        
        option = self.AddOption("MSFT", Resolution.Minute)
        option.SetFilter(-3, 3, timedelta(20), timedelta(40))

        self.high = self.MAX(self.equity, 21, Resolution.Daily, Field.High)
    
    
    def OnData(self,data):
        if not self.high.IsReady:
            return
        
        option_invested = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.Option]
        
        if option_invested:
            if self.Time + timedelta(4) > option_invested[0].ID.Date:
                self.Liquidate(option_invested[0], "Too close to expiration")
            return
        
        if self.Securities[self.equity].Price >= self.high.Current.Value:
            for i in data.OptionChains:
                chains = i.Value
                self.BuyCall(chains)

 
    def BuyCall(self,chains):
        expiry = sorted(chains,key = lambda x: x.Expiry, reverse=True)[0].Expiry
        calls = [i for i in chains if i.Expiry == expiry and i.Right == OptionRight.Call]
        call_contracts = sorted(calls,key = lambda x: abs(x.Strike - x.UnderlyingLastPrice))
        if len(call_contracts) == 0: 
            return
        self.call = call_contracts[0]
        
        quantity = self.Portfolio.TotalPortfolioValue / self.call.AskPrice
        quantity = int( 0.05 * quantity / 100 )
        
        # Buy calls and set stop and take profit levels
        self.Buy(self.call.Symbol, quantity)
        self.LimitOrder(self.call.Symbol, -quantity, (self.call.AskPrice * 1.2))
        self.StopMarketOrder(self.call.Symbol, -quantity, (self.call.AskPrice * 0.9))


    def OnOrderEvent(self, orderEvent):
        order = self.Transactions.GetOrderById(orderEvent.OrderId)
        # Cancel remaining order if limit order or stop loss order is executed
        if order.Status == OrderStatus.Filled:
            if order.Type == OrderType.Limit or OrderType.StopMarket:
                self.Transactions.CancelOpenOrders(order.Symbol)
                
            if order.Status == OrderStatus.Canceled:
                self.Log(str(orderEvent))
        
        # Liquidate before options are exercised
        if order.Type == OrderType.OptionExercise:
            self.Liquidate()