Overall Statistics
Total Orders
913
Average Win
1.91%
Average Loss
-0.45%
Compounding Annual Return
9.849%
Drawdown
63.500%
Expectancy
1.502
Start Equity
100000
End Equity
577154.48
Net Profit
477.154%
Sharpe Ratio
0.32
Sortino Ratio
0.353
Probabilistic Sharpe Ratio
0.068%
Loss Rate
53%
Win Rate
47%
Profit-Loss Ratio
4.28
Alpha
0.043
Beta
1.244
Annual Standard Deviation
0.256
Annual Variance
0.066
Information Ratio
0.295
Tracking Error
0.171
Treynor Ratio
0.066
Total Fees
$4488.85
Estimated Strategy Capacity
$1000000.00
Lowest Capacity Asset
ERUS URI1LRYQ5ISL
Portfolio Turnover
0.74%
#region imports
from AlgorithmImports import *
#endregion


class ValueEffectWithinCountries(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2000, 1, 8)   # Set Start Date
        self.set_end_date(2018, 9, 1)     # Set End Date
        self.set_cash(100000)            # Set Strategy Cash
        self._symbol = self.add_data(CAPE, "CAPE", Resolution.DAILY).symbol

        self._symbols = Symbols().tickers
        for key, value in self._symbols.items():
            self.add_equity(value[1], Resolution.DAILY)  
        
    def on_data(self, data):
        if data.contains_key(self._symbol):
            cape = {}
            for key, value in self._symbols.items(): 
                if not self.securities[value[1]].price:
                    continue
                cape[value[1]] = data[self._symbol].get_property(key)

            sorted_cape = sorted(cape, key=lambda x: cape[x])
            
            # invests the cheapest 33% of countries if those countries have a CAPE below 15
            lowest_cape = sorted_cape[:int(1/3*len(sorted_cape))]
            long_list = [i for i in lowest_cape if cape[i] < 15]
            invested = [x.key for x in self.portfolio if x.value.invested]
            
            for i in invested:
                if i.value not in long_list:
                    self.liquidate(i)
            
            for i in long_list:
                self.set_holdings(i, 1/len(long_list))
                    

class CAPE(PythonData):

    def get_source(self, config, date, is_live_mode):
        return SubscriptionDataSource("https://indices.cib.barclays/file.app?action=shared&path=shiller/cape.csv", SubscriptionTransportMedium.REMOTE_FILE)

    def reader(self, config, line, date, is_live_mode):
        if not (line.strip() and line[1].replace('.', '', 1).isdigit()): 
            return None

        try:
            index = CAPE()
            index.symbol = config.symbol
            
            data = line.split(',')
            index.time = datetime.strptime(data[0], "%d/%m/%Y")
            symbols = Symbols().tickers
            for key, value in symbols.items():
                index[key] = float(data[value[0]]) if data[value[0]] else 100000 # very large number to avoid be selected
            return index

        except:
            return None


class Symbols:
    def __init__(self):
        # the indiex is the country name
        # the first element of the value is the column number of CAPE ratio value in custom dataset
        # the second element of the value is the corresponding country ETF
        
        self.tickers = {"Australia":[1, "EWA"],       # ASX All Ordinaries Index: iShares MSCI Australia ETF
                        "Brazil":[2, "EWZ"],          # Indice Bovespa (Ibovespa): iShares MSCI Brazil ETF
                        "Canada":[3, "XIC"],          # S&P/TSX Composite Index: iShares S&P TSX Capped Cmpst Indx Fnd
                        "China":[4, "MCHI"],          # SSE Composite: iShares MSCI China Index Fund
                        "Europe":[5, "IEUR"],         # STOXX Europe 600 Index: iShares Core MSCI Europe ETF
                        "France":[6, "EWQ"],          # CAC 40 Index: iShares MSCI France ETF
                        "Germany":[7, "EWG"],         # HDAX Index: iShares MSCI Germany ETF
                        "Hong Kong":[8, "EWH"],       # Hang Seng Index: iShares MSCI Hong Kong Index Fund
                        "Italy":[9, "EWI"],           # FTSE MIB Index: iShares MSCI Italy ETF
                        "India":[10, "INDY"],         # NIFTY 50 Index: iShares India 50 ETF
                        "Israel":[11, "EIS"],         # Tel Aviv 125 Index: iShares MSCI Israel ETF
                        "Japan":[12, "EWJ"],          # All Public Companies: iShares MSCI Japan ETF
                        "Korea":[13,"EWY"],           # KOSPI Index: iShares MSCI South Korea ETF
                        "Mexico":[14, "EWW"],         # &P/BMV IPC Index: iShares MSCI Mexico ETF
                        "Netherlands":[15, "EWN"],    # NL 25 Index: iShares MSCI Netherlands ETF
                        "Poland":[16, "EPOL"],        # WIG Index: iShares MSCI Poland ETF  
                        "Russia":[17, "ERUS"],        # RTS Index: iShares MSCI Russia ETF
                        "Singapore":[18, "EWS"],      # STI Index:  iShares MSCI Singapore ETF
                        "Southafrica":[19, "EZA"],    # FTSE/JSE CAP Top 40 Index: iShares MSCI South Africa ETF
                        "Spain":[20, "EWP"],          # IBEX 35 Index: iShares MSCI Spain ETF
                        "Sweden":[21, "EWD"],         # OMXS 30 index: iShares MSCI Sweden ETF
                        "Switzerland":[22, "EWL"],    # CH 20 index: iShares MSCI Switzerland ETF
                        "Taiwan":[23, "EWT"],         # TWSE: iShares MSCI Taiwan ETF
                        "Turkey":[24, "TUR"],         # BIST 100: iShares MSCI Turkey ETF
                        "UK":[25, "EWU"],             # FTSE 100 Index: iShares MSCI United Kingdom ETF
                        "USA":[26, "SPY"]            # S&P 500 Index: SPDR S&P 500 ETF 
        }