{"id":2529,"date":"2023-10-04T10:43:08","date_gmt":"2023-10-04T10:43:08","guid":{"rendered":"https:\/\/eodhd.com\/financial-academy\/?p=2529"},"modified":"2025-02-05T12:16:51","modified_gmt":"2025-02-05T12:16:51","slug":"trading-predictions-using-ai-and-python","status":"publish","type":"post","link":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python","title":{"rendered":"Trading predictions using AI and Python"},"content":{"rendered":"\n<p>I&#8217;ve tried a number of techniques for predicting stock prices including forecasting tools like <a href=\"https:\/\/facebook.github.io\/prophet\/\" target=\"_blank\" rel=\"noreferrer noopener\">Facebook Prophet<\/a>, statistical approaches like the Seasonal Autoregressive Integrated Moving Average (SARIMA) model, machine learning techniques like Polynomial Regression, and finally an AI recurrent neural network (RNN).<\/p>\n\n\n\n<p>There are a number of AI models and techniques but I&#8217;ve found an Long Short-Term Memory (LSTM) model gets the best results. An LSTM model is a type of recurrent neural network (RNN) architecture designed to effectively handle sequence prediction problems. Unlike traditional feedforward neural networks, LSTM has a memory-like architecture that allows it to maintain contextual information over long sequences, making it ideal for time-series prediction, natural language processing, and other sequence-dependent tasks. It overcomes the limitations of basic RNNs by addressing issues like vanishing and exploding gradients, thereby enabling the model to capture long-term dependencies in the data. This makes LSTMs a popular choice for complex tasks that require the understanding of data over extended time periods.<\/p>\n\n\n\n<p>I&#8217;ve created a proof of concept to show you how it works.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><a class=\"maxbutton-1 maxbutton maxbutton-subscribe-to-api external-css btn\" href=\"https:\/\/eodhd.com\/register\"><span class='mb-text'>Register &amp; Get Data<\/span><\/a><\/p>\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-preparation\">Preparation<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Install Python and PIP, ideally the latest.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create yourself a Python project with a file called &#8220;<strong>main.py<\/strong>&#8220;.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create a directory within your project called &#8220;<strong>data<\/strong>&#8220;.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create yourself a virtual environment within your project and load it.<\/li>\n<\/ul>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">trading-ai-lstm $ python3 -m venv venv\ntrading-ai-lstm $ source venv\/.bin\/activate\n(venv) trading-ai-lstm $\n<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<ul class=\"wp-block-list\">\n<li>Create yourself a, &#8220;<strong>requirements.txt<\/strong>&#8221; file that looks like this.<\/li>\n<\/ul>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">pandas\nnumpy\nscikit-learn\nscipy\nmatplotlib\ntensorflow\neodhd\npython-dotenv\n<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<ul class=\"wp-block-list\">\n<li>Make sure you have upgraded PIP within your virtual environment and install the dependencies.<\/li>\n<\/ul>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">(venv) trading-ai-lstm $ pip install --upgrade pip\n\n(venv) trading-ai-lstm $ python3 -m pip install -r requirements.txt\n<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>I have added my<a href=\"https:\/\/eodhd.com\/\" target=\"_blank\" rel=\"noreferrer noopener\"> EODHD API&#8217;s<\/a> API key into a .env file that looks like this.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">API_TOKEN=<strong>&lt;YOUR_API_KEY_GOES_HERE&gt;<\/strong><\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p class=\"has-text-align-center\"><a class=\"maxbutton-1 maxbutton maxbutton-subscribe-to-api external-css btn\" href=\"https:\/\/eodhd.com\/register\"><span class='mb-text'>Register &amp; Get Data<\/span><\/a><\/p>\n\n\n\n<p>That should be ready now. If you are using <a href=\"https:\/\/code.visualstudio.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">VSCode<\/a> and would like to use the same, &#8220;<strong>.vscode\/settings.json<\/strong>&#8221; file as me, here it is.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">{\n  \"python.formatting.provider\": \"none\",\n  \"python.formatting.blackArgs\": [\"--line-length\", \"160\"],\n  \"python.linting.flake8Args\": [\n    \"--max-line-length=160\",\n    \"--ignore=E203,E266,E501,W503,F403,F401,C901\"\n  ],\n  \"python.analysis.diagnosticSeverityOverrides\": {\n    \"reportUnusedImport\": \"information\",\n    \"reportMissingImports\": \"none\"\n  },\n  \"[python]\": {\n    \"editor.defaultFormatter\": \"ms-python.black-formatter\"\n  }\n}<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>I&#8217;ve create a <a href=\"https:\/\/github.com\/whittlem\/trading-ai-lstm\" target=\"_blank\" rel=\"noreferrer noopener\">Github repo<\/a> for this in case you get stuck.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-building-up-the-code\">Building up the code<\/h2>\n\n\n\n<p>The first step is you will want to import the necessary libraries.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">import os\nos.environ[\"TF_CPP_MIN_LOG_LEVEL\"] = \"1\"\n\nimport pickle\nimport pandas as pd\nimport numpy as np\nfrom dotenv import load_dotenv\nfrom sklearn.metrics import mean_squared_error, mean_absolute_error\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import LSTM, Dense, Dropout\nfrom tensorflow.keras.models import load_model\nfrom sklearn.preprocessing import MinMaxScaler\nimport matplotlib.pyplot as plt\nfrom eodhd import APIClient<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>TensorFlow produces a lot of warnings and debug information by default. I prefer the output to look nice and tidy so I hide them. That&#8217;s what that os.environ line is doing after the &#8220;os&#8221; import. <\/p>\n\n\n\n<p>When training Machine Learning and AI models, it requires a lot of fine tuning. This is done with something called hyperparameters. This is a really complicated topic and an art on it&#8217;s own. The optimal hyperparameters will depend on a number of factors. Based on the daily S&amp;P 500 data I retrieve from <a href=\"https:\/\/eodhd.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">EODHD API&#8217;s<\/a>, I&#8217;ve started with some fairly common options. Feel free to adjust them to find improve the results. I would leave the sequence length at 20 for now.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\"># Configurable hyperparameters\nseq_length = 20\nbatch_size = 64\nlstm_units = 50\nepochs = 100<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>The next step is I want to retrieve my <a href=\"https:\/\/eodhd.com\/\">EODHD API&#8217;s<\/a> API_TOKEN from my .env file.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><a class=\"maxbutton-1 maxbutton maxbutton-subscribe-to-api external-css btn\" href=\"https:\/\/eodhd.com\/register\"><span class='mb-text'>Register &amp; Get Data<\/span><\/a><\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\"># Load environment variables from the .env file\nload_dotenv()\n\n# Retrieve the API key\nAPI_TOKEN = os.getenv(\"API_TOKEN\")\n\nif API_TOKEN is not None:\n    print(f\"API key loaded: {API_TOKEN[:4]}********\")\nelse:\n    raise LookupError(\"Failed to load API key.\")<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>Nothing too complicated here, just make sure you have a valid <a href=\"https:\/\/eodhd.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">EODHD API&#8217;s<\/a> API_TOKEN to be able to retrieve the data.<\/p>\n\n\n\n<p>I&#8217;ve created a number of repeatable functions. I&#8217;ll explain what they do when we actually use them below. I&#8217;ve included comments to explain what is happening within the functions.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">def get_ohlc_data(use_cache: bool = False) -&gt; pd.DataFrame:\n    ohlcv_file = \"data\/ohlcv.csv\"\n\n    if use_cache:\n        if os.path.exists(ohlcv_file):\n            return pd.read_csv(ohlcv_file, index_col=None)\n        else:\n            api = APIClient(API_TOKEN)\n            df = api.get_historical_data(\n                symbol=\"HSPX.LSE\",\n                interval=\"d\",\n                iso8601_start=\"2010-05-17\",\n                iso8601_end=\"2023-10-04\",\n            )\n            df.to_csv(ohlcv_file, index=False)\n            return df\n    else:\n        api = APIClient(API_TOKEN)\n        return api.get_historical_data(\n            symbol=\"HSPX.LSE\",\n            interval=\"d\",\n            iso8601_start=\"2010-05-17\",\n            iso8601_end=\"2023-10-04\",\n        )\n\ndef create_sequences(data, seq_length):\n    x, y = [], []\n    for i in range(len(data) - seq_length):\n        x.append(data[i : i + seq_length])\n        y.append(data[i + seq_length, 3])  # The prediction target \"close\" is the 4th column (index 3)\n    return np.array(x), np.array(y)\n\ndef get_features(df: pd.DataFrame = None, feature_columns: list = [\"open\", \"high\", \"low\", \"close\", \"volume\"]) -&gt; list:\n    return df[feature_columns].values\n\ndef get_target(df: pd.DataFrame = None, target_column: str = \"close\") -&gt; list:\n    return df[target_column].values\n\ndef get_scaler(use_cache: bool = True) -&gt; MinMaxScaler:\n    scaler_file = \"data\/scaler.pkl\"\n\n    if use_cache:\n        if os.path.exists(scaler_file):\n            # Load the scaler\n            with open(scaler_file, \"rb\") as f:\n                return pickle.load(f)\n        else:\n            scaler = MinMaxScaler(feature_range=(0, 1))\n            with open(scaler_file, \"wb\") as f:\n                pickle.dump(scaler, f)\n            return scaler\n    else:\n        return MinMaxScaler(feature_range=(0, 1))\n\ndef scale_features(scaler: MinMaxScaler = None, features: list = []):\n    return scaler.fit_transform(features)\n\ndef get_lstm_model(use_cache: bool = False) -&gt; Sequential:\n    model_file = \"data\/lstm_model.h5\"\n\n    if use_cache:\n        if os.path.exists(model_file):\n            # Load the model\n            return load_model(model_file)\n        else:\n            # Train the LSTM model and save it\n            model = Sequential()\n            model.add(LSTM(units=lstm_units, activation='tanh', input_shape=(seq_length, 5)))\n            model.add(Dropout(0.2))\n            model.add(Dense(units=1))\n\n            model.compile(optimizer=\"adam\", loss=\"mean_squared_error\")\n            model.fit(x_train, y_train, epochs=epochs, batch_size=batch_size, validation_data=(x_test, y_test))\n\n            # Save the entire model to a HDF5 file\n            model.save(model_file)\n\n            return model\n\n    else:\n        # Train the LSTM model\n        model = Sequential()\n        model.add(LSTM(units=lstm_units, activation='tanh', input_shape=(seq_length, 5)))\n        model.add(Dropout(0.2))\n        model.add(Dense(units=1))\n\n        model.compile(optimizer=\"adam\", loss=\"mean_squared_error\")\n        model.fit(x_train, y_train, epochs=epochs, batch_size=batch_size, validation_data=(x_test, y_test))\n\n        return model\n\ndef get_predicted_x_test_prices(x_test: np.ndarray = None):\n    predicted = model.predict(x_test)\n\n    # Create a zero-filled matrix to aid in inverse transformation\n    zero_filled_matrix = np.zeros((predicted.shape[0], 5))\n\n    # Replace the 'close' column of zero_filled_matrix with the predicted values\n    zero_filled_matrix[:, 3] = np.squeeze(predicted)\n\n    # Perform inverse transformation\n    return scaler.inverse_transform(zero_filled_matrix)[:, 3]\n\ndef plot_x_test_actual_vs_predicted(actual_close_prices: list = [], predicted_x_test_close_prices = []) -&gt; None:\n    # Plotting the actual and predicted close prices\n    plt.figure(figsize=(14, 7))\n    plt.plot(actual_close_prices, label=\"Actual Close Prices\", color=\"blue\")\n    plt.plot(predicted_x_test_close_prices, label=\"Predicted Close Prices\", color=\"red\")\n    plt.title(\"Actual vs Predicted Close Prices\")\n    plt.xlabel(\"Time\")\n    plt.ylabel(\"Price\")\n    plt.legend()\n    plt.show()\n\ndef predict_next_close(df: pd.DataFrame = None, scaler: MinMaxScaler = None) -&gt; float:\n    # Take the last X days of data and scale it\n    last_x_days = df.iloc[-seq_length:][[\"open\", \"high\", \"low\", \"close\", \"volume\"]].values\n    last_x_days_scaled = scaler.transform(last_x_days)\n\n    # Reshape this data to be a single sequence and make the prediction\n    last_x_days_scaled = np.reshape(last_x_days_scaled, (1, seq_length, 5))\n\n    # Predict the future close price\n    future_close_price = model.predict(last_x_days_scaled)\n\n    # Create a zero-filled matrix for the inverse transformation\n    zero_filled_matrix = np.zeros((1, 5))\n\n    # Put the predicted value in the 'close' column (index 3)\n    zero_filled_matrix[0, 3] = np.squeeze(future_close_price)\n\n    # Perform the inverse transformation to get the future price on the original scale\n    return scaler.inverse_transform(zero_filled_matrix)[0, 3]\n\ndef evaluate_model(x_test: list = []) -&gt; None:\n    # Evaluate the model\n    y_pred = model.predict(x_test)\n    mse = mean_squared_error(y_test, y_pred)\n    mae = mean_absolute_error(y_test, y_pred)\n    rmse = np.sqrt(mse)\n\n    print(f\"Mean Squared Error: {mse}\")\n    print(f\"Mean Absolute Error: {mae}\")\n    print(f\"Root Mean Squared Error: {rmse}\")<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>There is one point I just want to highlight in the code above. I&#8217;ve included a &#8220;<strong>use_cache<\/strong>&#8221; variable in several of the functions. The intention of this is to avoid sending API calls to <a href=\"https:\/\/eodhd.com\/\">EODHD API&#8217;s<\/a> repeatedly for no reason, and to avoid re-training the model repeatedly using the same daily data for no reason. If you enable the &#8220;<strong>use_cache<\/strong>&#8221; variable it to save the data to files in the &#8220;<strong>data\/<\/strong>&#8221; directory. If the data doesn&#8217;t exist it will create it, and if it exists it will load it. If you are running the script repeatedly it&#8217;s much more efficient this way. If you would like to generate new data each time just disable the &#8220;<strong>use_cache<\/strong>&#8221; when the function runs or just clear the files in the &#8220;<strong>data\/<\/strong>&#8221; directory. It will have the same effect.<\/p>\n\n\n\n<p>Now we dive into the main code&#8230;<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">if __name__ == \"__main__\":\n    # Retrieve 3369 days of S&amp;P 500 data\n    df = get_ohlc_data(use_cache=True)\n    print(df)<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>We first retrieve our OHLCV data <a href=\"https:\/\/eodhd.com\/\">EODHD API&#8217;s<\/a> and store it in a Pandas Dataframe called &#8220;<strong>df<\/strong>&#8220;. OHLCV stands for Open, High, Low, Close, and Volume which are typical fields you would have for trading candle data. You also will notice I have enabled the caching as described above. I also optionally print the data on the screen.<\/p>\n\n\n\n<p class=\"has-text-align-center bordered_paragraph has-background\" style=\"background-color:#f1f6f9;font-size:16px;font-style:normal;font-weight:500\">While understanding the trading signals is crucial, the reliability of the data you use is equally important. Learn more:<br><a href=\"https:\/\/eodhd.com\/financial-academy\/fundamental-analysis-examples\/reliability-of-free-stock-data\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Free vs Paid Stock Data: Which One Can You Trust?<\/strong><\/a> <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\" id=\"Python_DataFrame_OHLV_PrintigResult_Screenshot\"><img loading=\"lazy\" decoding=\"async\" width=\"1458\" height=\"372\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-04-at-10.52.01.png\" alt=\"\" class=\"wp-image-2536\"\/><figcaption class=\"wp-element-caption\">Screenshot by Author<\/figcaption><\/figure>\n<\/div>\n\n\n<p>I&#8217;ll explain the next code block in one go&#8230;<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">    features = get_features(df)\n    target = get_target(df)\n\n    scaler = get_scaler(use_cache=True)\n    scaled_features = scale_features(scaler, features)\n\n    x, y = create_sequences(scaled_features, seq_length)\n\n    train_size = int(0.8 * len(x))  # Create a train\/test split of 80\/20%\n    x_train, x_test = x[:train_size], x[train_size:]\n    y_train, y_test = y[:train_size], y[train_size:]\n\n    # Re-shape input to fit lstm layer\n    x_train = np.reshape(x_train, (x_train.shape[0], seq_length, 5))  # 5 features\n    x_test = np.reshape(x_test, (x_test.shape[0], seq_length, 5))  # 5 features<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<ul class=\"wp-block-list\">\n<li>&#8220;<strong>features<\/strong>&#8221; contains a list of inputs we will use to predict our target I.e. &#8220;<strong>close<\/strong>&#8220;.<\/li>\n\n\n\n<li>&#8220;<strong>target<\/strong>&#8221; contains a list of the target values I.e. &#8220;<strong>close<\/strong>&#8220;.<\/li>\n\n\n\n<li>&#8220;<strong>scaler<\/strong>&#8221; is a technique used to normalise numbers to make them comparable. For example we have a close of 784 as our first row, and a close of 3538 on the last row. Just because the last row has a higher value doesn&#8217;t mean it&#8217;s necessarily more important in terms of a prediction. We want them to be comparable, and this is how it&#8217;s done.<\/li>\n\n\n\n<li>&#8220;<strong>scaled_features<\/strong>&#8221; is the result of the scaling and what we will use to train our AI model.<\/li>\n\n\n\n<li>&#8220;<strong>x_train<\/strong>&#8221; and &#8220;<strong>x_test<\/strong>&#8221; are our sets will use to train our AI model and then test it. I&#8217;ve used an 80\/20 split which is fairly common. 80% of our trading data will be used for training the AI model, and 20% of the data will be used to test the model. The &#8220;x&#8221; means it&#8217;s the features, the inputs.<\/li>\n\n\n\n<li>&#8220;<strong>y_train<\/strong>&#8221; and &#8220;<strong>y_test<\/strong>&#8221; is similar to above but it will just contain the target values I.e. &#8220;<strong>close<\/strong>&#8220;<\/li>\n\n\n\n<li>Finally, the data needs to be re-shaped to fit into an LSTM layer.<\/li>\n<\/ul>\n\n\n\n<p>I have created a function to either train the model or load a trained model.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">model = get_lstm_model(use_cache=True)<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1326\" height=\"624\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-04-at-11.04.21.png\" alt=\"\" class=\"wp-image-2537\"\/><figcaption class=\"wp-element-caption\">Screenshot by Author<\/figcaption><\/figure>\n<\/div>\n\n\n<p>The screenshot above shows a snippet of the training process. You will notice that as the training starts the &#8220;<strong>loss<\/strong>&#8221; and &#8220;<strong>val_loss<\/strong>&#8221; won&#8217;t be very close as as the training progresses you should the numbers getting closer together. <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>loss<\/code>: This is the mean squared error (MSE) computed on the training dataset. It reflects the &#8220;<strong>cost<\/strong>&#8221; or &#8220;<strong>error<\/strong>&#8221; between predicted and true labels for each training epoch. The aim is to minimize this value over epochs.<\/li>\n\n\n\n<li><code>val_loss<\/code>: This is the mean squared error computed on the validation dataset. The validation dataset is a subset of the data that the model has never seen during training. It&#8217;s an indicator of how well the model generalises to unseen data.<\/li>\n<\/ul>\n\n\n\n<p>If you want to see a list of the predicted close prices on the test set, you can use this code.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">    predicted_x_test_close_prices = get_predicted_x_test_prices(x_test)\n    print(\"Predicted close prices:\", predicted_x_test_close_prices)<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>It&#8217;s not all that helpful or easy to visualise on it&#8217;s own. If we plot the actual closing prices against the predicted closing prices (remember 20% of the full dataset), it looks like this.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">    # Plot the actual and predicted close prices for the test data\n    plot_x_test_actual_vs_predicted(df[\"close\"].tail(len(predicted_x_test_close_prices)).values, predicted_x_test_close_prices)\n\n<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2344\" height=\"1194\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-04-at-11.11.38.png\" alt=\"\" class=\"wp-image-2539\"\/><figcaption class=\"wp-element-caption\">Screenshot by Author<\/figcaption><\/figure>\n<\/div>\n\n\n<p>You can see it&#8217;s done a pretty good job a predicting the closing price using the testing phase.<\/p>\n\n\n\n<p>Now the part you are probably waiting for. Can we find out what the predicted closing price is tomorrow?<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">   # Predict the next close price\n    predicted_next_close =  predict_next_close(df, scaler)\n    print(\"Predicted next close price:\", predicted_next_close)\n\n<strong>Predicted next close price: 3536.906685638428<\/strong><\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>This is just a basic example for academic purposes, and just the start. Following on from this you can look at adding more training data, experimenting with the hyperparameters, or training models on different markets and intervals.<\/p>\n\n\n\n<p>If you want to evaluate the model you can include this.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">    # Evaluate the model\n    evaluate_model(x_test)<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>Which in my case is&#8230;<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code lang=\"python\" class=\"language-python\">Mean Squared Error: 0.00021641664334765608\nMean Absolute Error: 0.01157513692221611\nRoot Mean Squared Error: 0.014711106122506767\n<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>The <code>mean_squared_error<\/code> and <code>mean_absolute_error<\/code> functions from scikit-learn&#8217;s metrics module are used to calculate MSE and MAE, respectively. The Root Mean Squared Error (RMSE) is calculated as the square root of MSE.<\/p>\n\n\n\n<p>These metrics provide a quantitative evaluation of the model&#8217;s performance, while the plot helps in visually assessing how closely the predicted values match with the actual values.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><a class=\"maxbutton-1 maxbutton maxbutton-subscribe-to-api external-css btn\" href=\"https:\/\/eodhd.com\/register\"><span class='mb-text'>Register &amp; Get Data<\/span><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve tried a number of techniques for predicting stock prices including forecasting tools like Facebook Prophet, statistical approaches like the Seasonal Autoregressive Integrated Moving Average (SARIMA) model, machine learning techniques like Polynomial Regression, and finally an AI recurrent neural network (RNN). There are a number of AI models and techniques but I&#8217;ve found an Long [&hellip;]<\/p>\n","protected":false},"author":8,"featured_media":2530,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[65,42],"tags":[],"coding-language":[30],"ready-to-go-solution":[56],"qualification":[31,32],"financial-apis-category":[34,36],"financial-apis-manuals":[39],"class_list":["post-2529","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-backtesting-strategies-examples","category-stocks-data-analysis-examples","coding-language-python","ready-to-go-solution-eodhd-python-financial-library","qualification-experienced","qualification-guru","financial-apis-category-crypto-market-prices","financial-apis-category-stock-market-prices","financial-apis-manuals-end-of-day","has_thumb"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.9 (Yoast SEO v26.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Trading predictions using AI and Python | EODHD APIs Academy<\/title>\n<meta name=\"description\" content=\"Explore an Long Short-Term Memory (LSTM) model which gets the best results in trading predictions using AI and Python.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Trading predictions using AI and Python\" \/>\n<meta property=\"og:description\" content=\"Explore an Long Short-Term Memory (LSTM) model which gets the best results in trading predictions using AI and Python.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python\" \/>\n<meta property=\"og:site_name\" content=\"Financial Academy\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/eodhistoricaldata\" \/>\n<meta property=\"article:published_time\" content=\"2023-10-04T10:43:08+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-05T12:16:51+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/AdobeStock_254411885.jpeg\" \/>\n\t<meta property=\"og:image:width\" content=\"980\" \/>\n\t<meta property=\"og:image:height\" content=\"461\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Michael Whittle\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@EOD_data\" \/>\n<meta name=\"twitter:site\" content=\"@EOD_data\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Michael Whittle\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#article\",\"isPartOf\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python\"},\"author\":{\"name\":\"Michael Whittle\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/50784c270b6267df5969514d80d510ad\"},\"headline\":\"Trading predictions using AI and Python\",\"datePublished\":\"2023-10-04T10:43:08+00:00\",\"dateModified\":\"2025-02-05T12:16:51+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python\"},\"wordCount\":1328,\"publisher\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#organization\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#primaryimage\"},\"thumbnailUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/AdobeStock_254411885.jpeg\",\"articleSection\":[\"Backtesting Strategies Examples\",\"Stocks Data Analysis Examples\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python\",\"name\":\"Trading predictions using AI and Python | EODHD APIs Academy\",\"isPartOf\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#primaryimage\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#primaryimage\"},\"thumbnailUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/AdobeStock_254411885.jpeg\",\"datePublished\":\"2023-10-04T10:43:08+00:00\",\"dateModified\":\"2025-02-05T12:16:51+00:00\",\"description\":\"Explore an Long Short-Term Memory (LSTM) model which gets the best results in trading predictions using AI and Python.\",\"breadcrumb\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#primaryimage\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/AdobeStock_254411885.jpeg\",\"contentUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/AdobeStock_254411885.jpeg\",\"width\":8500,\"height\":4000,\"caption\":\"Humanoid robot with a notebook and a growing candle stick chart. 3d illustration.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/eodhd.com\/financial-academy\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Trading predictions using AI and Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#website\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/\",\"name\":\"Financial APIs Academy | EODHD\",\"description\":\"Financial Stock Market Academy\",\"publisher\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/eodhd.com\/financial-academy\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#organization\",\"name\":\"EODHD (EOD Historical Data)\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/12\/EODHD-Logo.png\",\"contentUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/12\/EODHD-Logo.png\",\"width\":159,\"height\":82,\"caption\":\"EODHD (EOD Historical Data)\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/eodhistoricaldata\",\"https:\/\/x.com\/EOD_data\",\"https:\/\/www.reddit.com\/r\/EODHistoricalData\/\",\"https:\/\/eod-historical-data.medium.com\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/50784c270b6267df5969514d80d510ad\",\"name\":\"Michael Whittle\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5076af85c7ee0445454257247cad4970ae8cf5d7d4940d2b32c521f51c0a0f5a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5076af85c7ee0445454257247cad4970ae8cf5d7d4940d2b32c521f51c0a0f5a?s=96&d=mm&r=g\",\"caption\":\"Michael Whittle\"},\"description\":\"Solution architect, developer, and analyst with over 20+ years experience (TOP author on Medium).\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/author\/michaelwhittle\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Trading predictions using AI and Python | EODHD APIs Academy","description":"Explore an Long Short-Term Memory (LSTM) model which gets the best results in trading predictions using AI and Python.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python","og_locale":"en_US","og_type":"article","og_title":"Trading predictions using AI and Python","og_description":"Explore an Long Short-Term Memory (LSTM) model which gets the best results in trading predictions using AI and Python.","og_url":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python","og_site_name":"Financial Academy","article_publisher":"https:\/\/www.facebook.com\/eodhistoricaldata","article_published_time":"2023-10-04T10:43:08+00:00","article_modified_time":"2025-02-05T12:16:51+00:00","og_image":[{"url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/AdobeStock_254411885.jpeg","width":980,"height":461,"type":"image\/jpeg"}],"author":"Michael Whittle","twitter_card":"summary_large_image","twitter_creator":"@EOD_data","twitter_site":"@EOD_data","twitter_misc":{"Written by":"Michael Whittle","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#article","isPartOf":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python"},"author":{"name":"Michael Whittle","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/50784c270b6267df5969514d80d510ad"},"headline":"Trading predictions using AI and Python","datePublished":"2023-10-04T10:43:08+00:00","dateModified":"2025-02-05T12:16:51+00:00","mainEntityOfPage":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python"},"wordCount":1328,"publisher":{"@id":"https:\/\/eodhd.com\/financial-academy\/#organization"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#primaryimage"},"thumbnailUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/AdobeStock_254411885.jpeg","articleSection":["Backtesting Strategies Examples","Stocks Data Analysis Examples"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python","url":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python","name":"Trading predictions using AI and Python | EODHD APIs Academy","isPartOf":{"@id":"https:\/\/eodhd.com\/financial-academy\/#website"},"primaryImageOfPage":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#primaryimage"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#primaryimage"},"thumbnailUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/AdobeStock_254411885.jpeg","datePublished":"2023-10-04T10:43:08+00:00","dateModified":"2025-02-05T12:16:51+00:00","description":"Explore an Long Short-Term Memory (LSTM) model which gets the best results in trading predictions using AI and Python.","breadcrumb":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#primaryimage","url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/AdobeStock_254411885.jpeg","contentUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/AdobeStock_254411885.jpeg","width":8500,"height":4000,"caption":"Humanoid robot with a notebook and a growing candle stick chart. 3d illustration."},{"@type":"BreadcrumbList","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/trading-predictions-using-ai-and-python#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/eodhd.com\/financial-academy\/"},{"@type":"ListItem","position":2,"name":"Trading predictions using AI and Python"}]},{"@type":"WebSite","@id":"https:\/\/eodhd.com\/financial-academy\/#website","url":"https:\/\/eodhd.com\/financial-academy\/","name":"Financial APIs Academy | EODHD","description":"Financial Stock Market Academy","publisher":{"@id":"https:\/\/eodhd.com\/financial-academy\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/eodhd.com\/financial-academy\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/eodhd.com\/financial-academy\/#organization","name":"EODHD (EOD Historical Data)","url":"https:\/\/eodhd.com\/financial-academy\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/logo\/image\/","url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/12\/EODHD-Logo.png","contentUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/12\/EODHD-Logo.png","width":159,"height":82,"caption":"EODHD (EOD Historical Data)"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/eodhistoricaldata","https:\/\/x.com\/EOD_data","https:\/\/www.reddit.com\/r\/EODHistoricalData\/","https:\/\/eod-historical-data.medium.com\/"]},{"@type":"Person","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/50784c270b6267df5969514d80d510ad","name":"Michael Whittle","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5076af85c7ee0445454257247cad4970ae8cf5d7d4940d2b32c521f51c0a0f5a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5076af85c7ee0445454257247cad4970ae8cf5d7d4940d2b32c521f51c0a0f5a?s=96&d=mm&r=g","caption":"Michael Whittle"},"description":"Solution architect, developer, and analyst with over 20+ years experience (TOP author on Medium).","url":"https:\/\/eodhd.com\/financial-academy\/author\/michaelwhittle"}]}},"jetpack_featured_media_url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/10\/AdobeStock_254411885.jpeg","jetpack_shortlink":"https:\/\/wp.me\/pdOdVT-EN","jetpack_sharing_enabled":true,"acf":[],"_links":{"self":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/2529","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/comments?post=2529"}],"version-history":[{"count":10,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/2529\/revisions"}],"predecessor-version":[{"id":6251,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/2529\/revisions\/6251"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/media\/2530"}],"wp:attachment":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/media?parent=2529"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/categories?post=2529"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/tags?post=2529"},{"taxonomy":"coding-language","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/coding-language?post=2529"},{"taxonomy":"ready-to-go-solution","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/ready-to-go-solution?post=2529"},{"taxonomy":"qualification","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/qualification?post=2529"},{"taxonomy":"financial-apis-category","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/financial-apis-category?post=2529"},{"taxonomy":"financial-apis-manuals","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/financial-apis-manuals?post=2529"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}