| Overall Statistics |
|
Total Trades 4 Average Win 0.07% Average Loss -0.01% Compounding Annual Return 0.764% Drawdown 0.000% Expectancy 6.100 Net Profit 0.064% Sharpe Ratio 2.072 Probabilistic Sharpe Ratio 70.301% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 13.20 Alpha 0.005 Beta 0.008 Annual Standard Deviation 0.003 Annual Variance 0 Information Ratio -0.453 Tracking Error 0.108 Treynor Ratio 0.641 Total Fees $5.00 Estimated Strategy Capacity $0 Lowest Capacity Asset SPY Y8JTHA93KD46|SPY R735QTJ8XC9X Portfolio Turnover 0.03% |
from AlgorithmImports import *
from datetime import datetime
class AlertLightBrownHyena(QCAlgorithm):
def Initialize(self):
self.ticker = "SPY"
self.numberContract = 5
self.resolution = Resolution.Minute
self.SetStartDate(2023, 5, 1) # Set Start Date
self.SetEndDate(2023, 5, 31) # Set End Date
self.SetCash(1000000) # Set Strategy Cash
self.SetWarmUp(100, self.resolution)
self.equity = self.AddEquity(self.ticker, self.resolution)
self.equity.SetDataNormalizationMode(DataNormalizationMode.Raw)
self.option = self.AddOption(self.ticker, self.resolution)
self.option.SetFilter(-10, 10, 2, 2)
self.symbol = self.option.Symbol
self.rsi = self.RSI(self.equity.Symbol, 14)
self.liquidContract = None
self.liquidContractType = None
self.liquidContractDate = None
self.contractTypeCall = 0
self.contractTypePut = 1
def OnData(self, data: Slice):
# Force sell option at the end of the next day
if self.liquidContractDate and self.liquidContractDate < self.Time - timedelta(days=1) and self.Time.hour >= 15:
self.liquidateExpiringOption()
if self.rsi.IsReady:
#self.Plot("RelativeStrengthIndex", "rsi", self.rsi.Current.Value)
if self.rsi.Current.Value < 23:
# Buy call
if not self.Portfolio.Invested:
self.orderCall(data)
elif self.rsi.Current.Value < 30 and self.liquidContractType == self.contractTypePut:
# Sell put
if self.Portfolio.Invested:
self.Log("Liquidated")
self.MarketOrder(self.liquidContract, -self.numberContract)
elif self.rsi.Current.Value > 77:
# Buy put
if not self.Portfolio.Invested:
self.orderPut(data)
elif self.rsi.Current.Value > 70 and self.liquidContractType == self.contractTypeCall:
# Sell call
if self.Portfolio.Invested:
self.Log("Liquidated")
self.MarketOrder(self.liquidContract, -self.numberContract)
def getContracts(self, data, type):
chain = data.OptionChains.get(self.symbol)
if chain:
contracts = [x for x in chain if x.Right == type] # Get the correct option types
contracts = sorted(contracts, key = lambda x: x.Expiry, reverse = True) # Sort by the longest expiration first
return contracts
return []
def orderCall(self, data):
contracts = self.getContracts(data, self.contractTypeCall)
if len(contracts) > 0:
self.Log("Call Ordered (Market: " + str(self.Securities["SPY"].Price) + " Strike: " + str(contracts[0].Strike) + " Expiry: " + str(contracts[0].Expiry) + ")")
self.liquidContract = contracts[0].Symbol
self.liquidContractType = self.contractTypeCall
self.liquidContractDate = self.Time
self.MarketOrder(contracts[0].Symbol, self.numberContract)
else:
self.Log("Call cancelled (no contracts)")
def orderPut(self, data):
contracts = self.getContracts(data, self.contractTypePut)
if len(contracts) > 0:
self.Log("Put Ordered (Market: " + str(self.Securities["SPY"].Price) + " Strike: " + str(contracts[0].Strike) + " Expiry: " + str(contracts[0].Expiry) + ")")
self.liquidContract = contracts[0].Symbol
self.liquidContractType = self.contractTypePut
self.liquidContractDate = self.Time
self.MarketOrder(contracts[0].Symbol, self.numberContract)
else:
self.Log("Put cancelled (no contracts)")
def liquidateExpiringOption(self):
self.Log("Liquidated (time)")
self.MarketOrder(self.liquidContract, -self.numberContract)
self.liquidContract = None
self.liquidContractType = None
self.liquidContractDate = None