Overall Statistics |
Total Trades 73 Average Win 6.96% Average Loss -3.75% Compounding Annual Return 9.771% Drawdown 21.700% Expectancy 0.825 Net Profit 179.056% Sharpe Ratio 0.647 Loss Rate 36% Win Rate 64% Profit-Loss Ratio 1.86 Alpha 0.085 Beta 0.97 Annual Standard Deviation 0.161 Annual Variance 0.026 Information Ratio 0.526 Tracking Error 0.161 Treynor Ratio 0.107 Total Fees $1205.30 |
# 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(2008, 1, 1) # Set Start Date self.SetEndDate(2019, 1, 1) # Set Start Date self.SetCash(100000) # Set Strategy Cash self.us = self.AddEquity("SPY", Resolution.Daily).Symbol self.worldExUS = self.AddEquity("VEU", Resolution.Daily).Symbol self.tbill = self.AddEquity("SHV", Resolution.Daily).Symbol #SHY self.agg = self.AddEquity("BND", Resolution.Daily).Symbol # AGG self.lookBackPeriod = 100 self.symbolDataDict = {symbol:SymbolData(symbol,self.lookBackPeriod) for symbol in [self.us,self.worldExUS,self.tbill,self.agg]} self.Schedule.On(self.DateRules.MonthEnd("SPY"),self.TimeRules.AfterMarketOpen("SPY"), self.Rebalance) self.leverage = 1.3 self.Portfolio.MarginCallModel = MarginCallModel.Null; def Rebalance(self): if self.symbolDataDict[self.us].Return < self.symbolDataDict[self.tbill].Return: self.currentLong = self.agg elif self.symbolDataDict[self.us].Return > self.symbolDataDict[self.worldExUS].Return: self.currentLong=self.us else: self.currentLong = self.worldExUS 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.Daily) 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)