| Overall Statistics |
|
Total Trades 6 Average Win 94.07% Average Loss 0% Compounding Annual Return 264.637% Drawdown 25.200% Expectancy 0 Net Profit 306.747% Sharpe Ratio 3.475 Probabilistic Sharpe Ratio 90.107% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 1.384 Beta 0.031 Annual Standard Deviation 0.514 Annual Variance 0.264 Information Ratio -4.334 Tracking Error 2.599 Treynor Ratio 57.953 Total Fees $1007.06 Estimated Strategy Capacity $11000000.00 Lowest Capacity Asset BTCUSD XJ |
class SimpleTurtleTrading(QCAlgorithm):
def Initialize(self):
# indicate whether or not logging is allowed
self.LOGGING = True
# set our start and end dates
self.SetStartDate(2020, 11, 1)
self.SetEndDate(2021, 12, 1)
# set our amount of initial cash
self.SetCash(10_000)
# set the crypto brokerage mode
self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash)
# initialize our assets and set our benchmark so we can compare our
# results to it
self.coin = self.AddCrypto("BTCUSD", Resolution.Daily, Market.GDAX)
self.SetBenchmark(self.coin.Symbol)
# initialize our rolling window size
self.WINDOW_SIZE = 55
# create our Donchian channel indicator and our simple moving average
# indicator
self.donchian = self.DCH(self.coin.Symbol, self.WINDOW_SIZE,
self.WINDOW_SIZE, Resolution.Daily)
self.sma = self.SMA(self.coin.Symbol, self.WINDOW_SIZE,
Resolution.Daily)
# create a plot for the price, max, average, and buy/sell events
self.plot_title = "Turtle Trading"
plot = Chart(self.plot_title)
plot.AddSeries(Series("Price", SeriesType.Line, 0))
plot.AddSeries(Series(f"{self.WINDOW_SIZE} Day Max",
SeriesType.Line, 0))
plot.AddSeries(Series(f"{self.WINDOW_SIZE} Day Avg",
SeriesType.Line, 0))
plot.AddSeries(Series("Buy", SeriesType.Scatter, 1))
plot.AddSeries(Series("Sell", SeriesType.Scatter, 1))
self.AddChart(plot)
# set our warmup time
self.SetWarmUp(self.WINDOW_SIZE, Resolution.Daily)
def OnData(self, data):
# if neither of our indicators are ready, return
if not all([self.donchian.IsReady, self.sma.IsReady]):
self._log("WARMING UP - {}".format(self.Time))
return
# grab the current price of our asset, then grab the upper band
# value from our donchian indicator and the average price from
# our SMA indicator
price = data[self.coin.Symbol].Close
window_max = self.donchian.UpperBand.Current.Value
window_avg = self.sma.Current.Value
# set our buying conditions
buy = all([
not self.Portfolio.Invested,
price > window_max
])
# set our sell conditions
sell = all([
self.Portfolio.Invested,
price < window_avg
])
# check to see if we are buying
if buy:
# purchase our assets
self._log("PURCHASE - price: {}, max: {}".format(price, window_max))
self.SetHoldings(self.coin.Symbol, 1.0)
self.Plot(self.plot_title, "Buy", price)
# check to seel if we are selling
elif sell:
# sell our assets
self._log("SELL - price: {}, avg: {}".format( price, window_avg))
self.Liquidate()
self.Plot(self.plot_title, "Sell", price)
# otherwise, no action is to be taken (but log it anyway so we can
# track our algorithm's progress)
else:
self._log("NO ACTION - price: {}, max: {}, avg: {}".format(
price, window_max, window_avg))
# plot the price, max, and average
self.Plot(self.plot_title, "Price", price)
self.Plot(self.plot_title, f"{self.WINDOW_SIZE} Day Max",
window_max)
self.Plot(self.plot_title, f"{self.WINDOW_SIZE} Day Avg",
window_avg)
def _log(self, s):
# check to see if logging is enabled, and if so, log the string
if self.LOGGING:
self.Log(s)