Overall Statistics |
Total Trades 9 Average Win 45.92% Average Loss -16.85% Compounding Annual Return 340.068% Drawdown 34.400% Expectancy 1.793 Net Profit 228.255% Sharpe Ratio 2.011 Loss Rate 25% Win Rate 75% Profit-Loss Ratio 2.72 Alpha 1.168 Beta 0.274 Annual Standard Deviation 0.597 Annual Variance 0.356 Information Ratio 1.811 Tracking Error 0.598 Treynor Ratio 4.386 Total Fees $0.00 |
# WarmCryptoCrossover (Py) v0.01 import clr from clr import AddReference clr.AddReference("System") clr.AddReference("QuantConnect.Algorithm") clr.AddReference("QuantConnect.Indicators") clr.AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Data import * from QuantConnect.Algorithm import * from QuantConnect.Indicators import * import decimal as d import numpy as np class CryptoWarmupMovingAverageCross(QCAlgorithm): def Initialize(self): self.SetStartDate(2017, 1, 1) # Set Start Date self.SetEndDate(2017, 10, 19) # Set End Date self.SetCash(10000) # Set Strategy Cash # Set brokerage we are using: GDAX for cryptos #self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash) # Set crypto to BTC at 1 hour resolution self.AddCrypto("BTCUSD", Resolution.Hour) # Define windows in days for EMA fast_period = 15 slow_period = 30 # create a fast exponential moving average at daily resolution self.fast = self.EMA("BTCUSD", fast_period, Resolution.Daily) # create a slow exponential moving average at daily resolution self.slow = self.EMA("BTCUSD", slow_period, Resolution.Daily) # "slow_period + 1" because rolling window waits for one to fall off the back to be considered ready # History method returns a dict with a pandas.DataFrame history = self.History(["BTCUSD"], slow_period + 1) # prints out the tail of the dataframe self.Log(str(history.loc["BTCUSD"].tail())) self.Log(str(history.loc["BTCUSD"].head())) # Populate warmup data for index, row in history.loc["BTCUSD"].iterrows(): self.fast.Update(index, row["close"]) self.slow.Update(index, row["close"]) # Log warmup status self.Log( "FAST {0} READY. Samples: {1}".format("IS" if self.fast.IsReady else "IS NOT", self.fast.Samples)) self.Log( "SLOW {0} READY. Samples: {1}".format("IS" if self.slow.IsReady else "IS NOT", self.slow.Samples)) self.previous = None def OnData(self, data): # 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 # Determine number of BTC held holdings = self.Portfolio["BTCUSD"].Quantity # Log stats #self.Log("Holding {} BTCUSD @ {}".format(str(holdings), holdings * self.Securities["BTCUSD"].Price))) # 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 * d.Decimal(1 + tolerance): self.Log("BUY >> {0}".format(self.Securities["BTCUSD"].Price)) self.SetHoldings("BTCUSD", 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 holdings > 0 and self.fast.Current.Value < self.slow.Current.Value: self.Log("SELL >> {0}".format(self.Securities["BTCUSD"].Price)) self.SetHoldings("BTCUSD", 0) self.previous = self.Time