Overall Statistics |
Total Orders 30 Average Win 4.81% Average Loss -10.16% Compounding Annual Return 4.180% Drawdown 11.900% Expectancy 0.327 Start Equity 1000000 End Equity 1368889.26 Net Profit 36.889% Sharpe Ratio 0.104 Sortino Ratio 0.026 Probabilistic Sharpe Ratio 3.304% Loss Rate 10% Win Rate 90% Profit-Loss Ratio 0.47 Alpha 0.004 Beta 0.031 Annual Standard Deviation 0.067 Annual Variance 0.005 Information Ratio -0.498 Tracking Error 0.164 Treynor Ratio 0.224 Total Fees $4231.68 Estimated Strategy Capacity $920000.00 Lowest Capacity Asset CROX TG0PJGXPBS6D Portfolio Turnover 0.71% |
''' a. Enter: If Close >Open on Earnings Date, Enter position Next Day Open if open < high b. Exit: Price >= High of ED [can be High*(1+r%)] c. Stoploss: -10% of Entry Price Req Data: ED_Open, ED_Close, ED_High Orders: ENTER:MKT(AED_OPEN), EXIT:LIMIT(ED_HIGH), STOPLOSS: STOP(-10% of EntryPrice) ''' # region imports from AlgorithmImports import * # endregion # Strategy Class class PowerEarninggap(QCAlgorithm): # Variables stopMarketTicket = None limitTicket = None # Initialize strategy def initialize(self): self.SetStartDate(2017, 1, 1) self.SetEndDate(2024,8,30) self.SetCash(1000000) # self.AddUniverse(self.CoarseFilter, self.FineFilter) # self.SPY = self.AddEquity('SPY', Resolution.Minute).Symbol # self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 1), self.AfterMarketOpen) self.CROX = self.AddEquity('CROX', Resolution.Minute).Symbol self.Schedule.On(self.DateRules.EveryDay("CROX"), self.TimeRules.AfterMarketOpen("CROX", 1), self.AfterMarketOpen) def AfterMarketOpen(self): req_securities = [sec.Symbol.Value for sec in self.ActiveSecurities.Values] for security in self.ActiveSecurities.Values: # Add check for yesterday yesterday = self.Time - timedelta(days=1) # Check yesterday is ED if security.Fundamentals.EarningReports.FileDate.ThreeMonths.date() == yesterday.date(): symbol = security.Symbol historyData = self.History(symbol, 3, Resolution.Daily) try: openED = historyData['open'][-1] closeED = historyData['close'][-1] highED = historyData['high'][-1] openAED = security.Open except: self.Debug(f"History data unavailable for {symbol.Value}") continue # Trading Logic if closeED>openED and openAED<highED and security.Fundamentals.EarningReports.FileDate.ThreeMonths: # Enter Position if not invested if not self.Portfolio.Invested: # Enter Market Order self.qty = int((self.Portfolio.Cash/security.AskPrice)*0.99) self.MarketOrder(symbol,self.qty) # Enter Stoploss Order, return OrderTicket self.stopMarketTicket = self.StopMarketOrder(symbol, -self.qty, 0.9*openAED) # Exit Market Order self.limitTicket = self.LimitOrder(symbol,-self.qty,highED) # Triggered when any event related to order happens def OnOrderEvent(self, orderEvent): # Check if limit order is filled if self.limitTicket is not None and self.limitTicket.OrderId == orderEvent.OrderId: self.Debug("Limit Order Filled Time:" + str(self.Time)) self.Debug("Limit Order Filled :(") response = self.stopMarketTicket.Cancel() if response.is_success: self.debug("StopLoss Order successfully cancelled") else: self.debug("StopLoss Order not cancelled :(") # If stopMarketTicket is filled, cancel the limit order if self.stopMarketTicket is not None and self.stopMarketTicket.OrderId == orderEvent.OrderId: # store time self.stopMarketFillTime = self.time self.Debug("Cancel Limit Order Time:" + str(self.stopMarketFillTime)) response = self.limitTicket.Cancel() if response.is_success: self.debug("Order successfully cancelled") else: self.debug("Order not cancelled :(")