Hi,
I am trying to backtest this strategy,m but I get several errors. Why?
Runtime Error: ArgumentNullException : Value cannot be null.
Parameter name: key
at System.Collections.Concurrent.ConcurrentDictionary`2[TKey,TValue].ThrowKeyNullException () [0x00000] in <b0e1ad7573a24fd5a9f2af9595e677e7>:0
at System.Collections.Concurrent.ConcurrentDictionary`2[TKey,TValue].ContainsKey (TKey key) [0x00008] in <b0e1ad7573a24fd5a9f2af9595e677e7>:0
at QuantConnect.Securities.UniverseManager.get_Item (QuantConnect.Symbol symbol) [0x00000] in <e2116c6c2b30479ab313dc7ef47ce6f3>:0
at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <b0e1ad7573a24fd5a9f2af9595e677e7>:0
at OnData in main.py:line 44
:: for i in self.UniverseManager[self.uni_symbol].Members:
ArgumentNullException : Value cannot be null.
Parameter name: key
at System.Collections.Concurrent.ConcurrentDictionary`2[TKey,TValue].ThrowKeyNullException () [0x00000] in <b0e1ad7573a24fd5a9f2af9595e677e7>:0
at System.Collections.Concurrent.ConcurrentDictionary`2[TKey,TValue].ContainsKey (TKey key) [0x00008] in <b0e1ad7573a24fd5a9f2af9595e677e7>:0
at QuantConnect.Securities.UniverseManager.get_Item (QuantConnect.Symbol symbol) [0x00000] in <e2116c6c2b30479ab313dc7ef47ce6f3>:0
at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <b0e1ad7573a24fd5a9f2af9595e677e7>:0 (Open Stacktrace)
11 | 10:38:59:
Algorithm Id:(a29db63a8d6f8aaca4c44cd521845a2a) completed in 15.46 seconds at 0k data points per second. Processing total of 6,864 data points.
from clr import AddReference
AddReference("System.Core")
AddReference("System.Collections")
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Algorithm")
import statistics
from datetime import datetime
from System.Collections.Generic import List
class ShortTimeReversal(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2005, 1, 1)
self.SetEndDate(2017, 5, 10)
self.SetCash(1000000)
self.UniverseSettings.Resolution = Resolution.Daily
self.AddUniverse(self.CoarseSelectionFunction)
self._numberOfSymbols = 100
self._numberOfTradings = int(0.1 * self._numberOfSymbols)
self._numOfWeeks = 0
self._LastDay = -1
self._ifWarmUp = False
self._stocks = []
self._values = {}
def CoarseSelectionFunction(self, coarse):
sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
top100 = sortedByDollarVolume[:self._numberOfSymbols]
return [i.Symbol for i in top100]
def OnData(self, data):
if not self._ifWarmUp:
if self._LastDay == -1:
self._LastDay = self.Time.date()
self._stocks = []
self.uni_symbol = None
symbols = self.UniverseManager.Keys
for i in symbols:
if str(i.Value) == "QC-UNIVERSE-COARSE-USA":
self.uni_symbol = i
for i in self.UniverseManager[self.uni_symbol].Members:
self._stocks.append(i.Value.Symbol)
self._values[i.Value.Symbol] = [self.Securities[i.Value.Symbol].Price]
else:
delta = self.Time.date() - self._LastDay
if delta.days >= 7:
self._LastDay = self.Time.date()
for stock in self._stocks:
self._values[stock].append(self.Securities[stock].Price)
self._numOfWeeks += 1
if self._numOfWeeks == 3:
self._ifWarmUp = True
else:
delta = self.Time.date() - self._LastDay
if delta.days >= 7:
self._LastDay = self.Time.date()
returns = {}
for stock in self._stocks:
newPrice = self.Securities[stock].Price
oldPrice = self._values[stock].pop(0)
self._values[stock].append(newPrice)
try:
returns[stock] = newPrice/oldPrice
except:
returns[stock] = 0
newArr = [(v,k) for k,v in returns.items()]
newArr.sort()
for ret, stock in newArr[self._numberOfTradings:-self._numberOfTradings]:
if self.Portfolio[stock].Invested:
self.Liquidate(stock)
for ret, stock in newArr[0:self._numberOfTradings]:
self.SetHoldings(stock, 0.5/self._numberOfTradings)
for ret, stock in newArr[-self._numberOfTradings:]:
self.SetHoldings(stock, -0.5/self._numberOfTradings)
self._LastDay = self.Time.date()
Douglas Stridsberg
Hi Johnny,
Welcome to QC. Please use the insert code snippet button () to insert code, that way it will be highlighted.
If you debug self.uni_symbol before you use it, you'll see it's still set to None. This is because the key you're looking for is actually along the lines of "QC-UNIVERSE-COARSE-USA-7F88DEF7-E727-4742-99CC-9127CADB0475 2T", so you will never set self.uni_symbol properly.
It takes a while for your code to run, so I'm not attaching the backtest, but please see the code below. I've replaced your equality check with a .startswith() call.
from clr import AddReference AddReference("System.Core") AddReference("System.Collections") AddReference("QuantConnect.Common") AddReference("QuantConnect.Algorithm") import statistics from datetime import datetime from System.Collections.Generic import List class ShortTimeReversal(QCAlgorithm): def Initialize(self): self.SetStartDate(2005, 1, 1) self.SetEndDate(2017, 5, 10) self.SetCash(1000000) self.UniverseSettings.Resolution = Resolution.Daily self.AddUniverse(self.CoarseSelectionFunction) self._numberOfSymbols = 100 self._numberOfTradings = int(0.1 * self._numberOfSymbols) self._numOfWeeks = 0 self._LastDay = -1 self._ifWarmUp = False self._stocks = [] self._values = {} def CoarseSelectionFunction(self, coarse): sortedByDollarVolume = sorted(coarse, key = lambda x: x.DollarVolume, reverse=True) top100 = sortedByDollarVolume[:self._numberOfSymbols] return [i.Symbol for i in top100] def OnData(self, data): if not self._ifWarmUp: if self._LastDay == -1: self._LastDay = self.Time.date() self._stocks = [] self.uni_symbol = None symbols = self.UniverseManager.Keys for i in symbols: if str(i.Value).startswith("QC-UNIVERSE-COARSE-USA"): self.uni_symbol = i self.Debug(f"Value of i is {i}") self.Debug(f"Value of self.uni_symbol is {self.uni_symbol}") for i in self.UniverseManager[self.uni_symbol].Members: self._stocks.append(i.Value.Symbol) self._values[i.Value.Symbol] = [self.Securities[i.Value.Symbol].Price] else: delta = self.Time.date() - self._LastDay if delta.days >= 7: self._LastDay = self.Time.date() for stock in self._stocks: self._values[stock].append(self.Securities[stock].Price) self._numOfWeeks += 1 if self._numOfWeeks == 3: self._ifWarmUp = True else: delta = self.Time.date() - self._LastDay if delta.days >= 7: self._LastDay = self.Time.date() returns = {} for stock in self._stocks: newPrice = self.Securities[stock].Price oldPrice = self._values[stock].pop(0) self._values[stock].append(newPrice) try: returns[stock] = newPrice/oldPrice except: returns[stock] = 0 newArr = [(v,k) for k,v in returns.items()] newArr.sort() for ret, stock in newArr[self._numberOfTradings:-self._numberOfTradings]: if self.Portfolio[stock].Invested: self.Liquidate(stock) for ret, stock in newArr[0:self._numberOfTradings]: self.SetHoldings(stock, 0.5/self._numberOfTradings) for ret, stock in newArr[-self._numberOfTradings:]: self.SetHoldings(stock, -0.5/self._numberOfTradings) self._LastDay = self.Time.date()
Johnny Cash
Thank you!
I am trying use bitfinexdata. I found some code and modified it. This look to me just a Universe definition, but after accidentally hitting backtest it could actually trade. HOw is this possible? I do not see any algorithm for position sizing or signl creattion?
Also, how can I use margins with this Universe? When I add the line
self.SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Margin)
I get a lot of errors. I also tried with another code which just trades crypt against USD and margin worked there.
#from Alphas.HistoricalReturnsAlphaModel import HistoricalReturnsAlphaModel #from Execution.ImmediateExecutionModel import ImmediateExecutionModel #from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel class Test(QCAlgorithm): def Initialize(self): self.stateData = {} self.SetStartDate(2019, 1, 19) # Set Start Date #self.SetCash(100000) # Set Strategy Cash self.SetCash("BTC",10) self.SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Margin) # Add the pairs containing *BTC among all 346 pairs in Bitfinex symbols = ["LTCBTC", "ETHBTC", "ETCBTC", "RRTBTC", "ZECBTC", "XMRBTC", "DSHBTC", "XRPBTC", "IOTBTC", "EOSBTC", "SANBTC", "OMGBTC", "BCHBTC", "NEOBTC", "ETPBTC", "QTMBTC", "AVTBTC", "EDOBTC", "BTGBTC", "DATBTC", "QSHBTC", "YYWBTC", "GNTBTC", "SNTBTC", "BATBTC", "MNABTC", "FUNBTC", "ZRXBTC", "TNBBTC", "SPKBTC", "TRXBTC", "RCNBTC", "RLCBTC", "AIDBTC", "SNGBTC", "REPBTC", "ELFBTC", "IOSBTC", "AIOBTC", "REQBTC", "RDNBTC", "LRCBTC", "WAXBTC", "DAIBTC", "CFIBTC", "AGIBTC", "MTNBTC", "SNGBTC", "ODEBTC", "ANTBTC", "DTHBTC", "MITBTC", "STJBTC", "XLMBTC", "XVGBTC", "BCIBTC", "MKRBTC", "VENBTC", "KNCBTC", "POABTC", "LYMBTC", "UTKBTC", "VEEBTC", "DADBTC", "ORSBTC", "AUCBTC", "POYBTC", "FSNBTC", "CBTBTC", "ZCNBTC", "SENBTC", "NCABTC", "CNDBTC", "CTXBTC", "PAIBTC", "SEEBTC", "ESSBTC", "ATMBTC", "HOTBTC", "DTABTC", "IQXBTC", "WPRBTC", "ZILBTC", "BNTBTC", "XTZBTC", "OMNBTC", "DGBBTC", "BSVBTC", "BABBTC", "RBTBTC", "RIFBTC", "VSYBTC", "BFTBTC"] Symbols = [] tickers= [] for symbol in symbols: # add according forex data to add the crypto pairs forexS=symbol[:3]+"USD" self.AddForex(forexS, Resolution.Daily) Symbols.append(Symbol.Create(symbol, SecurityType.Crypto, Market.Bitfinex)) tickers.append(symbol) self.SetUniverseSelection(ManualUniverseSelectionModel(Symbols))
Douglas Stridsberg
Hi Johnny,
There are no trades - the reason you're seeing fluctuations in the value is because you've defined the starting cash to be 10 BTC. Hence, the USD value of your portfolio will fluctuate in line with the value of 10 BTC.
Margin trading for Bitfinex is not implemented, hence why uncommenting that line breaks your algorithm.
Johnny Cash
HI Douglas,
I thikn the margin models works. In this post there is an example of code which works.
https://www.quantconnect.com/forum/discussion/5564/bitfinex-crypto-algo-short-term-momentum-algorithmJohnny Cash
Johnny Cash
Hi,
does the linked above code work or not ? I think it did, and it is using the bitfinex margin model. Can you confirm?
Johnny Cash
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!