Carry Trading: A step by step Guide to Profitable Strategies and Risk Management using Python

9 min

What is Carry Trading

In the vast world of finance, carry trading has emerged as a popular strategy for traders and investors seeking to capitalize on interest rate differentials between currencies.

A carry trading strategy revolves around the concept of borrowing funds in a low-interest-rate currency and investing those funds in a higher-yielding currency.

The fundamental principle behind this strategy lies in taking advantage of interest rate differentials between countries.

When implemented correctly, carry trading can result in substantial returns, making it an enticing prospect for market participants.

Many funds utilize this strategy to generate profits on the Forex market.

The DCBR fund that uses carry trade strategies on the foreign exchange market
Historical performance of carry trade strategies

Why Carry Trade is Interesting Today ?

In today's economic landscape, there are many factors that benefits to the use carry trading strategies. Here are a few :

  1. Unconventional Monetary Policies
  2. Market Volatility and Uncertainty
  3. Increasing Interest Rate Differentials
  4. Increasing Currency Correlations

Unconventional Monetary Policies

Money printing (QE)

In recent years, central banks in several countries have adopted unconventional monetary policies, such as negative interest rates and quantitative easing (QE).

These policies have contributed to lower or even negative yields in some currencies, creating an environment where carry traders can borrow at low or negative interest rates and invest in higher-yielding currencies, potentially amplifying returns.

Market Volatility and Uncertainty

Market volatility and uncertainty have also become more prevalent in recent times, driven by geopolitical tensions, economic fluctuations, and unexpected events.

Carry trade, as a strategy, can offer an avenue for traders to capitalize on short-term fluctuations in exchange rates and generate returns.

The potential for profits from both interest differentials and currency movements makes carry trading an attractive option in volatile market conditions.

Increasing Interest Rate Differentials

Currency interest rate differential matrix on 6/3/2023

Interest rate differentials between countries remain a fundamental driver of carry trade profitability.

While central banks around the world have implemented various monetary policies in response to economic conditions, interest rate differentials persist.

This creates potential opportunities for carry traders to benefit from the yield differentials between higher-yielding and lower-yielding currencies.

Increasing Currency Correlations

Currency rates correlation

The relationship between currencies is constantly evolving, influenced by a wide range of factors.

In some cases, currency correlations have become more pronounced, making it easier for carry traders to identify opportunities and implement diversified strategies.

This correlation can provide additional stability and risk management options for carry trades.

Diversification Benefits

A pie representing diversification

Carry trading can offer diversification benefits to a portfolio. By investing in multiple currency pairs and spreading risk across different economies, traders can potentially reduce their exposure to country-specific risks and achieve a more balanced risk-return profile. This diversification aspect makes carry trading an attractive option for portfolio managers and investors looking to broaden their investment horizons.

Risk and Return Considerations

Potential Returns

Carry trading offers the potential for attractive returns through interest rate differentials.

By borrowing funds in a low-interest-rate currency and investing in a higher-yielding currency, traders can earn the interest rate differential as a profit. The size of the potential returns largely depends on the interest rate spread between the two currencies involved in the trade.

Exchange Rate Risks

One of the key risks in carry trading is the volatility of exchange rates. Currencies are influenced by various economic, political, and geopolitical factors, leading to fluctuations in their values relative to each other.

These exchange rate movements can either amplify gains or offset them, impacting the overall profitability of the carry trade.

It is important to carefully analyze and assess the stability and potential volatility of the currency pairs being traded.

What history has teached us : How Japanese wifes made billions on the foreign exchange market ?

In the mid-2000s, when Japan's interest rates were at rock-bottom, an image emerged of "Mrs. Watanabe" - a representation of Japanese retail investors looking for better returns abroad, particularly in the forex markets via carry trades.

For ages, the Japanese yen (JPY) has been a go-to currency for these trades, all thanks to Japan's incredibly low interest rates.

Many made fortunes doing carry trading by borrowing low interest rate JPY and lending foreign currencies.

Yet this approach wasn't without its risks.

Imagine putting your money in a foreign currency, only to see its value plummet or watch the yen soar. That's a quick recipe for losses.

And when the 2008 financial crisis hit, many, picturing themselves as savvy traders, were caught off guard. The yen's surprising appreciation during that time dealt a blow to numerous investors.

Amplifying this risk was leveraging, where traders borrowed money to magnify their trades.

This meant bigger potential profits, but also much heftier losses. Such unpredictable swings in currency made carry trading a gamble, one that even Mrs. Watanabe couldn't always win.

How to find carry trade opportunities using Python

Step by step guide

  1. Compute the current currency interest rate differential matrix to find opportunities (or the historical evolution)
  2. Compute the historical volatility on different currency to check the stability of the currency.
  3. Compute the currency correlation to find two currencies that tend to correlates positively to avoid a loss in value due to a drastic change in currency rate.
  4. Place your orders on a broker that allow for carry trading.

How to compute the current currency interest rate differential matrix to find opportunities in Python

Computing a currency interest rate differential matrix provides a comprehensive overview of interest rate disparities among various currency pairs.

Using this will help you identify profitable carry trade opportunities, assess risk levels, diversify your portfolio, and monitor market conditions.

import pandas as pd

# We got the data from https://www.investing.com/central-banks/
data = {
    'Central Bank': ['Federal Reserve (FED)', 'European Central Bank (ECB)', 'Bank of England (BOE)', 
                     'Swiss National Bank (SNB)', 'Reserve Bank of Australia (RBA)', 'Bank of Canada (BOC)', 
                     'Reserve Bank of New Zealand (RBNZ)', 'Bank of Japan (BOJ)', 
                     'Central Bank of the Russian Federation (CBR)', 'Reserve Bank of India (RBI)', 
                     'People\'s Bank of China (PBOC)', 'Central Bank of Brazil (BCB)'],
    'Current Rate': [5.25, 3.75, 4.5, 1.5, 3.85, 4.5, 5.5, -0.10, 7.5, 6.5, 3.65, 13.75],
    'Next Meeting': ['Jun 14, 2023', 'Jun 15, 2023', 'Jun 22, 2023', 'Jun 22, 2023', 'Jun 06, 2023', 
                     'Jun 07, 2023', 'Jul 12, 2023', 'Jun 16, 2023', 'Jun 09, 2023', 'Jun 08, 2023', '', 'Jun 21, 2023'],
    'Last Change': ['May 03, 2023 (25bp)', 'May 04, 2023 (25bp)', 'May 11, 2023 (25bp)', 
                    'Mar 23, 2023 (50bp)', 'May 02, 2023 (25bp)', 'Jan 25, 2023 (25bp)', 
                    'May 24, 2023 (25bp)', 'Jan 29, 2016 (-20bp)', 'Sep 16, 2022 (-50bp)', 
                    'Feb 08, 2023 (25bp)', 'Aug 22, 2022 (-5bp)', 'Aug 03, 2022 (50bp)']
}

df = pd.DataFrame(data)

# Central Bank to Currency mapping
central_bank_to_currency = {
    'Federal Reserve (FED)': 'USD',
    'European Central Bank (ECB)': 'EUR',
    'Bank of England (BOE)': 'GBP',
    'Swiss National Bank (SNB)': 'CHF',
    'Reserve Bank of Australia (RBA)': 'AUD',
    'Bank of Canada (BOC)': 'CAD',
    'Reserve Bank of New Zealand (RBNZ)': 'NZD',
    'Bank of Japan (BOJ)': 'JPY',
    'Central Bank of the Russian Federation (CBR)': 'RUB',
    'Reserve Bank of India (RBI)': 'INR',
    'People\'s Bank of China (PBOC)': 'CNY',
    'Central Bank of Brazil (BCB)': 'BRL',
}

# Create dictionary of interest rates
interest_rates = {central_bank_to_currency[bank]: rate for bank, rate in zip(df['Central Bank'], df['Current Rate'])}

# Function to get the matrix
def get_interest_rate_matrix(currencies, interest_rates):
    data = {}
    for from_currency in currencies:
        data[from_currency] = {}
        for to_currency in currencies:
            if from_currency == to_currency:
                data[from_currency][to_currency] = 0.0
            else:
                differential = interest_rates[from_currency] - interest_rates[to_currency]
                data[from_currency][to_currency] = differential
    return pd.DataFrame(data)

currencies = list(interest_rates.keys())
interest_rate_matrix = get_interest_rate_matrix(currencies, interest_rates)
print(interest_rate_matrix)
Computing the currency interest rate differential matrix

What you are looking for ?

Try to look for the biggest spread, but be careful with the selected currencies, they must be strong (e.g. USD - CHF).

How to find low risk high reward currencies using historical volatility in Python

Computing historical volatility in currency rates is vital for carry trading as it allows traders to assess risk levels (e.g. A volatile currency will  hold more risks in a carry trade situation...), determine position sizes (e.g. The more volatile the currency the smaller the amount to invest), select suitable strategies, place effective stop-loss orders, and set realistic trade expectations (e.g. Look at what past has given us to assess realistic potential returns).

By analyzing past volatility patterns, traders can make informed decisions, manage risk, and adjust their trading approach based on the characteristics of different currency pairs.

Historical volatility provides valuable insights that help traders navigate the complexities of carry trading with greater confidence and precision.

import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
from sklearn.preprocessing import StandardScaler

# List of currency codes we're interested in
currencies = ['EUR', 'GBP', 'CHF', 'AUD', 'CAD', 'NZD', 'JPY', 'RUB', 'INR', 'CNY', 'BRL']

# Fetch data for the past 5 years
end = datetime.now()
start = end - timedelta(days=5*365)

data = yf.download([f'{cur}=X' for cur in currencies], start=start, end=end)

# Extract just the Close prices
prices = data['Close']

# Calculate the percentage change and its rolling standard deviation (volatility)
returns = prices.pct_change()
volatility = returns.rolling(window=30).std()

# Standardize the volatility
scaler = StandardScaler()
volatility_standardized = pd.DataFrame(scaler.fit_transform(volatility), columns=volatility.columns, index=volatility.index)

# Plot the standardized volatility
plt.figure(figsize=(15, 8))
for currency in volatility_standardized.columns:
    plt.plot(volatility_standardized.index, volatility_standardized[currency], label=currency)
plt.title('Standardized Currency Rate Volatility Over Time (relative to usd)')
plt.xlabel('Date')
plt.ylabel('Standardized Volatility')
plt.legend()
plt.show()
How to compute Standardized Currency Rate Volatility Over Time (relative to USD)

What are you looking for ?

The best thing you can find is two low volatile currencies. But also stability in their volatility, you don't want volatility spikes.

How to reduce correlation risks using the currency rates correlation matrix in Python

The best scenario is to have two currencies that do positively correlates. So that the arbitrage risk stays the same.

Here is how to compute it in python

import yfinance as yf
import pandas as pd
from datetime import datetime, timedelta

# List of currency codes we're interested in
currencies = ['EUR', 'GBP', 'CHF', 'AUD', 'CAD', 'NZD', 'JPY', 'RUB', 'INR', 'CNY', 'BRL']

# Fetch data for the past 15 years
end = datetime.now()
start = end - timedelta(days=15*365)

data = yf.download([f'{cur}=X' for cur in currencies], start=start, end=end)

# Extract just the Close prices
prices = data['Close']

# Calculate correlations over the past 1, 5, and 15 years
correlation_1y = prices.tail(252).corr()  # ~252 trading days in a year
correlation_5y = prices.tail(252*5).corr()
correlation_15y = prices.corr()  # All data

# Print the correlation matrices
print('Correlation over the past 1 year:\n', correlation_1y)
print('Correlation over the past 5 years:\n', correlation_5y)
print('Correlation over the past 15 years:\n', correlation_15y)

What you are looking for ?

The carry trade strategy is about borrowing in a currency while lending in another.

The worst that can happen is when your initial debt value exchanged in another currency cannot fully refund your debt.

This happens when the value of your initial debt exchange to a foreign currency fall down.

It's either the lending currency that is loosing value, or your debt currency that is appreciating.

If your two currencies of interest are moving along together, it is good. Positive correlation is good since you have no risk in exchange rate movements. If one currency is appreciating the other is too.

Negative correlation can only benefit you when your debt currency is deprecating while (or) the lending currency is appreciating.

If your currency debt is appreciating and your lending currency is deprecating, this is bad. You'll probably end up at a loss.

Why and How to set clear strategy constraints in Python

There are many ways to set constraints or risk limitations on your strategy.

  • Volatility limit: I cannot allow more than 10% movement in the two currencies or I don't want huge spikes in volatility.
  • Correlation limit: I cannot allow a correlation close to zero or sub-zero.
  • Leverage risk: If I do more than 1:5 leverage I will increase my chances of ruin.
  • Loss risk: If I loose more than 4% in a day, I liquidate the position.

How to be ready for any situations ?

One of the best thing you can do is test your strategy in completely random situations. To do this, you can test on historical data and perform a monte-carlo simulation.

A monte-carlo simulation will give you a hint on how your strategy perform in any situation.

import numpy as np
import matplotlib.pyplot as plt

# Parameters for our simplified carry trade strategy
initial_investment = 10000  # USD
borrow_rate = 0.01  # e.g., borrowing in JPY
invest_rate = 0.05  # e.g., investing in AUD
n_simulations = 1000
n_days = 365

# Monte Carlo simulation
final_returns = []

for _ in range(n_simulations):
    daily_returns = np.random.normal((invest_rate - borrow_rate) / n_days,
                                     0.01,  # assumed daily volatility
                                     n_days) + 1
    
    total_return = np.prod(daily_returns)
    final_returns.append(initial_investment * total_return)

# Visualization
plt.hist(final_returns, bins=50, facecolor='blue', alpha=0.7)
plt.xlabel('Final Return')
plt.ylabel('Frequency')
plt.title('Distribution of Returns for the Carry Trade Strategy')
plt.show()
A super simple example of a monte-carlo example in the context of carry trading strategies

Conclusion

In our current economic context a carry trading strategy can be a good way to profit from the interest rates differentials between currencies.

While the basic concept might seem simple at first glance, achieving consistent profitability requires a nuanced understanding of global economics, risk management, setting good strategy constrains and thorough testing.