Overall Statistics |
Total Trades 1502 Average Win 0.26% Average Loss -0.15% Compounding Annual Return 1.195% Drawdown 17.900% Expectancy 0.044 Net Profit 4.217% Sharpe Ratio 0.142 Probabilistic Sharpe Ratio 2.183% Loss Rate 62% Win Rate 38% Profit-Loss Ratio 1.71 Alpha 0.015 Beta -0.018 Annual Standard Deviation 0.094 Annual Variance 0.009 Information Ratio -0.438 Tracking Error 0.199 Treynor Ratio -0.751 Total Fees $29328.98 |
import numpy as np class QuantumNadionCompensator(QCAlgorithm): def Initialize(self): self.SetStartDate(2017, 1, 1) # Set Start Date self.SetCash(100000) # Set Strategy Cash _ = [self.AddCrypto(x, Resolution.Hour, Market.Bitfinex) for x in ['BTCUSD', 'ETHUSD']] self.SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Margin) # Kalman filter parameters self.theta = np.ones(2) # Hidden state - weights of the linear model self.R = None # Variance-covariance matrix self.delta = 1e-6 # System noise self.wt = self.delta / (1 - self.delta) * np.eye(2) self.vt = 1e-7 # Measurement noise # Strategy parameters self.invest_type = None # long/short BTCUSD self.invest_portf = 0.1 # Share of the portfolio to be invested into each asset def OnData(self, data): # Kalman filtering update obs = np.array([data['ETHUSD'].Close, 1]) y = data['BTCUSD'].Close if self.R is None: self.R = np.eye(2)#np.zeros((2,2)) #self.R[0,0] = 100 else: self.R = self.C + self.wt yhat = obs.dot(self.theta) et = y - yhat # Variance of the prediction at t=i Qt = obs.dot(self.R).dot(obs.T) + self.vt pred_err = np.sqrt(Qt) # Posterior values of states theta At = self.R.dot(obs.T) / Qt self.theta = self.theta + At.flatten() * et self.C = self.R - At * obs.dot(self.R) # Implement pairs trading strategy if self.invest_type is None: if et < -pred_err: # Undervalued BTC => long BTC, short ETH self.SetHoldings('BTCUSD', self.invest_portf, False) self.SetHoldings('ETHUSD', -self.theta[0] * self.invest_portf * data['ETHUSD'].Close / data['BTCUSD'].Close, False) self.invest_type = 'long' elif et > pred_err: # Overvalued BTC => long BTC, short ETH self.SetHoldings('BTCUSD', -self.invest_portf, False) self.SetHoldings('ETHUSD', self.theta[0] * self.invest_portf * data['ETHUSD'].Close / data['BTCUSD'].Close, False) self.invest_type = 'short' elif self.invest_type == 'long' and et > -pred_err or self.invest_type == 'short' and et < pred_err: self.SetHoldings('BTCUSD', 0, False) self.SetHoldings('ETHUSD', 0, False) self.invest_type = None