| 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 :(")