Combining AI and Python for Better Stock Trading

This article explores the use of reinforcement learning with Python to create a trading bot to make informed stock trading decisions.

EODHD APIs
7 min readAug 27, 2024

While we delve deeper into the trading landscape, one principle remains undeniable: experience is the greatest teacher. This truth applies not only to humans but also to machines, where algorithms learn and evolve from experience. Enter reinforcement learning — an approach where algorithms adapt and improve with each interaction.

The concept of building a trading bot has long intrigued both researchers and enthusiasts. There are various ways to train models to make effective decisions within the ever-changing world of real-time market dynamics. Trusting an algorithm to trade on your behalf is a significant choice that requires extensive research and a rich source of data. This is where EODHD APIs comes into play, offering a comprehensive real-time data set, perfect for powering reinforcement learning applications.

In this article, we’ll embark on the journey of creating a trading bot powered by machine learning. Together, we will explore how reinforcement learning principles can be used to develop a smart trading assistant that evolves over time.

Importing the Required Libraries

Before we get started on our journey, we need to gather the essential tools. The following packages serve as the foundation for our project, each contributing its own unique functionality:

eodhd:
This is the official Python library from EODHD, designed to provide seamless access to EODHD’s APIs, making financial data retrieval simple and efficient.

TensorFlow:
A versatile machine learning library for building and training neural networks. It is ideal for deep learning tasks and can also be applied to natural language processing and computer vision.

Stable Baselines3:
A Python library offering solid implementations of reinforcement learning algorithms. A2C, one of its algorithms, is frequently used in handling sequential decision-making problems.

Gym and Gymnasium:
OpenAI Gym is a toolkit for developing and testing reinforcement learning algorithms. It provides a broad range of environments, making it a popular choice for RL projects.

Gym Anytrading:
An extension of OpenAI Gym specifically designed for financial trading environments, allowing you to test algorithms within the framework of algorithmic trading.

Processing Libraries (NumPy, Pandas, Matplotlib):
NumPy offers efficient numerical computations with multi-dimensional array support, Pandas simplifies data manipulation, and Matplotlib is a robust library for creating various visualizations.

import gymnasium as gym
import gym_anytrading

# Stable baselines - rl stuff
from stable_baselines3.common.vec_env import DummyVecEnv
from stable_baselines3 import A2C

# Processing libraries
import numpy as np

import pandas as pd
from matplotlib import pyplot as plt

from eodhd import APIClient

Activating the API Key

To use the EODHD package’s functionalities, activating your API key is necessary. If you haven’t obtained an API key yet, you can register on the EODHD website. Once registered, navigate to the Dashboard, where your secret API key will be displayed. Keep this key private.

# API KEY ACTIVATION

api_key = '<YOUR API KEY>'
client = APIClient(api_key)

This code is straightforward: in the first line, the API key is stored in the variable api_key, and the second line utilizes the APIClient class to activate the API and save the response in the client variable.

Remember to replace <YOUR API KEY> with your actual API key. Additionally, for improved security, you can opt to store the API key using environment variables or other secure methods.

Extracting Historical Data

Before we jump into the extraction process, it’s helpful to understand what historical or end-of-day (EOD) data entails. This type of data captures price movements and volume over a specific period, allowing for the identification of patterns, trends, and overall market behavior. Leveraging historical data is vital for traders looking to analyze market activity and refine their strategies. With the eodhd package, extracting Tesla’s historical data is simple. Here’s how you can do it:

# EXTRACTING HISTORICAL DATA

df = client.get_historical_data('TSLA', 'd', "2018-11-26","2023-11-24")
df = df[['open','high','low','close','volume']]
df.columns = ['Open','High','Low','Close','Volume']
df.tail()

In this code, we are utilizing the get_historical_data function from the eodhd package. It takes three parameters:

  1. The stock’s symbol (in this case, 'TSLA' for Tesla).
  2. The interval ('d' for daily data).
  3. The start and end dates for the data range (from "2018-11-26" to "2023-11-24").

After the data is fetched, some basic data cleaning is applied to rename and format the columns. The resulting dataframe shows Tesla’s historical open, high, low, close prices, and trading volume. Here’s a snapshot of the formatted dataset:

Utilizing the Trading Gym

In this step, we will set up and explore the trading environment using AnyTrading, a toolkit built on top of OpenAI’s gym framework tailored specifically for financial market simulations.

env = gym.make('stocks-v0', df=df, frame_bound=(5, len(df)-1), window_size=5)

This command creates the default trading environment using the Tesla dataset (df) we previously extracted. The frame_bound defines the range of data used for the simulation, and the window_size sets the number of data points to consider in each step.

You can easily modify parameters like the dataset, frame_bound, or window_size to fit your specific strategy and preferences.

Once the environment is set, we can reset it and render the current state visually:

state = env.reset()
env.render()

This code resets the environment and visually renders the trading scenario. The AnyTrading toolkit allows you to experiment with different market conditions and strategies in a simulated environment, offering valuable insights for algorithmic trading.

The output provides a visual representation of how the environment interprets and processes the dataset.

Training and Predicting the Model

At this stage, the environment previously set up will be used to train the model, which can later be applied in real-world trading scenarios.

state = env.reset()
while True:
action = env.action_space.sample()
observation, reward, terminated, truncated, info = env.step(action)
done = terminated or truncated

# env.render()
if done:
print("info:", info)
break

plt.cla()
env.unwrapped.render_all()
plt.show()

This process entails categorizing observations, rewards, termination or truncation statuses, and other relevant data points, and then using them to train the model accordingly.

During each iteration, the model makes random trading decisions within the environment, gathering feedback in the form of observations and rewards, as well as the state of the environment. The loop continues until either the trading episode is terminated or truncated.

A visual representation of the trading scenario can be generated optionally to observe the actions in real-time. At the conclusion of each episode, the relevant information is printed to allow for further evaluation. The code also renders a clear visualization of the trading environment, which provides a deeper understanding of how the model evolves and performs during training.

In this section, both short and long positions are represented by red and green colors, respectively. You’ll notice that the environment always starts at position 1.

env_maker = lambda: gym.make('stocks-v0', df=df, frame_bound=(5,100), window_size=5)
env = DummyVecEnv([env_maker])

This code sets up a stock trading environment using OpenAI Gym. The env_maker function generates an instance of the ‘stocks-v0’ environment, customized with a DataFrame (df) containing the market data, along with specific frame boundaries and window size. By utilizing the DummyVecEnv class, a vectorized version of the environment is created and assigned to env, preparing it for reinforcement learning model training.

model = A2C('MlpPolicy', env, verbose=1)
model.learn(total_timesteps=1000000)

In this snippet, an A2C (Advantage Actor-Critic) model is implemented with the MlpPolicy in the configured stock trading environment. The model undergoes a learning process for one million time steps, leveraging the learn method to refine its predictions.

After training, a new stock trading environment is created, using an updated time frame. The trained model is used in a loop to make predictions and execute trades, continuing until the trading episode concludes. The system then outputs the results of the trading session.

Lastly, the code generates and displays a plot that visualizes the entire trading environment for further analysis:

env = gym.make('stocks-v0', df=df, frame_bound=(10,1100), window_size=5)
obs = env.reset()
obs = obs[0]
while True:
obs = obs[np.newaxis, ...]
action, _states = model.predict(obs)
observation, reward, terminated, truncated, info = env.step(action)
if done:
print("info", info)
break

plt.figure(figsize=(15,6))
plt.cla()
env.render_all()
plt.show()

This code provides a full representation of the stock trading session, using the trained model to make decisions in a real-time environment and offering visual insights into the process.

The resulting graph displays the predicted outcomes over the selected time frame and can be directly compared with the initial graph from the start of this exploration. It highlights the model’s decision-making process, showcasing how the market dynamics unfolded during that period based on the model’s learning and predictions.

Conclusion

The idea of delegating decision-making to an entity based on learned experience and accumulated knowledge is both fascinating and powerful. The use of AI, particularly reinforcement learning, in the financial domain holds vast potential and is still largely unexplored. As technology and data availability grow, there are boundless opportunities for this field to evolve and become even more impactful, reshaping the landscape of stock trading.

The original article was published in the EODHD Academy by Nikhil Adithyan.

Please note that this article is for informational purposes only and should not be taken as financial advice. We do not bear responsibility for any trading decisions made based on the content of this article. Readers are advised to conduct their own research or consult with a qualified financial professional before making any investment decisions.

For those eager to delve deeper into such insightful articles and broaden their understanding of different strategies in financial markets, we invite you to follow our account and subscribe for email notifications.

Stay tuned for more valuable articles that aim to enhance your data science skills and market analysis capabilities.

--

--

EODHD APIs

eodhd.com — stock market fundamental and historical prices API for stocks, ETFs, mutual funds and bonds all over the world.