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
-5.906
Tracking Error
0.078
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, Lasso

import pandas as pd
from math import floor

class ScikitLearnLinearRegressionAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2018, 1, 4)  # Set Start Date 
        self.SetEndDate(2018, 3, 4) # Set End Date
        self.SetCash(1000000)  # Set Strategy Cash
        #self.Settings.FreePortfolioValuePercentage = 0.30
        
        self.timestamp = 60*24 #1day
        self.lookback = 30*24*60 # 30days, 1 month
        self.testing = 25*self.timestamp  #testing period table
        
        self.long_quantile = 0.5
        self.short_quantile = 0.5
        self.close_quantile = 0
        self.alpha = 0.1

        self.BTC = self.AddFuture(Futures.Currencies.BTC, Resolution.Minute) 
        self.AddEquity("SPY", Resolution.Minute)    
        self.AddEquity("TLT", Resolution.Minute)     
        #self.SetBenchmark("BTCUSD")
        
        self.BTC.SetFilter(lambda x: x.FrontMonth())
        
        self.Schedule.On(self.DateRules.MonthEnd(),self.TimeRules.At(23, 59) ,self.Regression)
        self.er_rebuild_model = 0
        
        self.run = 0
            
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(23, 59), self.handle_error)    
           

        
    def OnData(self, slice):
        for chain in slice.FutureChains:
            contracts_list = [contract for contract in chain.Value]
            ideal_contract = sorted(contracts_list, key=lambda k : k.OpenInterest, reverse=True)[0]
            self.contract_symbol = ideal_contract.Symbol
    
    def data_construction(self, look_back_period):
        slices = self.History(self.contract_symbol, look_back_period, Resolution.Minute)
        if slices.empty:
            return
        expiry = list(slices.index.levels[0])[0]
        history = slices.loc[expiry].loc[self.contract_symbol]
        df = history[['bidclose', 'bidsize', 'askclose', 'asksize', 'open', 'close']]
        
        if (self.timestamp != 1):
            # Resample the data
            temp_str = str(self.timestamp) + "T"
            df = df.resample(temp_str).last()
            temp_sum = df.resample(temp_str).sum()/self.timestamp
            #temp_sum = temp_sum.astype(int)
            temp_first = df.resample(temp_str).first()
            df[["bidsize", "asksize"]] = temp_sum[["bidsize", "asksize"]]
            df["open"]=temp_first["open"]
        
        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):
        try:
            df = self.data_construction(self.lookback)
            if df is None or df.empty:
                return
            self.Quit(df.head().to_string())
            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(self.long_quantile)
            self.closelong = df['yhat'].quantile(self.long_quantile-self.close_quantile)
            self.short = df['yhat'].quantile(self.short_quantile)
            self.closeshort = df['yhat'].quantile(self.short_quantile+self.close_quantile)
            self.MLmodel = Model
            self.run=1 
            
            self.Debug("long signal " + str(self.long))
            self.Debug("short signal " + str(self.short))
            self.Debug(self.MLmodel)
            self.Debug(self.Time)
            
            self.er_rebuild_model = 0
        except:
            self.er_rebuild_model = 1
            self.Debug("Model need to be rebuilt in the upcoming day " + str(self.Time))

    def handle_error(self):
        if (self.er_rebuild_model == 1):
            self.Regression()