Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
import clr
clr.AddReference("System")
clr.AddReference("QuantConnect.Algorithm")
clr.AddReference("QuantConnect.Common")

from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
import datetime
from datetime import timedelta

import numpy as np
from sklearn import preprocessing
from sklearn.linear_model import Ridge

import pandas as pd
#import statsmodels.api as sm

class ScikitLearnLinearRegressionAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2018, 1, 6)  # Set Start Date # BTC Future Start Date 2009, 1, 1
        self.SetEndDate(2018, 2, 6) # Set End Date
        self.SetCash(1000000)  # Set Strategy Cash
        
        self.lookback = 30 #*24*60 # number of previous days for training # one month # regression
        self.testing = 10 #testing period table
        
        self.long_quantile = 0.9
        self.short_quantile = 0.1
        self.close_quantile = 0.15
        self.alpha = 0.5
        

         #1. Request BTC futures and save the BTC security
        #self.BTC = self.AddFuture(Futures.Currencies.BTC, Resolution.Minute) 
        self.BTC = self.AddCrypto("BTCUSD", Resolution.Minute, Market.GDAX)
        self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash)
        
        #2. Set our expiry filter to return all contracts expiring within 35 days
        #self.BTC.SetFilter(0, 35)
        #self.BTC.SetFilter(lambda x: x.FrontMonth())
        
        self.Schedule.On(self.DateRules.WeekEnd(),self.TimeRules.At(23, 59) ,self.Regression)
        
        #self.exchange = self.Securities[self.BTC.Symbol].Exchange
        #if exchange.ExchangeOpen:
        
        self.Schedule.On(self.DateRules.EveryDay(self.BTC.Symbol), self.TimeRules.Every(timedelta(minutes=1)), self.Trade)
        self.run = 0
        
    def data_construction(self, look_back_period):
        slices = self.History(self.BTC.Symbol, timedelta(minutes=look_back_period), Resolution.Minute)
        if slices.empty or 'close' not in slices.columns:
            return
        slices = slices.loc[self.BTC.Symbol]
        
        df = slices[['bidclose', 'bidsize', 'askclose', 'asksize', 'open', 'close']]
        
        self.Log(f"df:\n{df.to_string()}")
        self.Quit()
        return
        
        #df = pd.DataFrame({"bidclose":bidclose, "bidsize":bidsize, "askclose":askclose, "asksize":asksize, "open":openprice, "close":close}, index=datetime)
        df['bidpricechange_lag']=df['bidclose']-df['bidclose'].shift(1)
        df['askpricechange_lag']=df['askclose']-df['askclose'].shift(1)
        df['bidsizediff_lag']=df['bidsize']-df['bidsize'].shift(1)
        df['asksizediff_lag']=df['asksize']-df['asksize'].shift(1)
        df=df.dropna(axis=0)
        
        deltaVolumeBid=[]
        for i in df.index:
            if df.loc[i,'bidpricechange_lag']  > 0:
                deltaVolumeBid.append(df.loc[i,'bidsize'])
            elif df.loc[i,'bidpricechange_lag']  < 0:
                deltaVolumeBid.append(0)
            else:
                deltaVolumeBid.append(df.loc[i,'bidsizediff_lag'])
        
        df['deltaVolumeBid']=deltaVolumeBid
        
        deltaVolumeAsk=[]
        for j in df.index:
            if df.loc[j,'askpricechange_lag']  > 0:
                deltaVolumeAsk.append(0)
            elif df.loc[j,'askpricechange_lag']  < 0:
                deltaVolumeAsk.append(df.loc[j,'asksize'])
            else:
                deltaVolumeAsk.append(df.loc[j,'asksizediff_lag'])
        
        
        df['deltaVolumeAsk']=deltaVolumeAsk
        df['Return']=(df['close'].shift(-1)/df['open'].shift(-1))-1 #open # default trading open?
        df['VOI']=df['deltaVolumeBid']-df['deltaVolumeAsk']
        df['OIR']=(df['bidsize']-df['asksize'])/(df['bidsize']+df['asksize'])
        df=df.fillna(0)     # As I checked the data and see that bidsize/asksize are 0 in some timestamps
        df['SP']=df['askclose']-df['bidclose']
        sp_0index = df[df["SP"]==0].index   
        df.loc[sp_0index, "SP"] = 1       # to ensure that adjusted VOI won't be nan 
        
        df['VOI_SP']=(df['VOI'])/df['SP']
        df['OIR_SP']=(df['OIR'])/df['SP']
        
        df['VOI_SP_lag1']=df['VOI_SP'].shift(1)
        df['VOI_SP_lag2']=df['VOI_SP'].shift(2)
        df['VOI_SP_lag3']=df['VOI_SP'].shift(3)
        df['VOI_SP_lag4']=df['VOI_SP'].shift(4)
        df['VOI_SP_lag5']=df['VOI_SP'].shift(5)
        
        df['OIR_SP_lag1']=df['OIR_SP'].shift(1)
        df['OIR_SP_lag2']=df['OIR_SP'].shift(2)
        df['OIR_SP_lag3']=df['OIR_SP'].shift(3)
        df['OIR_SP_lag4']=df['OIR_SP'].shift(4)
        df['OIR_SP_lag5']=df['OIR_SP'].shift(5)
        df=df.dropna(axis=0)
        
        return df
    
    def Regression(self):
        df = self.data_construction(self.lookback)
        return
        
        X = df[["VOI_SP", "VOI_SP_lag1", "VOI_SP_lag2", "VOI_SP_lag3", "VOI_SP_lag4", "VOI_SP_lag5", "OIR_SP", 
        "OIR_SP_lag1", "OIR_SP_lag2", "OIR_SP_lag3", "OIR_SP_lag4", "OIR_SP_lag5"]]

        self.scaler = preprocessing.StandardScaler().fit(X)
        X_scaled = self.scaler.transform(X)
        
        Model = Ridge(alpha = self.alpha).fit(X_scaled, df["Return"])
        df['yhat']= Model.predict(X_scaled)
        
        self.long= df['yhat'].quantile(0.9)
        self.closelong = df['yhat'].quantile(0.75)
        self.short = df['yhat'].quantile(0.1)
        self.closeshort = df['yhat'].quantile(0.25)
        self.MLmodel = Model
        self.run=1 
        
        
    def Trade(self):
        if self.run == 0:
            self.Regression()
        return
        
        df = self.data_construction(self.testing)
        
        X = df[["VOI_SP","VOI_SP_lag1", "VOI_SP_lag2", "VOI_SP_lag3", "VOI_SP_lag4", "VOI_SP_lag5", "OIR_SP", "OIR_SP_lag1", "OIR_SP_lag2", 
        "OIR_SP_lag3", "OIR_SP_lag4", "OIR_SP_lag5"]]
        
        X_scaled = self.scaler.transform(X)
        df['yhat'] = self.MLmodel.predict(X_scaled)
        
        predictedReturn = df.iloc[-1]['yhat']


        if not self.Portfolio.Invested:
            if predictedReturn > self.long:
                self.SetHoldings(self.BTC.Symbol, 1)
                
        if self.Portfolio[self.BTC.Symbol].IsLong:
            if predictedReturn < self.closelong:
                self.Liquidate(self.BTC.Symbol)