| Overall Statistics |
|
Total Trades 718 Average Win 0.24% Average Loss -0.38% Compounding Annual Return 1.416% Drawdown 26.700% Expectancy 0.000 Net Profit 8.031% Sharpe Ratio 0.192 Loss Rate 38% Win Rate 62% Profit-Loss Ratio 0.62 Alpha -0.062 Beta 4.118 Annual Standard Deviation 0.095 Annual Variance 0.009 Information Ratio -0.014 Tracking Error 0.095 Treynor Ratio 0.004 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(2013,1, 1)
self.SetEndDate(2018, 7, 1)
self.SetCash(2500000)
# self.lme_symbols = [
# ]
self.cme_symbols = ["CHRIS/CME_LC1", # Live Cattle Futures, Continuous Contract #1
"CHRIS/CME_LN1", # Lean Hog Futures, Continuous Contract #1
] #Settle
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
] #Settle
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)
] #Settle
self.equityIndex_symbols = ["CHRIS/LIFFE_Z1", #FTSE 100 Index Futures, Continuous Contract #1 (Z1) (Front Month)
"CHRIS/CME_SP1", #S&P 500 Futures, Continuous Contract #1 (SP1) (Front Month)
"CHRIS/ASX_AP1", #ASX SPI 200 Index Futures, Continuous Contract #1 (AP1) (Front Month)
"CHRIS/LIFFE_FCE1",#CAC40 Index Futures, Continuous Contract #1 (FCE1) (Front Month)
"CHRIS/EUREX_FDAX1", #DAX Futures, Continuous Contract #1 (FDAX1) (Front Month)
"CHRIS/LIFFE_FTI1", #AEX Index Futures, Continuous Contract #1 (FTI1) (Front Month)
] #Settle
# self.nymex_symbols = [
# ]
# self.comex_symbols = [
# ]
# self.tocom_symbols = [
# ]
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.equityIndex_symbols
self.symbols_Settle = self.cme_symbols + self.ice_symbols + self.cbot_symbols
# self.symbols_Value = self.currency_symbols
# self.symbols_Value = []
# self.symbols = self.symbols_Settle + self.symbols_Value
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)
# for symbol in self.symbols_Value:
# self.AddData(QuandlForex, 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.value)
# 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):
self.long = [symbol for symbol in self.roc if self.roc[symbol].Current.Value > 0]
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 = {}
weights_short = {}
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())
for short in self.short:
weights_short[short] = volatility[short]/sum(volatility.values())
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"
class QuandlForex(PythonQuandl):
def __init__(self):
self.ValueColumnName = "Value"