Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -0.903 Tracking Error 0.539 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. # Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from AlgorithmImports import * ### <summary> ### Example structure for structuring an algorithm with indicator and consolidator data for many tickers. ### </summary> ### <meta name="tag" content="consolidating data" /> ### <meta name="tag" content="indicators" /> ### <meta name="tag" content="using data" /> ### <meta name="tag" content="strategy example" /> class MultipleSymbolConsolidationAlgorithm(QCAlgorithm): # Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. def Initialize(self): #magical incantation to make the algorithm brokerage use cryptos: self.SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Cash) self.SetCash(69000) # This is the period of bars we'll be creating BarPeriod = TimeSpan.FromDays(1) # This is the period of our sma indicators ShortSMAPeriod = 10 LongSMAPeriod = 100 RSIPeriod = 4 # This is the number of consolidated bars we'll hold in symbol data for reference RollingWindowSize = 100 # Holds all of our data keyed by each symbol self.Data = {} # Contains all of our crypto symbols CryptoSymbols = ["BTCUSD", "ETHUSD", "ADAUSD", "XRPUSD", "SOLUSD", #"AMPUSD", "DOTUSD", "DOGEUSD", "LUNAUSD", "AVAXUSD", "UNIUSD", "LINKUSD", "LTCUSD", # "ATOUSD", # "MATICUSD", "ICPUSD", "FILUSD", "XLMUSD", "DAIUSD", "FTTUSD", "TRXUSD", "ETCUSD", "VETUSD", "XTZUSD", "XMRUSD", # "XECUSD", "EGLDUSD", # "AXSUSD", "EOSUSD", "AAVEUSD", "NEARUSD", "FTMUSD", # "IOTUSD", "GRTUSD", "KSMUSD", "NEOUSD", # "USTUSD", "LEOUSD", # "WAVESUSD", "BSVUSD", "MKRUSD", "BTTUSD", "COMPUSD", "XDCUSD", "CHZUSD", # "DCRUSD", "ZECUSD", "SUSHIUSD", "OMGUSD", # "MNAUSD", "CELUSD", "SNXUSD", "YFIUSD", "ENJUSD", "ZILUSD", # "QTMUSD", "BATUSD", "BTGUSD", "NEXOUSD", "BNTUSD", "ZRXUSD", "DGBUSD", # "CHSBUSD", "FETUSD", "LRCUSD", "1INCHUSD", "OCEANUSD", "GNOUSD", "BESTUSD", "BANDUSD", # "ROSEUSD", "MIRUSD", "ALBTUSD", "UOSUSD", "JSTUSD", "BALUSD", "SUNUSD", "OXYUSD", "RBTCUSD", "SUKUUSD", "BTSEUSD"] self.SetStartDate(2021, 8, 1) self.SetEndDate(2021, 9, 27) # initialize our equity data for symbol in CryptoSymbols: equity = self.AddCrypto(symbol,Resolution.Hour, Market.Bitfinex) self.Data[symbol] = SymbolData(equity.Symbol, BarPeriod, RollingWindowSize) # loop through all our symbols and request data subscriptions and initialize indicator for symbol, symbolData in self.Data.items(): # define the indicator for SMA10 symbolData.SMA10 = SimpleMovingAverage(self.CreateIndicatorName(symbol, "SMA" + str(ShortSMAPeriod), Resolution.Daily), ShortSMAPeriod) symbolData.SMA100 = SimpleMovingAverage(self.CreateIndicatorName(symbol, "SMA" + str(LongSMAPeriod), Resolution.Daily), LongSMAPeriod) symbolData.RSI4 = RelativeStrengthIndex(self.CreateIndicatorName(symbol, "RSI" + str(RSIPeriod), Resolution.Daily), RSIPeriod, MovingAverageType.Wilders) # define a consolidator to consolidate data for this symbol on the requested period consolidator = TradeBarConsolidator(BarPeriod) if symbolData.Symbol.SecurityType == SecurityType.Crypto else QuoteBarConsolidator(BarPeriod) # write up our consolidator to update the indicator consolidator.DataConsolidated += self.OnDataConsolidated # we need to add this consolidator so it gets auto updates self.SubscriptionManager.AddConsolidator(symbolData.Symbol, consolidator) def OnDataConsolidated(self, sender, bar): self.Data[bar.Symbol.Value].SMA10.Update(bar.Time, bar.Close) self.Data[bar.Symbol.Value].SMA100.Update(bar.Time, bar.Close) self.Data[bar.Symbol.Value].RSI4.Update(bar.Time, bar.Close) self.Data[bar.Symbol.Value].Bars.Add(bar) # OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. # Argument "data": Slice object, dictionary object with your stock data def OnData(self,data): # loop through each symbol in our structure for symbol in self.Data.keys(): self.Debug(symbol) symbolData = self.Data[symbol] # this check proves that this symbol was JUST updated prior to this OnData function being called if symbolData.IsReady() and symbolData.WasJustUpdated(self.Time): if not self.Portfolio[symbol].Invested: if symbolData.SMA10 > symbolData.SMA100: if symbolData.RSI4 < 10: self.Debug(symbol+"**") self.MarketOrder(symbol, 0.1) # End of a trading day event handler. This method is called at the end of the algorithm day (or multiple times if trading multiple assets). # Method is called 10 minutes before closing to allow user to close out position. def OnEndOfDay(self, symbol): i = 0 for symbol in sorted(self.Data.keys()): symbolData = self.Data[symbol] # we have too many symbols to plot them all, so plot every other i += 1 if symbolData.IsReady() and i%2 == 0: self.Plot(symbol, symbol, symbolData.RSI4.Current.Value) class SymbolData(object): def __init__(self, symbol, barPeriod, windowSize): self.Symbol = symbol # The period used when population the Bars rolling window self.BarPeriod = barPeriod # A rolling window of data, data needs to be pumped into Bars by using Bars.Update( tradeBar ) and can be accessed like: # mySymbolData.Bars[0] - most first recent piece of data # mySymbolData.Bars[5] - the sixth most recent piece of data (zero based indexing) self.Bars = RollingWindow[IBaseDataBar](windowSize) # The simple moving average indicator for our symbol self.SMA = None # Returns true if all the data in this instance is ready (indicators, rolling windows, ect...) def IsReady(self): return self.Bars.IsReady and self.SMA10.IsReady and self.SMA100.IsReady and self.RSI4.IsReady # Returns true if the most recent trade bar time matches the current time minus the bar's period, this # indicates that update was just called on this instance def WasJustUpdated(self, current): return self.Bars.Count > 0 and self.Bars[0].Time == current - self.BarPeriod