BackCandlestick Python EURUSD

Backtest Like a Pro with a Forex API

06 December 2024


The financial markets are fast-paced, making them instrumental in accessing reliable data for building and testing trading strategies. Seamlessly integrating high-quality data into backtesting frameworks is invaluable for traders and analysts. TraderMade APIs provide traders and analysts with this capability by delivering accurate, granular, and comprehensive market data.

This article uses TraderMade's Time Series API to access historical data, implement a simple moving average (SMA) crossover strategy, and backtest its performance.

What is an SMA Crossover Strategy?

A moving average crossover strategy is a basic yet powerful technical analysis method. It involves tracking two SMAs:

1) A short-term SMA, which reacts more quickly to price changes.

2) A long-term SMA smoothens out short-term fluctuations.

When the short-term SMA crosses above the long-term SMA, it generates a buy signal, indicating upward momentum. Conversely, when the short-term SMA crosses below the long-term SMA, it generates a sell signal, suggesting downward momentum.

Data Collection

Start by installing TraderMade's SDK as follows:

!pip install tradermade

We use the installed SDK to fetch hourly time series forex data. The following Python code illustrates how to fetch currency pair EUR/USD data.

import tradermade as tm

import pandas as pd

def fetch_forex_data(api_key, currency, start_date, end_date,    interval="hourly", fields=["open", "high", "low", "close"]):


   # Set API key
   tm.set_rest_api_key(api_key)

   # Fetch the data
   data = tm.timeseries(currency=currency, start=start_date, end=end_date, interval=interval, fields=fields)


   # Convert data directly to DataFrame
   df = pd.DataFrame(data)

   # Convert 'date' column to datetime
   df["date"] = pd.to_datetime(df["date"])

   # Set 'date' as the index
   df.set_index("date", inplace=True)

   return df

# Adjust as needed
api_key = "YOUR TRADERMADE API KEY"
currency = "EURUSD"
start_date = "2024-11-01-00:00"
end_date = "2024-11-27-05:12"

# Fetch the data and display the first few rows
forex_data = fetch_forex_data(api_key, currency, start_date, end_date)
forex_data.head()

ohlc-data-backtesting

The data has been successfully fetched and preprocessed for Backtesting.

Implementing a Simple SMA Crossover strategy and Backtesting

This section uses the backtesting Python library to define and test our SMA crossover strategy. Here's a little background about the backtesting library for those who haven't heard about it. It's one of the most powerful and reliable Python frameworks for backtesting technical strategies such as SMA crossover, RSI crossover, Mean-reversal strategies, Momentum strategies, and more.

import numpy as np
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from backtesting.test import SMA

# Define the SMA crossover trading strategy
class SMACrossoverStrategy(Strategy):

       def init(self):
           # Calculate shorter-period SMAs for limited data
           price = self.data.Close
           self.short_sma = self.I(SMA, price, 20)  # Short window
           self.long_sma = self.I(SMA, price, 60)  # Long window

       def next(self):
           # Check for crossover signals
           if crossover(self.short_sma, self.long_sma):
               self.buy()
           elif crossover(self.long_sma, self.short_sma):
               self.sell()

   # Initialize and run the backtest
df = forex_data
df.rename(columns={"open": "Open", "high": "High", "low": "Low", "close": "Close"}, inplace=True)
bt = Backtest(df, SMACrossoverStrategy, cash=10000, commission=.002)
result = bt.run()

   # Display the backtest results
print("Backtest Results:")
print(result)

backtest-results

The strategy involves tracking two moving averages: a 20-period and a 60-period SMA. When the short SMA crosses the long SMA, it triggers a buy order. Conversely, when it crosses below, it triggers a sell order. Within 25 days, the simple strategy made a profit of $243 from 6 trades.

Equity and SMAs Curve

The Python code below evaluates the performance of the SMA crossover strategy. SMAs help visualize the price trends and the points of crossover that generate buy/sell signals. The equity curve helps evaluate the strategy's performance, showing how these signals affect portfolio growth.

Combining the two curves helps to easily observe how the crossover events correlate with the changes in portfolio value, providing critical insights into the efficacy of the SMA crossover strategy.

Plotly visualizes the equity and SMAs curves helping traders assess their strategy's profitability.

import plotly.graph_objects as go

# Plot equity curve and SMAs using Plotly

import plotly.graph_objects as go

fig = go.Figure()

# Add equity curve
equity_curve = result['_equity_curve']
fig.add_trace(go.Scatter(
   x=equity_curve.index,
   y=equity_curve['Equity'],
   mode='lines',
   name='Equity Curve',
   yaxis='y1'  # Link to first y-axis
))

# Add price with SMAs on a secondary y-axis
fig.add_trace(go.Scatter(
   x=forex_data.index,
   y=forex_data['Close'],
   mode='lines',
   name='Close Price',
   yaxis='y2',  # Link to second y-axis
   line=dict(color='blue')
))
fig.add_trace(go.Scatter(
   x=forex_data.index,
   y=forex_data['Close'].rolling(window=20).mean(),
   mode='lines',
   name='Short SMA (20)',
   yaxis='y2',  # Link to second y-axis
   line=dict(color='orange', dash='dash')
))
fig.add_trace(go.Scatter(
   x=forex_data.index,
   y=forex_data['Close'].rolling(window=60).mean(),
   mode='lines',
   name='Long SMA (60)',
   yaxis='y2',  # Link to second y-axis
   line=dict(color='green', dash='dash')
))

# Customize layout with two y-axes
fig.update_layout(
   title="Equity Curve and SMAs (SMA Crossover Strategy)",
   xaxis_title="Date",
   yaxis_title="Portfolio Value ($)",  # For equity curve
   yaxis=dict(title="Equity ($)", side="left"),
   yaxis2=dict(title="Price and SMAs", overlaying="y", side="right"),  # For price and SMAs
   template="plotly_dark",
   showlegend=True
)

# Show the plot
fig.show()

sma-chart-backtesting

Final Thoughts

In conclusion, Backtesting requires accurate, high-frequency data, and TraderMade's APIs make this seamless. Whether you are a beginner experimenting with various strategies or a seasoned analyst building complex models, the company's products empower you with the appropriate tools.

Are you ready to integrate TraderMade's APIs into your workflow? Get started today and bring your ideas to life!