Overall Statistics |
Total Trades 31 Average Win 0.01% Average Loss -0.01% Compounding Annual Return -0.029% Drawdown 0.200% Expectancy -0.169 Net Profit -0.011% Sharpe Ratio -0.082 Probabilistic Sharpe Ratio 25.667% Loss Rate 62% Win Rate 38% Profit-Loss Ratio 1.16 Alpha -0.002 Beta 0.006 Annual Standard Deviation 0.004 Annual Variance 0 Information Ratio -2.52 Tracking Error 0.148 Treynor Ratio -0.052 Total Fees $31.00 Estimated Strategy Capacity $44000.00 Lowest Capacity Asset QQQ XONZHAZN83XI|QQQ RIWIV7K5Z9LX |
import clr clr.AddReference("System") clr.AddReference("QuantConnect.Algorithm") clr.AddReference("QuantConnect.Indicators") clr.AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Algorithm import * from QuantConnect.Indicators import * ### <summary> ### In this example we look at the canonical 15/30 day moving average cross. This algorithm ### will go long when the 15 crosses above the 30 and will liquidate when the 15 crosses ### back below the 30. ### </summary> ### <meta name="tag" content="indicators" /> ### <meta name="tag" content="indicator classes" /> ### <meta name="tag" content="moving average cross" /> ### <meta name="tag" content="strategy example" /> class MovingAverageCrossAlgorithm(QCAlgorithm): def Initialize(self): '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.''' self.SetStartDate(2021,1,1) #Set Start Date self.SetEndDate(2021,5,15) #Set End Date self.SetCash(1000000) #Set Strategy Cash # Find more symbols here: http://quantconnect.com/data self.AddEquity("QQQ") option = self.AddOption("QQQ", Resolution.Minute) # Add the option corresponding to underlying stock self.symbol = option.Symbol option.SetFilter(-2, +2, timedelta(6), timedelta(13)) # create a 15 day exponential moving average self.fast = self.EMA("QQQ", 50, Resolution.Minute) # create a 30 day exponential moving average self.slow = self.EMA("QQQ", 200, Resolution.Minute) self.MarketTicket = None self.previous = None def OnData(self, data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.''' # a couple things to notice in this method: # 1. We never need to 'update' our indicators with the data, the engine takes care of this for us # 2. We can use indicators directly in math expressions # 3. We can easily plot many indicators at the same time # wait for our slow ema to fully initialize if not self.slow.IsReady: return # only once per day if self.previous is not None and self.previous.date() == self.Time.date(): return # define a small tolerance on our checks to avoid bouncing tolerance = 0.00015 QQQprice = self.Securities["QQQ"].Price # Gives close price of QQQ QQQopen = self.Securities["QQQ"].Open # Gives last open price of QQQ holdings = self.Portfolio["QQQ"].Quantity # we only want to go long if we're currently short or flat if holdings <= 0: # if the fast is greater than the slow, we'll go long if self.fast.Current.Value > self.slow.Current.Value *(1 + tolerance): for symbol, chain in data.OptionChains.items(): contracts = [c for c in chain if c.Right == OptionRight.Call and c.UnderlyingLastPrice > c.Strike] if len(contracts) == 0: continue sorted_contracts = sorted(contracts, key=lambda x: x.Strike, reverse=True) contract = sorted_contracts[0].Symbol self.MarketTicket = self.MarketOrder(contract, 1) # we only want to liquidate if we're currently long # if the fast is less than the slow we'll liquidate our long if self.Portfolio.Invested and self.fast.Current.Value < self.slow.Current.Value: #self.Log("SELL >> {0}".format(self.Securities["QQQ"].Price)) self.Liquidate() self.previous = self.Time