After making a machine learning algorithm that attempts to predict the future price of forex securities, I thought about trying to automate trading, using theories that originate from technical analysis.
The main theory that I tried to recreate was the MA cross concept, basically gathering insights when two moving averages intersect. The two moving averages would be of various ranges. The strategy in question works because, it shows how the current trend is relative to past trends. If the current uptrend is higher than the long term average, it is likely that the price will tend to increase.
Step 1| Dependencies:
import numpy as np
from matplotlib import pyplot as plt
import datetimeAPI_KEY = 'XXXXX'
from_symbol = 'EUR'
to_symbol = 'USD'
These dependencies are necessary to make calculations and plot results. Fill in the API_KEY variable with your own api key from alpha vantage.
Step 2 | Creating the SMA:
means = 
count = 0
while value+count <= len(prices):
pre_val = prices[count:value+count]
The SMA function is in fact very simple, with just the closing price and the value of the SMA lines as parameters. It runs a loop through the prices, gets the current range and then finds the average. It returns a list of the averages which when plotted, is the SMA.
Step 3 | Calculating Intersections:
intersections = 
insights = 
if len(lst_1) > len(lst_2):
settle = len(lst_2)
settle = len(lst_1)
for i in range(settle-1):
if (lst_1[i+1] < lst_2[i+1]) != (lst_1[i] < lst_2[i]):
if ((lst_1[i+1] < lst_2[i+1]),(lst_1[i] < lst_2[i])) == (True,False):
The intersection takes in two simple moving averages as parameters. It took me a while to get the intersection to work as intended. Here is a list of things I tried:
- Find terms that appeared in both lists and then find their index
This approach didn’t work because the SMA plotted is a “connect-the-dots” line of the values calculated, and therefore the point of intersection may not be a datapoint in the list of SMA values.
- Use simultaneous equations to calculate values that satisfy the equation
This approach didn’t work because the SMA cannot be defined by simple functions. The more complex a function, the more variables are necessary to define it, making it ineffective to find intersections via simultaneous equations.
The approach that finally worked was if the order in which the SMA’s were stacked changed. If it did, it means that an intersection must have occurred before this change. This works well in may cases, but has a slight delay.
Step 4| Simulating Trades:
sma_1 = SMA(close_price,sma_one)
sma_2 = SMA(close_price,sma_two)
intersections,insights = intersection(sma_1,sma_2)
profit = 0
logs = 
for i in range(len(insights)):
index = intersections[i]
if insights[i] == buy:
if index+trade_time < len(fx_data):
if fx_data[index][-1] < fx_data[index+trade_time][-1]:
profit += trade_value * 0.8
elif fx_data[index][-1] > fx_data[index+trade_time][-1]:
profit -= trade_value
elif insights[i] == sell:
if index+trade_time <= len(fx_data):
if fx_data[index][-1] > fx_data[index+trade_time][-1]:
profit += trade_value * 0.8
elif fx_data[index][-1] < fx_data[index+trade_time][-1]:
profit -= trade_value
profit = profit
The trading simulator is very simple and is essentially accessing the data and comparing it to the insights the program makes. It returns a log of all transactions for troubleshooting and profit tracking, and a sum of the profits.
With so many parameters, I wanted to see how to optimize the parameters to get the most amount of profits. I brute forced this with this code:
profits = 
log_of_logs = 
for minutes in range(1,10):
for sma1 in range(1,100):
for sma2 in range(1,100):
profit,logs = trading_simulator(minutes,10,close_price,sma1,sma2)
The independent variables were the two SMAs of a range from 1–100 and how long the trade was open for.
The results to the experiment was very interesting, here is a graph when plotting the profits:
Can you reach any conclusions by looking at this graph?
Hint: By looking at the graph and the program, you can tell that each spike in the graph was the change in how long the trade was open for.
The data shows that no matter the SMA value, longer trade times tend to have more stable results. Additionally, the narrowing down between each spike shows that the higher the two SMA values, the more stable the values are right?
Wrong! In fact all the conclusions in the previous paragraph are all inaccurate. Let me prove this step by step: Firstly, the discrepancies for the trade times stem from the fact that within a given amount of time, more 1 minute trades can be made than 9 minute trades. Secondly, there are more intersections for smaller values as compared to larger values for SMAs because it is exceeded averages of a closer time period happen more often as compared to averages of a longer time period.
So are there any conclusions? Yes, but another measurement must be conceded to see past the fog that plague previous conclusions. This measurement is accuracy. Because accuracy is a percentage, no matter how many intersections and how man trades are made, one can effectively compare how suitable the parameters are, as compared to others.
Just one line of code is necessary:
accuracy = logs.count(trade_value*0.8)/len(logs)*100
The results were that for each set of SMA values there were many varying possibilities that gave 90%+ accuracies, for example, SMA values of 60 and 4, and a trade time of 3 minutes.
I hope you learnt something from my article. Thank you for reading this.