Overall Statistics
Total Trades
55
Average Win
8.30%
Average Loss
-7.49%
Compounding Annual Return
-99.841%
Drawdown
64.200%
Expectancy
-0.385
Net Profit
-58.400%
Sharpe Ratio
-0.8
Probabilistic Sharpe Ratio
2.848%
Loss Rate
71%
Win Rate
29%
Profit-Loss Ratio
1.11
Alpha
0
Beta
0
Annual Standard Deviation
1.222
Annual Variance
1.494
Information Ratio
-0.8
Tracking Error
1.222
Treynor Ratio
0
Total Fees
$55.00
Estimated Strategy Capacity
$1000.00
Lowest Capacity Asset
MSFT Y4D62XKF7W92|MSFT R735QTJ8XC9X
from AlgorithmImports import *
from datetime import datetime as date

class MACD(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2022, 9, 1)
        self.SetCash(500)

        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)

        self.LastTime = None
        self.entryTicket = None
        self.macd = dict()
        self.symbols = []

        symbols = ["AAPL","MSFT","GOOGL","AMZN"]

        for ticker in symbols:
            symbol = self.AddEquity(ticker, Resolution.Minute).Symbol
            option = self.AddOption(symbol, Resolution.Minute)
            self.symbols.append(option.Symbol)
            option.SetFilter(-100, 100, timedelta(41), timedelta(60))
            self.macd[symbol] = self.MACD(ticker, 12, 26, 9, MovingAverageType.Simple, Resolution.Minute)
        
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(15, 45), self.Liquidate)
        
    def OnData(self, data):
        if not all([macd.IsReady for symbol, macd in self.macd.items()]):
            return

        if self.Portfolio.Invested:
            return

        for symbol, macd in self.macd.items():
            if macd.Current.Value < -0.5:
                self.Debug(symbol.Value)
                opt_sym = [option for option in self.symbols if symbol== option.Underlying]
                for i in opt_sym:
                    chains = data.OptionChains.get(i)
                self.BuyCall(chains)

    def BuyCall(self,chains):
        if chains is None:return
        expiry = sorted(chains,key = lambda x: x.Expiry, reverse=False)[0].Expiry
        calls = [kvp for kvp in chains if 
                kvp.Expiry == expiry
                and kvp.Right == OptionRight.Call
                and kvp.AskPrice > 1]
        call_contracts = sorted(sorted(calls,                              
                                        key = lambda x: abs(x.Strike - x.UnderlyingLastPrice)),\
                                        key = lambda x: x.AskPrice, reverse=False)
        if len(call_contracts) == 0: 
            return
        self.call = call_contracts[0]
        
        quantity = math.ceil((0.1 * self.Portfolio.TotalPortfolioValue) / (self.call.AskPrice*100))

        self.entry_ticket = self.LimitOrder(self.call.Symbol, quantity, round(self.call.AskPrice,2))