Overall Statistics Total Trades2Average Win0%Average Loss0%Compounding Annual Return2.984%Drawdown4.800%Expectancy0Net Profit2.999%Sharpe Ratio0.551Loss Rate0%Win Rate0%Profit-Loss Ratio0Alpha0Beta1.515Annual Standard Deviation0.038Annual Variance0.001Information Ratio0.189Tracking Error0.038Treynor Ratio0.014Total Fees\$0.00
```import numpy as np
import math
import statsmodels.api as smapi
import statsmodels as sm
from sklearn import linear_model
import pandas as pd
from sklearn import decomposition
from sklearn.decomposition import PCA
from sklearn import svm
from sklearn.preprocessing import StandardScaler

### <summary>
### Basic template algorithm simply initializes the date range and cash. This is a skeleton
### framework you can use for designing an algorithm.
### </summary>
class BasicTemplateCryptoAlgorithm(QCAlgorithm):
'''Basic template algorithm simply initializes the date range and cash'''

def Initialize(self):
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

self.SetStartDate(2017, 1, 1)  #Set Start Date
self.SetEndDate(2018, 1, 1)    #Set End Date
self.SetCash(10000)          #Set Strategy Cash
# Find more symbols here: http://quantconnect.com/data

#sets parameters
self.lookback = 30
self.n_components = 5
self.longnum = 3
self.shortnum = 3
self.highvarthres = 0.80
self.lowvarthres = 0.70

# History method returns a dict with a pandas.DataFrame - multi-index pandas DataFrame.
self.pxhistory = self.History(["BTCUSD","LTCUSD", "ETHUSD", "LTCBTC", "ETHBTC", "EURUSD", "JPYUSD", "GBPUSD", "AUDUSD", "CADUSD","CHFUSD", "CNYUSD", "SEKUSD", "NZDUSD"], self.lookback)

# prints out the tail of the dataframe
#self.Log(str(open.tail()))

#sets brokerage model
#self.SetBrokerageModel(BrokerageName.InteractiveBrokers, AccountType.Cash)

def OnData(self, data):
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.

Arguments:
data: Slice object keyed by symbol containing the stock data
'''
# Good practice to check whether the dataframe is empty
if not self.pxhistory.empty:
#filter for open prices
price_history = self.pxhistory["open"]
#switch column symbol to column headers
price_history = price_history.unstack('symbol')

#clearing all the NaNs in returns
returns = price_history.pct_change()
#for idx in returns.count():
#    returns = returns[pd.notnull(returns[list(returns)[idx]])]
#returns = returns.bfill().ffill()
returns = returns.dropna()

returns_np = StandardScaler().fit_transform(returns)
returns = pd.DataFrame(data = returns_np, columns = returns.columns, index=returns.index)

pca = PCA(n_components=self.n_components, whiten=True)
pca.fit(returns)
var = pca.explained_variance_ratio_

highcount = 1
while sum(var) > self.highvarthres:
new_components = self.n_components - highcount
pca = PCA(n_components=new_components, whiten=True)
pca.fit(returns)
var = pca.explained_variance_ratio_
highcount += 1

lowcount = 1
while sum(var) < self.lowvarthres:
new_components = self.n_components + lowcount
pca = PCA(n_components=new_components, whiten=True)
pca.fit(returns)
var = pca.explained_variance_ratio_
lowcount += 1

try:
self.Log(str(new_components))

except:
pass

pca_returns = pca.transform(returns)
factors = pd.DataFrame(pca_returns)

X = factors.iloc[0:-1,:]
lastday = factors.iloc[-1,:]
lastday = lastday.to_frame().T
pred_ret = pd.Series(index=returns.columns)

#self.Log("variance is: %s" %sum(var))

for stock in returns.columns:
Y = returns.iloc[0:-1,:]
Y = Y[stock]
#print ('shape of Y is', Y.shape)
LR = linear_model.Lasso(alpha=0.1)
LR.fit(X,Y)
#score = LR.score(X,Y)
#print ("score is:", score)

pred = LR.predict(lastday)
pred_ret.loc[stock] = pred

self.Log(str(pred_ret.nlargest(self.longnum).index))

if self.Time.minute == 0:
for stock in returns.columns:
if stock not in pred_ret.nlargest(self.longnum).index and stock not in pred_ret.nsmallest(self.shortnum).index:
self.SetHoldings(stock, 0)
elif stock in pred_ret.nlargest(self.longnum).index and pred_ret[stock] > 0:
self.SetHoldings(stock, 0.33)
elif stock in pred_ret.nsmallest(self.shortnum).index  and pred_ret[stock] < 0:
self.SetHoldings(stock, -0.33)

#if self.Time.minute == 0:
#    if not self.Portfolio.Invested:
#        self.SetHoldings("BTCUSD", 1)
#    else:
#        self.Liquidate()

#    btcHoldings = self.Portfolio.CashBook["BTC"].Amount
#    usdCash = self.Portfolio.CashBook["USD"].Amount
#    self.Log("{} - BTC holdings: {} - USD cash: {}".format(self.Time, btcHoldings, usdCash))```