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