| Overall Statistics |
|
Total Trades 110 Average Win 583.59% Average Loss -5.14% Compounding Annual Return 30267.997% Drawdown 59.400% Expectancy 25.939 Net Profit 31132.125% Sharpe Ratio 3.465 Loss Rate 76% Win Rate 24% Profit-Loss Ratio 113.49 Alpha 1.961 Beta 0.777 Annual Standard Deviation 1.425 Annual Variance 2.03 Information Ratio 0.968 Tracking Error 1.143 Treynor Ratio 6.353 Total Fees $2173.85 |
import decimal as d
### <summary>
### GDAX Playground.
### </summary>
### <meta name="tag" content="crypto bitcoin GDAX SetHoldings order PostType playground" />
class GDAXPlaygroundAlgorithm(QCAlgorithm):
def Initialize(self):
#-- QC Parameters ------------------------------------------------------
self.cryptos = ["BTCUSD", "ETHUSD", "LTCUSD"]
self.cash = 500
self.SetStartDate(2017, 1, 1)
self.SetEndDate(2018, 1, 1)
self.resolution = Resolution.Daily
#-----------------------------------------------------------------------
#-- Other Parameters ---------------------------------------------------
self.maxPerTrade = 0.15 # (from 0 to 1) - e.g.: 0.1 <=> 10% of total portfolio value
self.ema10s = dict()
self.ema50s = dict()
self.sma10s = dict()
self.sma50s = dict()
#-----------------------------------------------------------------------
self.cash = d.Decimal(self.cash)
self.SetCash(self.cash)
self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash)
for crypto in self.cryptos:
self.AddCrypto(crypto, self.resolution)
self.Securities[crypto].SetLeverage(1)
self.ema10s.update({crypto: self.EMA(crypto, 10, Resolution.Daily)})
self.ema50s.update({crypto: self.EMA(crypto, 20, Resolution.Daily)})
self.sma10s.update({crypto: self.SMA(crypto, 10, Resolution.Daily)})
self.sma50s.update({crypto: self.SMA(crypto, 50, Resolution.Daily)})
history = self.History(crypto, 50);
for tradeBar in history:
self.ema10s[crypto].Update(tradeBar.EndTime, tradeBar.Close);
self.ema50s[crypto].Update(tradeBar.EndTime, tradeBar.Close);
self.sma10s[crypto].Update(tradeBar.EndTime, tradeBar.Close);
self.sma50s[crypto].Update(tradeBar.EndTime, tradeBar.Close);
self.SetBenchmark(SecurityType.Crypto, "ETHUSD")
def OnData(self, data):
for crypto in self.cryptos:
security = self.Securities[crypto]
price = security.Price
portfolio = self.Portfolio
if price * d.Decimal(self.maxPerTrade) * d.Decimal(0.98) > portfolio.Cash:
continue
ema10 = self.ema10s[crypto].Current.Value
ema50 = self.ema50s[crypto].Current.Value
sma10 = self.sma10s[crypto].Current.Value
sma50 = self.sma50s[crypto].Current.Value
quantity = security.Holdings.Quantity
# Sell when price is starting to crash
if quantity > 0 and (ema10 < ema50):
self.Liquidate(crypto)
# Buy when price is trending up
elif price > sma10 and price > sma50:
self.SetHoldings(crypto, self.maxPerTrade)
# Overrides SetHoldings
def SetHoldings(self, symbol, ratio):
security = self.Securities[symbol]
if not security.IsTradable:
self.Debug("{} is not tradable.".format(symbol))
return
ratio = d.Decimal(ratio)
price, quantity = security.Price, security.Holdings.Quantity
# Keep 2% Cash (for rounding errors and safety)
orderQuantity = self.Portfolio.Cash * d.Decimal(0.98) * ratio / price
self.MarketOrder(symbol, orderQuantity)
# END