Sitemap
Analytics Vidhya

Analytics Vidhya is a community of Generative AI and Data Science professionals. We are building the next-gen data science ecosystem https://www.analyticsvidhya.com

Using Technical Indicators In Python

4 min readAug 15, 2020

--

Press enter or click to view image in full size

Introduction:

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.

Theory:

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.

Code Run-through:

Step 1| Dependencies:

import requests
import numpy as np
from matplotlib import pyplot as plt
import datetime
API_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:

def SMA(prices,value):
means = []
count = 0
while value+count <= len(prices):
pre_val = prices[count:value+count]
count +=1
means.append(np.mean(pre_val))
return means

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:

def intersection(lst_1,lst_2):
intersections = []
insights = []
if len(lst_1) > len(lst_2):
settle = len(lst_2)
else:
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):
insights.append('buy')
else:
insights.append('sell')
intersections.append(i)
return intersections,insights

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:

def trading_simulator(trade_time,trade_value,close_price,sma_one,sma_two):
sma_1 = SMA(close_price,sma_one)
sma_2 = SMA(close_price,sma_two)
intersections,insights = intersection(sma_1,sma_2)
profit = 0
logs = []
try:
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
logs.append(trade_value*0.8)
elif fx_data[index][-1] > fx_data[index+trade_time][-1]:
profit -= trade_value
logs.append(-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
logs.append(trade_value*0.8)
elif fx_data[index][-1] < fx_data[index+trade_time][-1]:
profit -= trade_value
logs.append(-trade_value)
profit = profit
except:
print(len(fx_data),index+trade_time)
return profit,logs

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.

The Experiment:

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):
print(sma1,sma2,minutes)
clear_output()
profit,logs = trading_simulator(minutes,10,close_price,sma1,sma2)
log_of_logs.append(logs)
profits.append(profit)

The independent variables were the two SMAs of a range from 1–100 and how long the trade was open for.

Results:

The results to the experiment was very interesting, here is a graph when plotting the profits:

y-axis is profits, x-axis is iterations

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.

Conclusions:

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.

--

--

Analytics Vidhya
Analytics Vidhya

Published in Analytics Vidhya

Analytics Vidhya is a community of Generative AI and Data Science professionals. We are building the next-gen data science ecosystem https://www.analyticsvidhya.com

Victor Sim
Victor Sim

Written by Victor Sim

Interested in Machine Learning. Open to internships and opportunities. Connect at https://linktr.ee/victorsi.