Overall Statistics
Total Orders
10
Average Win
0%
Average Loss
0%
Compounding Annual Return
11.352%
Drawdown
7.100%
Expectancy
0
Start Equity
25000
End Equity
31847.63
Net Profit
27.391%
Sharpe Ratio
0.678
Sortino Ratio
0.906
Probabilistic Sharpe Ratio
66.264%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0.045
Beta
-0.188
Annual Standard Deviation
0.062
Annual Variance
0.004
Information Ratio
0.133
Tracking Error
0.192
Treynor Ratio
-0.223
Total Fees
$0.00
Estimated Strategy Capacity
$1500000.00
Lowest Capacity Asset
USDINR 8G
Portfolio Turnover
0.24%
#region imports
from AlgorithmImports import *
#endregion
# The official interest rate is from Quandl
#
from AlgorithmImports import *
from NodaTime import DateTimeZone
import numpy as np

class ForexCarryTradeAlgorithm(QCAlgorithm):

    def Initialize(self):

        self.SetStartDate(2022, 1, 1) 
        self.SetEndDate(2024, 3, 31)  
        self.SetCash(25000)
        
        #tickers = ["USDEUR", "USDZAR", "USDAUD",
        #           "USDJPY", "USDTRY", "USDINR", 
        #           "USDCNY", "USDMXN", "USDCAD"]
        
        #rate_symbols = ["BCB/17900",  # Euro Area 
        #                "BCB/17906",  # South Africa
        #                "BCB/17880",  # Australia
        #                "BCB/17903",  # Japan
        #                "BCB/17907",  # Turkey
        #                "BCB/17901",  # India
        #                "BCB/17899",  # China
        #                "BCB/17904",  # Mexico
        #                "BCB/17881"]  # Canada


        rate_symbol_by_ticker = {
            "USDEUR": "BCB/17900",  # Euro Area
            "USDZAR": "BCB/17906",  # South Africa
            "USDAUD": "BCB/17880",  # Australia
            "USDJPY": "BCB/17903",  # Japan
            "USDTRY": "BCB/17907",  # Turkey
            "USDINR": "BCB/17901",  # India
            "USDCNY": "BCB/17899",  # China
            "USDMXN": "BCB/17904",  # Mexico
            "USDCAD": "BCB/17881"   # Canada
        }

        self.symbols = {}
        for ticker, rate_symbol in rate_symbol_by_ticker.items():
            forex_symbol = self.AddForex(ticker, Resolution.Daily, Market.Oanda).Symbol
            data_symbol = self.AddData(NasdaqDataLink, rate_symbol, Resolution.Daily, TimeZones.Utc, True).Symbol
            self.symbols[str(forex_symbol)] = data_symbol
                        
        #self.SetWarmUp(10)
       
        self._top = float(self.GetParameter("max_holding"))
        self._num = int(self.GetParameter("number_of_markets"))
        
        #self.Debug(f"Bond Rate directory : {dir(self.Securities[self.symbols['USDMXN']])}")
        #self.Debug(f"Bond Rate : {dir(self.Securities[self.symbols['USDMXN']].AskPrice)}")
        self.Schedule.On(self.DateRules.MonthStart("USDEUR"), self.TimeRules.AfterMarketOpen("USDEUR"), Action(self.Rebalance))
        
    def Rebalance(self):
        
        top_symbols = sorted(self.symbols, key = lambda x: self.Securities[self.symbols[x]].AskPrice)
        
        if self.IsWarmingUp:
            return
        self.SetHoldings(top_symbols[0],self._top)
        
        for j in np.arange(self._num):
            i=-1*(j+1)
            self.SetHoldings(top_symbols[i], -self._top/(self._num))

    def OnData(self, data):
        pass
    
#class QuandlRate(PythonQuandl):
#    
#    def __init__(self):
#        self.ValueColumnName = 'Value'