Overall Statistics
Total Trades
471
Average Win
0.17%
Average Loss
-0.47%
Compounding Annual Return
-6.893%
Drawdown
33.100%
Expectancy
-0.267
Net Profit
-22.094%
Sharpe Ratio
-0.602
Loss Rate
46%
Win Rate
54%
Profit-Loss Ratio
0.37
Alpha
-0.144
Beta
4.087
Annual Standard Deviation
0.106
Annual Variance
0.011
Information Ratio
-0.785
Tracking Error
0.106
Treynor Ratio
-0.016
Total Fees
$0.00
# https://quantpedia.com/Screener/Details/118


from QuantConnect.Python import PythonQuandl
from datetime import timedelta
import numpy as np
import pandas as pd


class TimeSeriesMomentumEffect(QCAlgorithm):

    def Initialize(self):

        self.SetStartDate(2015,1, 1) 
        self.SetEndDate(2018, 7, 1)  
        self.SetCash(2500000)

        self.cme_symbols = ["CHRIS/CME_LC1", # Live Cattle Futures, Continuous Contract #1 
                            "CHRIS/CME_LN1", # Lean Hog Futures, Continuous Contract #1 
                            ]       
        self.ice_symbols = ["CHRIS/ICE_B1", # Brent Crude Futures, Continuous Contract
                            "CHRIS/ICE_G1", # Gas Oil Futures, Continuous Contract
                            "CHRIS/ICE_CT1", # Cotton No. 2 Futures, Continuous Contract
                            "CHRIS/ICE_KC1", # Coffee C Futures, Continuous Contract
                            "CHRIS/ICE_CC1", # Cocoa Futures, Continuous Contract 
                            "CHRIS/ICE_SB1", # Sugar No. 11 Futures, Continuous Contract
                            ]       
                            
        self.cbot_symbols = ["CHRIS/CME_C1", #Corn Futures, Continuous Contract #1 (C1) (Front Month)
                             "CHRIS/CME_S1", #Soybean Futures, Continuous Contract #1 (S1) (Front Month)
                             "CHRIS/CME_SM1", #Soybean Meal Futures, Continuous Contract #1 (SM1) (Front Month)
                             "CHRIS/CME_BO1", #Soybean Oil Futures, Continuous Contract #1 (BO1) (Front Month)
                             "CHRIS/CME_W1", #Wheat Futures, Continuous Contract #1 (W1) (Front Month)
                                ]   
                                
    
        # self.currency_symbols =["AUD/USD","EUR/USD","CAD/USD","JPY/USD"]  #Value
        
        
        period = 252
        self.roc = {}
        self.symbols_Settle = self.cme_symbols + self.ice_symbols + self.cbot_symbols
        
        # self.symbols_Value = self.currency_symbols
        # self.symbols = self.symbols_Settle + self.currency_symbols
        self.symbols = self.symbols_Settle
        for symbol in self.symbols_Settle:
            self.AddData(QuandlFutures, symbol, Resolution.Daily)
            self.roc[symbol] = RateOfChange(period)
            hist = self.History([symbol], 400, Resolution.Daily).loc[symbol]
            for i in hist.itertuples():
                self.roc[symbol].Update(i.Index, i.settle)
    

        # Rebalance the portfolio every month
        self.Schedule.On(self.DateRules.MonthStart("CHRIS/CME_S1"), self.TimeRules.AfterMarketOpen("CHRIS/CME_S1"), self.Rebalance)
               

    def OnData(self, data):
        # Update the indicator value every day
        for symbol in self.symbols:
            if data.ContainsKey(symbol) and self.roc[symbol].IsReady:
                self.roc[symbol].Update(self.Time, data[symbol].Value)


    def Rebalance(self): 
        #choose underlying assests with positive momentum to long
        self.long = [symbol for symbol in self.roc if self.roc[symbol].Current.Value > 0]
        #choose underlying assests with positive momentum to long
        self.short =  [symbol for symbol in self.roc if self.roc[symbol].Current.Value < 0]
        
        for kvp in self.Portfolio:
            security_hold = kvp.Value
            # liquidate the futures which is no longer in the trading list
            if security_hold.Invested and (security_hold.Symbol.Value not in (self.long+self.short)):
                self.Liquidate(security_hold.Symbol)
        
        
        weights_long = {}   #contracts' weights for long
        weights_short = {}  #contracts' weights for short
        volatility = {}     #estimated volatility
            
        for symbol in self.symbols:
            hist = self.History(self.Symbol(symbol), 252, Resolution.Daily).loc[symbol]['value'].tolist()
            volatility[symbol] = 1/np.std(hist,ddof = 1)     #calculate the historical volatility and get its reciprocal
        
        for long in self.long:
            weights_long[long] = volatility[long]/sum(volatility.values())   #normalize the weights, making sure the sum is 1
        for short in self.short:
            weights_short[short] = volatility[short]/sum(volatility.values()) #normalize the weights, making sure the sum is 1
        
        #SetHoldings to trade
        for long in self.long:
            self.SetHoldings(long, 0.5*weights_long[long]/sum(weights_long.values())) 
        for short in self.short:
            self.SetHoldings(short, -0.5*weights_short[short]/sum(weights_short.values()))


class QuandlFutures(PythonQuandl):
    
    def __init__(self):
        self.ValueColumnName = "Settle"  
    #set the column name of value to "Settle", becasue the data from Quandl has a column named "Settle".