Backtesting an algorithmic trading strategy using Machine Learning and Sentiment Analysis.

Overview

Trading Tesla with Machine Learning and Sentiment Analysis

An interactive program to train a Random Forest Classifier to predict Tesla daily prices using technical indicators and sentiment scores of Twitter posts, backtesting the trading strategy and producing performance metrics.

The project leverages techniques, paradigms and data structures such as:

  • Functional and Object-Oriented Programming
  • Machine Learning
  • Sentiment Analysis
  • Concurrency and Parallel Processing
  • Direct Acyclic Graph (D.A.G.)
  • Data Pipeline
  • Idempotence

Scope

The intention behind this project was to implement the end-to-end workflow of the backtesting of an Algorithmic Trading strategy in a program with a sleek interface, and with a level of automation such that the user is able to tailor the details of the strategy and the output of the program by entering a minimal amount of data, partly even in an interactive way. This should make the program reusable, meaning that it's easy to carry out the backtesting of the trading strategy on a different asset. Furthermore, the modularity of the software design should facilitate changes to adapt the program to different requirements (i.e. different data or ML models).

Strategy Backtesting Results

The Random Forest classifier model was trained and optimised with the scikit-learn GridSearchCV module. After computing the trading signals predictions and backtesting the strategy, the following performances were recorded:

Performance Indicators Summary
Return Buy and Hold (%) 273.94
Return Buy and Hold Ann. (%) 91.5
Return Trading Strategy (%) 1555.54
Return Trading Strategy Ann. (%) 298.53
Sharpe Ratio 0.85
Hit Ratio (%) 93.0
Average Trades Profit (%) 3.99
Average Trades Loss (%) -1.15
Max Drawdown (%) -7.69
Days Max Drawdown Recovery 2

drawdown

returns

Running the Program

This is straightforward. There are very few variables and methods to initialise and call in order to run the whole program.

Let me illustrate it in the steps below:

  1. Provide the variables in download_params, a dictionary containing all the strategy and data downloading details.

    download_params = {'ticker' : 'TSLA',
                       'since' : '2010-06-29', 
                       'until' : '2021-06-02',
                       'twitter_scrape_by_account' : {'elonmusk': {'search_keyword' : '',
                                                                   'by_hashtag' : False},
                                                      'tesla': {'search_keyword' : '',
                                                                'by_hashtag' : False},
                                                      'WSJ' : {'search_keyword' : 'Tesla',
                                                               'by_hashtag' : False},
                                                      'Reuters' : {'search_keyword' : 'Tesla',
                                                                   'by_hashtag' : False},
                                                      'business': {'search_keyword' : 'Tesla',
                                                                   'by_hashtag' : False},
                                                      'CNBC': {'search_keyword' : 'Tesla',
                                                               'by_hashtag' : False},
                                                      'FinancialTimes' : {'search_keyword' : 'Tesla',
                                                                          'by_hashtag' : True}},
                       'twitter_scrape_by_most_popular' : {'all_twitter_1': {'search_keyword' : 'Tesla',
                                                                           'max_tweets_per_day' : 30,
                                                                           'by_hashtag' : True}},
                       'language' : 'en'                                      
                       }
  2. Initialise an instance of the Pipeline class:

    TSLA_data_pipeline = Pipeline()
  3. Call the run method on the Pipeline instance:

    TSLA_pipeline_outputs = TSLA_data_pipeline.run()

    This will return a dictionary with the Pipeline functions outputs, which in this example has been assigned to TSLA_pipeline_outputs. It will also print messages about the status and operations of the data downloading and manipulation process.

  4. Retrieve the path to the aggregated data to feed into the Backtest_Strategy class:

    data = glob.glob('data/prices_TI_sentiment_scores/*')[0]
  5. Initialise an instance of the Backtest_Strategy class with the data variable assigned in the previous step.

    TSLA_backtest_strategy = Backtest_Strategy(data)
  6. Call the preprocess_data method on the Backtest_Strategy instance:

    TSLA_backtest_strategy.preprocess_data()

    This method will show a summary of the data preprocessing results such as missing values, infinite values and features statistics.

From this point the program becomes interactive, and the user is able to input data, save and delete files related to the training and testing of the Random Forest model, and proceed to display the strategy backtesting summary and graphs.

  1. Call the train_model method on the Backtest_Strategy instance:

    TSLA_backtest_strategy.train_model()

    Here you will be able to train the model with the scikit-learn GridSearchCV, creating your own parameters grid, save and delete files containing the parameters grid and the best set of parameters found.

  2. Call the test_model method on the Backtest_Strategy instance:

    TSLA_backtest_strategy.test_model()

    This method will allow you to test the model by selecting one of the model's best parameters files saved during the training process (or the "default_best_param.json" file created by default by the program, if no other file was saved by the user).

    Once the process is complete, it will display the testing summary metrics and graphs.

    If you are satisfied with the testing results, from here you can display the backtesting summary, which equates to call the next and last method below. In this case, the program will also save a csv file with the data to compute the strategy performance metrics.

  3. Call the strategy_performance method on the Backtest_Strategy instance:

    TSLA_backtest_strategy.strategy_performance()

    This is the method to display the backtesting summary shown above in this document. Assuming a testing session has been completed and there is a csv file for computing the performance metrics, the program will display the backtesting results straight away using the existing csv file, which in turn is overwritten every time a testing process is completed. Otherwise, it will prompt you to run a training/testing session first.

Tips

If the required data (historical prices and Twitter posts) have been already downloaded, the only long execution time you may encounter is during the model training: the larger the parameters grid search, the longer the time. I recommend that you start getting confident with the program by using the data already provided within the repo (backtesting on Tesla stock).

This is because any downloading of new data on a significantly large period of time such to be reliable for the model training will likely require many hours, essentially due to the Twitter scraping process.

That said, please be also aware that as soon as you change the variables in the download_params dictionary and run the Pipeline instance, all the existing data files will be overwritten. This is because the program recognise on its own the relevant data that need to be downloaded according to the parameters passed into download_params, and this is a deliberate choice behind the program design.

That's all! Clone the repository and play with it. Any feedback welcome.

Disclaimer

Please be aware that the content and results of this project do not represent financial advice. You should conduct your own research before trading or investing in the markets. Your capital is at risk.

References

Owner
Renato Votto
Renato Votto
Customers Segmentation with RFM Scores and K-means

Customer Segmentation with RFM Scores and K-means RFM Segmentation table: K-Means Clustering: Business Problem Rule-based customer segmentation machin

5 Aug 10, 2022
Python package for machine learning for healthcare using a OMOP common data model

This library was developed in order to facilitate rapid prototyping in Python of predictive machine-learning models using longitudinal medical data from an OMOP CDM-standard database.

Sontag Lab 75 Jan 03, 2023
Kubeflow is a machine learning (ML) toolkit that is dedicated to making deployments of ML workflows on Kubernetes simple, portable, and scalable.

SDK: Overview of the Kubeflow pipelines service Kubeflow is a machine learning (ML) toolkit that is dedicated to making deployments of ML workflows on

Kubeflow 3.1k Jan 06, 2023
Microsoft 5.6k Jan 07, 2023
An easier way to build neural search on the cloud

Jina is geared towards building search systems for any kind of data, including text, images, audio, video and many more. With the modular design & multi-layer abstraction, you can leverage the effici

Jina AI 17k Jan 01, 2023
A library of extension and helper modules for Python's data analysis and machine learning libraries.

Mlxtend (machine learning extensions) is a Python library of useful tools for the day-to-day data science tasks. Sebastian Raschka 2014-2021 Links Doc

Sebastian Raschka 4.2k Dec 29, 2022
This handbook accompanies the course: Machine Learning with Hung-Yi Lee

This handbook accompanies the course: Machine Learning with Hung-Yi Lee

RenChu Wang 472 Dec 31, 2022
Basic Docker Compose for Machine Learning Purposes

Docker-compose for Machine Learning How to use: cd docker-ml-jupyterlab

Chris Chen 1 Oct 29, 2021
Simple and flexible ML workflow engine.

This is a simple and flexible ML workflow engine. It helps to orchestrate events across a set of microservices and create executable flow to handle requests. Engine is designed to be configurable wit

Katana ML 295 Jan 06, 2023
Exemplary lightweight and ready-to-deploy machine learning project

Exemplary lightweight and ready-to-deploy machine learning project

snapADDY GmbH 6 Dec 20, 2022
A Microsoft Azure Web App project named Covid 19 Predictor using Machine learning Model

A Microsoft Azure Web App project named Covid 19 Predictor using Machine learning Model (Random Forest Classifier Model ) that helps the user to identify whether someone is showing positive Covid sym

Priyansh Sharma 2 Oct 06, 2022
A simple python program which predicts the success of a movie based on it's type, actor, actress and director

Movie-Success-Prediction A simple python program which predicts the success of a movie based on it's type, actor, actress and director. The program us

Mahalinga Prasad R N 1 Dec 17, 2021
Predict profitability of trades based on indicator buy / sell signals

Predict profitability of trades based on indicator buy / sell signals Trade profitability analysis for trades based on various indicators signals: MAC

Tomasz Porzycki 1 Dec 15, 2021
Stacked Generalization (Ensemble Learning)

Stacking (stacked generalization) Overview ikki407/stacking - Simple and useful stacking library, written in Python. User can use models of scikit-lea

Ikki Tanaka 192 Dec 23, 2022
A chain of stores, 10 different stores and 50 different requests a 3-month demand forecast for its product.

Demand-Forecasting Business Problem A chain of stores, 10 different stores and 50 different requests a 3-month demand forecast for its product.

Ayşe Nur Türkaslan 3 Mar 06, 2022
Production Grade Machine Learning Service

This project is made to help you scale from a basic Machine Learning project for research purposes to a production grade Machine Learning web service

Abdullah Zaiter 10 Apr 04, 2022
Bayesian Modeling and Computation in Python

Bayesian Modeling and Computation in Python Open access and Code This repository contains the open access version of the text and the code examples in

Bayesian Modeling and Computation in Python 339 Jan 02, 2023
Kaggler is a Python package for lightweight online machine learning algorithms and utility functions for ETL and data analysis.

Kaggler is a Python package for lightweight online machine learning algorithms and utility functions for ETL and data analysis. It is distributed under the MIT License.

Jeong-Yoon Lee 720 Dec 25, 2022
MiniTorch - a diy teaching library for machine learning engineers

This repo is the full student code for minitorch. It is designed as a single repo that can be completed part by part following the guide book. It uses

1.1k Jan 07, 2023
UpliftML: A Python Package for Scalable Uplift Modeling

UpliftML is a Python package for scalable unconstrained and constrained uplift modeling from experimental data. To accommodate working with big data, the package uses PySpark and H2O models as base l

Booking.com 254 Dec 31, 2022