| Overall Statistics |
|
Total Trades 135 Average Win 1.80% Average Loss -2.09% Compounding Annual Return -4.541% Drawdown 54.800% Expectancy -0.410 Net Profit -52.837% Sharpe Ratio -0.426 Probabilistic Sharpe Ratio 0.000% Loss Rate 68% Win Rate 32% Profit-Loss Ratio 0.86 Alpha -0.038 Beta 0.035 Annual Standard Deviation 0.081 Annual Variance 0.007 Information Ratio -0.714 Tracking Error 0.187 Treynor Ratio -0.997 Total Fees $247.30 Estimated Strategy Capacity $22000.00 Lowest Capacity Asset EFNL V3L973NBYZQD |
# https://quantpedia.com/Screener/Details/16
import pandas as pd
from datetime import datetime
class CountryEquityIndexesMeanReversionAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2005,3, 1)
self.SetEndDate(2021,4,28)
self.SetCash(100000)
# create a dictionary to store return indicators for all symbols
self.data = {}
period = 21*12
self.symbols = ["EWA", # iShares MSCI Australia Index ETF
"EWO", # iShares MSCI Austria ETF
"EWK", # iShares MSCI Belgium ETF
"EWC", # iShares MSCI Canada ETF
"EDEN", # iShares MSCI Denmark ETF
"EFNL", # iShares MSCI Finland ETF
"EWQ", # iShares MSCI France ETF
"EWG", # iShares MSCI Germany ETF
"GREK", # iShares MSCI Greece ETF
"EWH", # iShares MSCI Hong Kong Index ETF
"EIRL", # iShares MSCI Ireland ETF
"EWI", # iShares MSCI Italy Index ETF
"EWJ", # iShares MSCI Japan Index ETF
"EWN", # iShares MSCI Netherlands Index ETF
"ENZL", # iShares MSCI New Zealand Investable Market Index Fund
"NORW" # Global X FTSE Norway 30 ETF
"PGAL", # Global X MSCI Portugal ETF
"EWS", # iShares MSCI Singapore Index ETF
"EWP", # iShares MSCI Spain Index ETF
"EWD", # iShares MSCI Sweden Index ETF
"EWL", # iShares MSCI Switzerland Index ETF
"IVV", # iShares S&P 500 Index
"EWU"] # iShares MSCI U.K. Index ETF
# warm up the Return indicator
self.SetWarmUp(period)
for symbol in self.symbols:
self.AddEquity(symbol, Resolution.Daily)
self.data[symbol] = self.ROC(symbol, period, Resolution.Daily)
# shcedule the function to fire at the month start
self.Schedule.On(self.DateRules.MonthStart("IVV"), self.TimeRules.AfterMarketOpen("IVV"), self.Rebalance)
# create the flag variable to save the number of months passed
self.months = -1
def OnData(self, data):
pass
def Rebalance(self):
# rebalance the portfolio every six months
self.months += 1
if self.months % 12 != 0: return
sorted_symbols = sorted(self.data, key=lambda x: self.data[x].Current.Value)
top = sorted_symbols[-5:]
bottom = sorted_symbols[:5]
for kvp in self.Portfolio:
security_hold = kvp.Value
# liquidate the security which is no longer in the list
if security_hold.Invested and (security_hold.Symbol.Value not in top+bottom):
self.Liquidate(security_hold.Symbol)
for short in top:
if not self.Portfolio[short].Invested:
self.SetHoldings(short, -0.5/len(top))
for long in bottom:
if not self.Portfolio[long].Invested:
self.SetHoldings(long, 0.5/len(bottom))