Overall Statistics
Total Trades
164
Average Win
1.38%
Average Loss
-1.22%
Compounding Annual Return
1.173%
Drawdown
9.700%
Expectancy
0.189
Net Profit
19.946%
Sharpe Ratio
0.301
Loss Rate
44%
Win Rate
56%
Profit-Loss Ratio
1.14
Alpha
0.013
Beta
-0.041
Annual Standard Deviation
0.033
Annual Variance
0.001
Information Ratio
-0.411
Tracking Error
0.169
Treynor Ratio
-0.242
Total Fees
$0.00
 
 
#Create an investment universe consisting of several currencies (10-20). Use the latest OECD Purchasing Power Parity figure to assess the fair value of each currency
#versus USD in the month of publishing and then use monthly CPI changes and exchange rate changes to create fair PPP value for the month prior to the current month.
#Go long 3 currencies that are the most undervalued (lowest PPP fair value figure) and go short 3 currencies that are the most overvalued (highest PPP fair value figure).
#Invest cash not used as margin on overnight rates. Rebalance quarterly or monthly.

from datetime import datetime
import pandas as pd

class Currency_Value_Factor(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2004, 1, 1)
        self.SetEndDate(2019, 8, 1)
        self.SetCash(100000)
        
        self.ppp_table = pd.read_csv('https://docs.google.com/spreadsheets/d/1tbGKl6bmSoP4AAYtKo5PWhljhBqwb2Lbau6171q7zD4/export?format=csv', index_col='year') #header=None)
        self.currencies = [x for x in self.ppp_table.keys()]
        
        self.qc_available_pairs = ['AUDUSD','USDCAD','USDCHF','EURUSD','GBPUSD','USDJPY','USDNOK','NZDUSD','USDSEK']
        for fx_pair in self.qc_available_pairs:
            self.AddForex(fx_pair, Resolution.Daily, Market.Oanda)

        self.Schedule.On(self.DateRules.MonthStart('EURUSD'), self.TimeRules.AfterMarketOpen('EURUSD'), self.Rebalance)

    def Rebalance(self):
        if self.Time.month != 1: return
        
        self.Liquidate()
        
        currencies_data = {}
        last_year_row = self.ppp_table.loc[self.Time.year - 1]
        
        for currency in self.currencies:
            currencies_data[currency] = last_year_row[currency]
        
        sorted_currencies = sorted(currencies_data.items(), key = lambda x: x[1], reverse = True)
        sorted_currencies = [x[0] for x in sorted_currencies]
        top = sorted_currencies[:3]
        low = sorted_currencies[-3:]
        
        weight = 1/len(top + low)
        
        for curr in low:
            if curr == 'USD': continue  # USD currency excluded
            fx_pair = curr + 'USD'
            
            if fx_pair in self.qc_available_pairs:
                self.SetHoldings(fx_pair, weight)
            else:
                fx_pair = 'USD' + curr
                if fx_pair in self.qc_available_pairs:
                    self.SetHoldings(fx_pair, -weight)

        for curr in top:
            if curr == 'USD': continue  # USD currency excluded
            fx_pair = curr + 'USD'
            
            if fx_pair in self.qc_available_pairs:
                self.SetHoldings(fx_pair, -weight)
            else:
                fx_pair = 'USD' + curr
                if fx_pair in self.qc_available_pairs:
                    self.SetHoldings(fx_pair, weight)