Overall Statistics |
Total Trades 3 Average Win 0% Average Loss 0% Compounding Annual Return 640.450% Drawdown 54.400% Expectancy 0 Net Profit 295.850% Sharpe Ratio 1.889 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0.001 Beta 134.056 Annual Standard Deviation 0.976 Annual Variance 0.952 Information Ratio 1.875 Tracking Error 0.976 Treynor Ratio 0.014 Total Fees $276.64 |
import numpy as np ### <summary> ### Basic template algorithm simply initializes the date range and cash. This is a skeleton ### framework you can use for designing an algorithm. ### </summary> 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 * from QuantConnect.Orders import * import decimal as d class MovingAverageAlgorithm(QCAlgorithm): def __init__(self): # Market parameters self.previousTime = None self.stopTicket = None self.cryptoassets = ["BTCUSD", "ETHUSD", "LTCUSD"] self.sell_flags = {crypto: True for crypto in self.cryptoassets} self.market = Market.GDAX self.brokerage = BrokerageName.GDAX self.resolution = Resolution.Daily # Strategy parameters self.length_fast_ema = 5 self.length_slow_ema = 15 def Initialize(self): self.SetStartDate(2017,6,1) # Set Start Date self.SetEndDate(2018,2,5) # Set End Date self.Portfolio.SetCash(100000) self.ema_fast_buy = {} self.ema_slow_buy = {} self.ema_slow_sell = {} self.ema_fast_sell= {} for crypto in self.cryptoassets: self.AddCrypto(crypto, self.resolution, self.market) # symbol to trade # Indicators # self.ema_fast_sell[crypto] = self.EMA(crypto, 7, self.resolution) # self.ema_slow_sell[crypto] = self.EMA(crypto, 21, self.resolution) # self.ema_fast_buy[crypto] = self.EMA(crypto, 30, self.resolution) # self.ema_slow_buy[crypto] = self.EMA(crypto, 90, self.resolution) # self.btc = Identity("BTCUSD") # self.eth = Identity("ETHUSD") # self.ltc = Identity("LTCUSD") # self.btcweighted = IndicatorExtensions.Times(self.btc, 0.33) # self.ethweighted = IndicatorExtensions.Times(self.eth, 0.33) # self.ltcweighted = IndicatorExtensions.Times(self.ltc, 0.33) # self.index1 = IndicatorExtensions.Plus(self.btcweighted, self.ethweighted) # self.index2 = IndicatorExtensions.Plus(self.index1, self.ltcweighted) self.SetBrokerageModel(self.brokerage, AccountType.Cash) # crypto brokerage coinPlot = Chart('Portfolio') # On the Trade Plotter Chart we want 3 series: trades and price: coinPlot.AddSeries(Series('Equity', SeriesType.Line, 0)) #coinPlot.AddSeries(Series('Benchmark', SeriesType.Line, 0)) def OnData(self, data): for crypto in self.cryptoassets: # if crypto == "LTCUSD": # continue # Wait for indicators to fully initialize #if not self.ema_slow_buy[crypto].IsReady: #or not self.btc.IsReady: # or not self.ltc.IsReady or not self.eth.IsReady \ # or not self.btcweighted.IsReady or not self.ltcweighted.IsReady or not self.ethweighted.IsReady \ # or not self.index1.IsReady or not self.index2.IsReady: #return quote = crypto[3:] base = crypto[:3] # # Allow one trade maximum per day # if self.previousTime is not None and self.previousTime.date() == self.Time.date(): # continue # Retrieve quote asset. CashBook is a dictionary of currencies (including crypto assets) availableQuote = self.Portfolio.CashBook[quote].Amount # Retrieve current holdings holdings = self.Portfolio.CashBook[base].Amount * d.Decimal(0.99) # Retrieve current price currentPrice = self.Securities[crypto].Close # Define a small tolerance to avoid bouncing when comparing indicators: tolerance = 0.015 quantity = self.CalculateOrderQuantity(crypto, 0.33) * d.Decimal(0.99) lot = self.Securities[crypto].SymbolProperties.LotSize quantity = round(quantity/lot-d.Decimal(0.5))*lot # -0.5 is present to round down the quantity ## BUY ORDER ## # 1. Go long if we're currently short or flat # Note that we cannot short crypto assets at the moment with GDAX API # 2. If fast ema is greater than slow ema, then go long if holdings <= 0:# and self.sell_flags[crypto]: #if self.ema_fast_buy[crypto].Current.Value > self.ema_slow_buy[crypto].Current.Value * d.Decimal(1 + tolerance): buyTicket = self.MarketOrder(crypto, quantity) # self.sell_flags[crypto] = False # stopPrice = round(currentPrice*d.Decimal(0.9), 2) # self.stopTicket = self.StopMarketOrder(crypto, -buyTicket.Quantity, stopPrice) ## SELL ORDER ## # 1. Liquidate if we're currently long # 2. If fast ema is less than slow ema then liquidate the long # else: # if self.ema_fast_sell[crypto].Current.Value < self.ema_slow_sell[crypto].Current.Value: # self.Liquidate(crypto) # self.sell_flags[crypto] = True # if self.stopTicket is not None: # self.stopTicket.Cancel() # self.stopTicket = None # Plot indicators and benchma #index = (self.Securities["BTCUSD"].Price + self.Securities["ETHUSD"].Price + self.Securities["LTCUSD"].Price) * d.Decimal(0.33) #index = self.Securities["BTCUSD"].Price self.Plot('Portfolio', 'Equity', self.Portfolio.TotalPortfolioValue) #self.Plot('Portfolio', 'Benchmark', index) # targetbuy = self.CalculateOrderQuantity(crypto, 0.33) # targetsell = self.CalculateOrderQuantity(crypto, 0.16) # if holdings <= 0: # quantitybuy = targetbuy * d.Decimal(0.99) # self.MarketOrder(crypto, quantitybuy) # continue # else: # quantitybuy = (targetbuy - holdings) * d.Decimal(0.99) # quantitysell = (holdings - targetsell) * d.Decimal(0.99) # # Define a small tolerance to avoid bouncing when comparing indicators: # tolerance = 0.015 # ## BUY ORDER ## # # 1. Go long if we're currently short or flat # # Note that we cannot short crypto assets at the moment with GDAX API # # 2. If fast ema is greater than slow ema, then go long # if holdings < self.CalculateOrderQuantity(crypto, 0.32): # if self.ema_fast[crypto].Current.Value > self.ema_slow[crypto].Current.Value * d.Decimal(1 + tolerance): # self.MarketOrder(crypto, quantitybuy) # self.sell_flags[crypto] = False # ## SELL ORDER ## # # 1. Liquidate if we're currently long # # 2. If fast ema is less than slow ema then liquidate the long # else: # if self.ema_fast[crypto].Current.Value < self.ema_slow[crypto].Current.Value and not self.sell_flags[crypto]: # self.MarketOrder(crypto, -holdings/2) # self.sell_flags[crypto] = True