| Overall Statistics |
|
Total Trades 65 Average Win 10.16% Average Loss -6.11% Compounding Annual Return 13.039% Drawdown 21.800% Expectancy 0.914 Net Profit 500.817% Sharpe Ratio 0.776 Loss Rate 28% Win Rate 72% Profit-Loss Ratio 1.66 Alpha 0.113 Beta -0.025 Annual Standard Deviation 0.143 Annual Variance 0.021 Information Ratio 0.149 Tracking Error 0.222 Treynor Ratio -4.392 Total Fees $1045.13 |
# https://quantpedia.com/Screener/Details/14
from QuantConnect.Data.UniverseSelection import *
import math
import numpy as np
import pandas as pd
import scipy as sp
from datetime import datetime
from collections import *
from scipy import stats
class DualMomentumGem(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2005, 1, 1) # Set Start Date
self.SetEndDate(2019, 8, 15) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
self.us = self.AddEquity("SPY", Resolution.Minute).Symbol
self.worldExUS = self.AddEquity("EFA", Resolution.Minute).Symbol
self.tbill = self.AddEquity("TLT", Resolution.Minute).Symbol #TLT
self.lookBackPeriod = 43200
self.symbolDataDict = {symbol:SymbolData(symbol,self.lookBackPeriod) for symbol in [self.us,self.worldExUS,self.tbill]}
self.Schedule.On(self.DateRules.MonthEnd("SPY"),self.TimeRules.BeforeMarketClose("SPY",10), self.Rebalance)
self.leverage = 1.0
self.Portfolio.MarginCallModel = MarginCallModel.Null;
def Rebalance(self):
if self.symbolDataDict[self.us].Return < self.symbolDataDict[self.worldExUS].Return:
self.currentLong = self.worldExUS
elif self.symbolDataDict[self.worldExUS].Return < self.symbolDataDict[self.tbill].Return:
self.currentLong=self.tbill
else:
self.currentLong = self.us
stocksInvested = [x.Key for x in self.Portfolio if x.Value.Invested]
if not stocksInvested or self.currentLong not in stocksInvested:
self.SetHoldings(self.currentLong, self.leverage, True)
def OnData(self, data):
for symbol, symbolData in self.symbolDataDict.items():
if not symbolData.IsReady:
history = self.History(symbol, self.lookBackPeriod, Resolution.Minute)
if str(symbol) in history.index:
symbolData.WarmUpIndicator(history.loc[str(symbol)])
else:
symbolData.Update(self.Securities[symbol].Close)
class SymbolData:
def __init__(self, symbol, lookBackPeriod):
self.symbol = symbol
self.Time = datetime.min
self.IsReady = False
self.Return = 0
self.queue = deque(maxlen=lookBackPeriod)
self.lookBackPeriod = lookBackPeriod
def Update(self, value):
self.queue.appendleft(value)
self.Return = self.queue[0]/self.queue[-1]-1
count = len(self.queue)
self.IsReady = count == self.queue.maxlen
def WarmUpIndicator(self, history):
for tuple in history.itertuples(): self.Update(tuple.close)