Overall Statistics
Total Trades
3141
Average Win
0.24%
Average Loss
-0.27%
Compounding Annual Return
-2.244%
Drawdown
39.200%
Expectancy
-0.082
Net Profit
-28.323%
Sharpe Ratio
-0.237
Loss Rate
51%
Win Rate
49%
Profit-Loss Ratio
0.87
Alpha
-0.024
Beta
0.108
Annual Standard Deviation
0.068
Annual Variance
0.005
Information Ratio
-0.583
Tracking Error
0.16
Treynor Ratio
-0.149
Total Fees
$0.00
 
 
#The investment universe consists of currencies from developed countries (the Euro area, Australia, Canada, Denmark, Japan, New Zealand, Norway, Sweden,
#Switzerland, and the United Kingdom). The average forward discount (AFD) is calculated for this basket of currencies (each currency has an equal weight).
#The average 3-month rate could be used instead of the AFD in the calculation. The AFD is then compared to the 3-month US Treasury rate. The investor
#goes long on the US dollar and goes short on the basket of currencies if the 3-month US Treasury rate is higher than the AFD. The investor goes short
#on the US dollar and long on the basket of currencies if the 3-month US Treasury rate is higher than the AFD. The portfolio is rebalanced monthly.

from datetime import datetime
import pandas as pd

class Dollar_Carry_Trade(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2005, 1, 1)
        self.SetEndDate(datetime.now())
        self.SetCash(100000)
        
        self.avg_bond_yields = pd.read_csv('https://docs.google.com/spreadsheets/d/15GO61pfTKSaAr4tNmHkxyW7JeXWiFxuCBemdC_tZSvU/export?format=csv', dtype={'date':str}, index_col='date') #   header=None)
        
        qc_available_pairs = ['AUDUSD','USDCAD','USDCHF','EURUSD','GBPUSD','USDJPY','USDNOK','NZDUSD','USDSEK']
        self.usd_first = [x for x in qc_available_pairs if 'USD' in x[:3]]
        self.currency_first = [x for x in qc_available_pairs if 'USD' in x[-3:]]
        
        for fx_pair in qc_available_pairs:
            self.AddForex(fx_pair, Resolution.Daily, Market.Oanda)

        self.Schedule.On(self.DateRules.MonthStart(qc_available_pairs[0]), self.TimeRules.AfterMarketOpen(qc_available_pairs[0]), self.Rebalance)

    def Rebalance(self):
        self.Liquidate()
        
        date = str(self.Time.month) + '/' + str(self.Time.year)
        current_row_index = self.avg_bond_yields.index.get_loc(date)
        row = self.avg_bond_yields.iloc[current_row_index - 1]

        long = []
        short = []

        treasuries_3m_rate = row['USD']
        average = row['average']
        
        if treasuries_3m_rate > average:
            # long on the US dollar and goes short on the basket of currencies 
            long = self.usd_first
            short = self.currency_first
        else:
            # short on the US dollar and long on the basket of currencies
            long = self.currency_first
            short = self.usd_first

        for symbol in long:
            self.SetHoldings(symbol, 1/9)
        for symbol in short:
            self.SetHoldings(symbol, -1/9)