AlgoTraders
stock-analysis-engine
Jupyter Notebook

Backtest 1000s of minute-by-minute trading algorithms for training AI with automated pricing data from: IEX, Tradier and FinViz. Datasets and trading performance automatically published to S3 for building AI training datasets for teaching DNNs how to trade. Runs on Kubernetes and docker-compose. >150 million trading history rows generated from +5000 algorithms. Heads up: Yahoo's Finance API was disabled on 2019-01-03 https://developer.yahoo.com/yql/

Last updated Jun 30, 2026
1.2k
Stars
272
Forks
5
Issues
0
Stars/day
Attention Score
82
Language breakdown
Jupyter Notebook 78.7%
Python 19.4%
Shell 1.7%
Smarty 0.1%
Dockerfile 0.0%
Vim Script 0.0%
Files click to expand
README

Stock Analysis Engine =====================

Build and tune investment algorithms for use with artificial intelligence (deep neural networks) <https://github.com/AlgoTraders/stock-analysis-engine/blob/master/compose/docker/notebooks/Comparing-3-Deep-Neural-Networks-Trained-to-Predict-a-Stocks-Closing-Price-Using-The-Analysis-Engine.ipynb> with a distributed stack for running backtests using live pricing data on publicly traded companies with automated datafeeds from: IEX Cloud <https://iexcloud.io/>, Tradier <https://tradier.com/> and FinViz <https://finviz.com> (includes: pricing, options, news, dividends, daily, intraday, screeners, statistics, financials, earnings, and more).

Kubernetes users please refer to the Helm guide to get started <https://stock-analysis-engine.readthedocs.io/en/latest/deployonkubernetesusinghelm.html> and Metalnetes for running multiple Analysis Engines at the same time on a bare-metal server <https://metalnetes.readthedocs.io/en/latest/#>

.. image:: https://i.imgur.com/tw2wJ6t.png

Fetch the Latest Pricing Data =============================

Supported fetch methods for getting pricing data:

  • Command line using `fetch command
  • IEX Cloud Fetch API api.html#iex-fetch-api-reference>_
  • Tradier Fetch API __
  • Docker-compose using ./compose/start.sh -c
  • Kubernetes jobs: Fetch Intraday intradayperminute.yml>, Fetch Daily daily.yml>, Fetch Weekly weekly.yml>, or Fetch from only Tradier tradierperminute.yml>
Fetch using the Command Line

Here is a video showing how to fetch the latest pricing data for a ticker using the command line:

.. image:: https://asciinema.org/a/220460.png :target: https://asciinema.org/a/220460?autoplay=1 :alt: Fetch Pricing Data using the Command Line

#. Clone to /opt/sa

::

git clone https://github.com/AlgoTraders/stock-analysis-engine.git /opt/sa cd /opt/sa

#. Create Docker Mounts and Start Redis and Minio

This will pull Redis and Minio docker images.

::

./compose/start.sh -a

#. Fetch All Pricing Data

#. Run through the Getting Started section __

#. Fetch pricing data from IEX Cloud (requires an account and uses on-demand usage pricing) and Tradier (requires an account) :

- Set the IEX_TOKEN environment variable to fetch from the IEX Cloud datafeeds:

::

export IEXTOKEN=YOURIEX_TOKEN

- Set the TD_TOKEN environment variable to fetch from the Tradier datafeeds:

::

export TDTOKEN=YOURTRADIER_TOKEN

- Fetch with:

::

fetch -t SPY

- Fetch only from IEX with -g iex:

::

fetch -t SPY -g iex # and fetch from just Tradier with: # fetch -t SPY -g td

- Fetch previous 30 calendar days of intraday minute pricing data from IEX Cloud

::

backfill-minute-data.sh TICKER # backfill-minute-data.sh SPY

#. Please refer to the documentation for more examples on controlling your pricing request usage (including how to run fetches for intraday, daily and weekly use cases) engine.scripts.fetchnewstockdatasets>__

.. note:: Yahoo disabled the YQL finance API so fetching pricing data from yahoo is disabled by default __

#. View the Compressed Pricing Data in Redis

::

redis-cli keys "SPY_*" redis-cli get "<key like SPY2019-01-08minute>"

Run Backtests with the Algorithm Runner API ===========================================

Run a backtest with the latest pricing data:

.. code-block:: python

import analysisengine.algorunner as algo_runner import analysisengine.plottrading_history as plot runner = algo_runner.AlgoRunner('SPY') # run the algorithm with the latest 200 minutes: df = runner.latest() print(df[['minute', 'close']].tail(5)) plot.plottradinghistory( title=( f'SPY - ${df["close"].iloc[-1]} at: ' f'{df["minute"].iloc[-1]}'), df=df) # start a full backtest with: # runner.start()

Check out the backtestwithrunner.py script engine/scripts/backtestwithrunner.py> for a command line example of using the Algorithm Runner API runner.html> to run and plot from an Algorithm backtest config file algo.json>_.

Extract from Redis API ======================

Once fetched, you can extract datasets from the redis cache with:

.. code-block:: python

import analysisengine.extract as aeextract print(ae_extract.extract('SPY'))

Extract Latest Minute Pricing for Stocks and Options ====================================================

.. code-block:: python

import analysisengine.extract as aeextract print(ae_extract.extract( 'SPY', datasets=['minute', 'tdcalls', 'tdputs']))

Extract Historical Data


Extract historical data with the date argument formatted YYYY-MM-DD:

.. code-block:: python

import analysisengine.extract as aeextract print(ae_extract.extract( 'AAPL', datasets=['minute', 'daily', 'financials', 'earnings', 'dividends'], date='2019-02-15'))

Additional Extraction APIs ==========================

  • Extraction API Reference __
  • IEX Cloud Extraction API Reference api.html#iex-extraction-api-reference>_
  • Tradier Extraction API Reference __
  • Inspect Cached Datasets in Redis for Errors datasets.html#module-analysisengine.scripts.inspectdatasets>_
Backups =======

Pricing data is automatically compressed in redis and there is an example Kubernetes job for backing up all stored pricing data to AWS S3 __.

Running the Full Stack Locally for Backtesting and Live Trading Analysis ========================================================================

While not required for backtesting, running the full stack is required for running algorithms during a live trading session. Here is a video on how to deploy the full stack locally using docker compose and the commands from the video.

.. image:: https://asciinema.org/a/220487.png :target: https://asciinema.org/a/220487?autoplay=1 :alt: Running the Full Stack Locally for Backtesting and Live Trading Analysis

#. Start Workers, Backtester, Pricing Data Collection, Jupyter, Redis and Minio

Now start the rest of the stack with the command below. This will pull the ~3.0 GB stock-analysis-engine docker image and start the workers, backtester, dataset collection and Jupyter image . It will start Redis and Minio if they are not running already.

::

./compose/start.sh

.. tip:: Mac OS X users just a note that there is a known docker compose issue with networkmode: "host" _ so you may have issues trying to connect to your services.

#. Check the Docker Containers

::

docker ps -a

#. View for dataset collection logs

::

logs-dataset-collection.sh

#. Wait for pricing engine logs to stop with ctrl+c

::

logs-workers.sh

#. Verify Pricing Data is in Redis

::

redis-cli keys "*"

#. Optional - Automating pricing data collection with the automation-dataset-collection.yml docker compose file __:

.. note:: Depending on how fast you want to run intraday algorithms, you can use this docker compose job or the Kubernetes job or the Fetch from Only Tradier Kubernetes job tradierper_minute.yml> to collect the most recent pricing information

::

./compose/start.sh -c

Run a Custom Minute-by-Minute Intraday Algorithm Backtest and Plot the Trading History ======================================================================================

With pricing data in redis, you can start running backtests a few ways:

  • Comparing 3 Deep Neural Networks Trained to Predict a Stocks Closing Price in a Jupyter Notebook __
  • Build, run and tune within a Jupyter Notebook and plot the balance vs the stock's closing price while running __
  • Analyze and replay algorithm trading histories stored in s3 with this Jupyter Notebook __
  • Run with the command line backtest tool engine/scripts/runbacktestandplothistory.py>_
  • Advanced - building a standalone algorithm as a class for running trading analysis engine/mocks/examplealgominute.py>_
Running an Algorithm with Live Intraday Pricing Data ====================================================

Here is a video showing how to run it:

.. image:: https://asciinema.org/a/220498.png :target: https://asciinema.org/a/220498?autoplay=1 :alt: Running an Algorithm with Live Intraday Pricing Data

The backtest command line tool engine/scripts/runbacktestandplothistory.py> uses an algorithm config dictionary configs/test5daysahead.json> to build multiple Williams %R indicators engine/scripts/runbacktestandplothistory.py#L49>__ into an algorithm with a 10,000.00 USD starting balance. Once configured, the backtest iterates through each trading dataset and evaluates if it should buy or sell based off the pricing data. After it finishes, the tool will display a chart showing the algorithm's balance and the stock's close price per minute using matplotlib and seaborn.

::

# this can take a few minutes to evaluate # as more data is collected # because each day has 390 rows to process bt -t SPY -f /tmp/history.json

.. note:: The algorithm's trading history dataset provides many additional columns to review for tuning indicators and custom buy/sell rules. To reduce the time spent waiting on an algorithm to finish processing, you can save the entire trading history to disk with the -f <savetofile> argument.

View the Minute Algorithm's Trading History from a File =======================================================

Once the trading history is saved to disk, you can open it back up and plot other columns within the dataset with:

.. image:: https://i.imgur.com/pH368gy.png

::

# by default the plot shows # balance vs close per minute plot-history -f /tmp/history.json

Run a Custom Algorithm and Save the Trading History with just Today's Pricing Data ==================================================================================

Here's how to run an algorithm during a live trading session. This approach assumes another process or cron is fetch-ing the pricing data using the engine so the algorithm(s) have access to the latest pricing data:

::

bt -t SPY -f /tmp/SPY-history-$(date +"%Y-%m-%d").json -j $(date +"%Y-%m-%d")

.. note:: Using -j <DATE> will make the algorithm jump-to-this-date before starting any trading. This is helpful for debugging indicators, algorithms, datasets issues, and buy/sell rules as well.

Run a Backtest using an External Algorithm Module and Config File =================================================================

Run an algorithm backtest with a standalone algorithm class contained in a single python module file that can even be outside the repository using a config file on disk:

::

ticker=SPY config=<CUSTOMALGOCONFIGDIR>/minutealgo.json algomod=<CUSTOMALGOMODULEDIR>/minute_algo.py bt -t ${ticker} -c ${algoconfig} -g ${algomod}

Or the config can use "algopath": "<PATHTO_FILE>" to set the path to an external algorithm module file.

::

bt -t ${ticker} -c ${algo_config}

.. note:: Using a standalone algorithm class must derive from the analysis_engine.algo.BaseAlgo class

Building Your Own Trading Algorithms ====================================

Beyond running backtests, the included engine supports running many algorithms and fetching data for both live trading or backtesting all at the same time. As you start to use this approach, you will be generating lots of algorithm pricing datasets, history datasets and coming soon performance datasets for AI training. Because algorithm's utilize the same dataset structure, you can share ready-to-go datasets with a team and publish them to S3 for kicking off backtests using lambda functions or just archival for disaster recovery.

.. note:: Backtests can use ready-to-go datasets out of S3, redis or a file

The next section looks at how to build an algorithm-ready datasets from cached pricing data in redis __.

Run a Local Backtest and Publish Algorithm Trading History to S3 ================================================================

::

ae -t SPY -p s3://algohistory/algotrainingSPY.json

Run distributed across the engine workers with -w

::

ae -w -t SPY -p s3://algohistory/algotrainingSPY.json

Run a Local Backtest using an Algorithm Config and Extract an Algorithm-Ready Dataset =====================================================================================

Use this command to start a local backtest with the included algorithm config configs/test5daysahead.json>__. This backtest will also generate a local algorithm-ready dataset saved to a file once it finishes.

#. Define common values

::

ticker=SPY algoconfig=tests/algoconfigs/test5days_ahead.json extract_loc=file:/tmp/algoready-SPY-latest.json history_loc=file:/tmp/history-SPY-latest.json loadloc=${extractloc}

Run Algo with Extraction and History Publishing


::

run-algo-history-to-file.sh -t ${ticker} -c ${algoconfig} -e ${extractloc} -p ${history_loc}

Profile Your Algorithm's Code Performance with vprof ====================================================

.. image:: https://i.imgur.com/1cwDUBC.png

The pip includes vprof for profiling an algorithm's performance (cpu, memory, profiler and heat map - not money-related) __ which was used to generate the cpu flame graph seen above.

Profile your algorithm's code performance with the following steps:

#. Start vprof in remote mode in a first terminal

.. note:: This command will start a webapp on port 3434

::

vprof -r -p 3434

#. Start Profiler in a second terminal

.. note:: This command pushes data to the webapp in the other terminal listening on port 3434

::

vprof -c cm ./analysisengine/perf/profilealgo_runner.py

Run a Local Backtest using an Algorithm Config and an Algorithm-Ready Dataset =============================================================================

After generating the local algorithm-ready dataset (which can take some time), use this command to run another backtest using the file on disk:

::

devhistoryloc=file:/tmp/dev-history-${ticker}-latest.json run-algo-history-to-file.sh -t ${ticker} -c ${algoconfig} -l ${loadloc} -p ${devhistoryloc}

View Buy and Sell Transactions


::

run-algo-history-to-file.sh -t ${ticker} -c ${algoconfig} -l ${loadloc} -p ${devhistoryloc} | grep "TRADE"

Plot Trading History Tools ==========================

Plot Timeseries Trading History with High + Low + Open + Close


::

sa -t SPY -H ${devhistoryloc}

Run and Publish Trading Performance Report for a Custom Algorithm =================================================================

This will run a backtest over the past 60 days in order and run the standalone algorithm as a class example engine/mocks/examplealgominute.py>_. Once done it will publish the trading performance report to a file or minio (s3).

Write the Trading Performance Report to a Local File


::

run-algo-report-to-file.sh -t SPY -b 60 -a /opt/sa/analysisengine/mocks/examplealgo_minute.py # run-algo-report-to-file.sh -t <TICKER> -b <NUMDAYSBACK> -a <CUSTOMALGOMODULE> # run on specific date ranges with: # -s <start date YYYY-MM-DD> -n <end date YYYY-MM-DD>

Write the Trading Performance Report to Minio (s3)


::

run-algo-report-to-s3.sh -t SPY -b 60 -a /opt/sa/analysisengine/mocks/examplealgo_minute.py

Run and Publish Trading History for a Custom Algorithm ======================================================

This will run a full backtest across the past 60 days in order and run the example algorithm engine/mocks/examplealgominute.py>_. Once done it will publish the trading history to a file or minio (s3).

Write the Trading History to a Local File


::

run-algo-history-to-file.sh -t SPY -b 60 -a /opt/sa/analysisengine/mocks/examplealgo_minute.py

Write the Trading History to Minio (s3)


::

run-algo-history-to-s3.sh -t SPY -b 60 -a /opt/sa/analysisengine/mocks/examplealgo_minute.py

Developing on AWS =================

If you are comfortable with AWS S3 usage charges, then you can run just with a redis server to develop and tune algorithms. This works for teams and for archiving datasets for disaster recovery.

Environment Variables


Export these based off your AWS IAM credentials and S3 endpoint.

::

export AWSACCESSKEY_ID="ACCESS" export AWSSECRETACCESS_KEY="SECRET" export S3_ADDRESS=s3.us-east-1.amazonaws.com

Extract and Publish to AWS S3 =============================

::

./tools/backup-datasets-on-s3.sh -t TICKER -q YOURBUCKET -k ${S3ADDRESS} -r localhost:6379

Publish to Custom AWS S3 Bucket and Key =======================================

::

extractloc=s3://YOURBUCKET/TICKER-latest.json ./tools/backup-datasets-on-s3.sh -t TICKER -e ${extract_loc} -r localhost:6379

Backtest a Custom Algorithm with a Dataset on AWS S3 ====================================================

::

backtestloc=s3://YOURBUCKET/TICKER-latest.json customalgomodule=/opt/sa/analysisengine/mocks/examplealgo_minute.py sa -t TICKER -a ${S3ADDRESS} -r localhost:6379 -b ${backtestloc} -g ${customalgomodule}

Fetching New Pricing Tradier Every Minute with Kubernetes =========================================================

If you want to fetch and append new option pricing data from Tradier started>_, you can use the included kubernetes job with a cron to pull new data every minute:

::

kubectl -f apply /opt/sa/k8/datasets/pulltradierper_minute.yml

Run a Distributed 60-day Backtest on SPY and Publish the Trading Report, Trading History and Algorithm-Ready Dataset to S3 ==========================================================================================================================

Publish backtests and live trading algorithms to the engine's workers for running many algorithms at the same time. Once done, the algorithm will publish results to s3, redis or a local file. By default, the included example below publishes all datasets into minio (s3) where they can be downloaded for offline backtests or restored back into redis.

.. note:: Running distributed algorithmic workloads requires redis, minio, and the engine running

::

numdaysback=60 ./tools/run-algo-with-publishing.sh -t SPY -b ${numdaysback} -w

Run a Local 60-day Backtest on SPY and Publish Trading Report, Trading History and Algorithm-Ready Dataset to S3 ================================================================================================================

::

numdaysback=60 ./tools/run-algo-with-publishing.sh -t SPY -b ${numdaysback}

Or manually with:

::

ticker=SPY numdaysback=60 use_date=$(date +"%Y-%m-%d") ds_id=$(uuidgen | sed -e 's/-//g') tickerdataset="${ticker}-${usedate}${dsid}.json" echo "creating ${ticker} dataset: ${ticker_dataset}" extractloc="s3://algoready/${tickerdataset}" historyloc="s3://algohistory/${tickerdataset}" reportloc="s3://algoreport/${tickerdataset}" backtestloc="s3://algoready/${tickerdataset}" # same as the extract_loc processedloc="s3://algoprocessed/${tickerdataset}" # archive it when done startdate=$(date --date="${numdays_back} day ago" +"%Y-%m-%d") echo "" echo "extracting algorithm-ready dataset: ${extract_loc}" echo "sa -t SPY -e ${extractloc} -s ${startdate} -n ${use_date}" sa -t SPY -e ${extractloc} -s ${startdate} -n ${use_date} echo "" echo "running algo with: ${backtest_loc}" echo "sa -t SPY -p ${historyloc} -o ${reportloc} -b ${backtestloc} -e ${processedloc} -s ${startdate} -n ${usedate}" sa -t SPY -p ${historyloc} -o ${reportloc} -b ${backtestloc} -e ${processedloc} -s ${startdate} -n ${usedate}

Jupyter on Kubernetes =====================

This command runs Jupyter on an AntiNex Kubernetes cluster __

::

./k8/jupyter/run.sh ceph dev

Kubernetes - Analyze and Tune Algorithms from a Trading History ===============================================================

With the Analysis Engine's Jupyter instance deployed you can tune algorithms from a trading history using this notebook __.

Kubernetes Job - Export SPY Datasets and Publish to Minio =========================================================

Manually run with an ssh-eng alias:

::

function ssheng() { pod_name=$(kubectl get po | grep ae-engine | grep Running |tail -1 | awk '{print $1}') echo "logging into ${pod_name}" kubectl exec -it ${pod_name} bash } ssheng # once inside the container on kubernetes source /opt/venv/bin/activate sa -a minio-service:9000 -r redis-master:6379 -e s3://backups/SPY-$(date +"%Y-%m-%d") -t SPY

View Algorithm-Ready Datasets


With the AWS cli configured you can view available algorithm-ready datasets in your minio (s3) bucket with the command:

::

aws --endpoint-url http://localhost:9000 s3 ls s3://algoready

View Trading History Datasets


With the AWS cli configured you can view available trading history datasets in your minio (s3) bucket with the command:

::

aws --endpoint-url http://localhost:9000 s3 ls s3://algohistory

View Trading History Datasets


With the AWS cli configured you can view available trading performance report datasets in your minio (s3) bucket with the command:

::

aws --endpoint-url http://localhost:9000 s3 ls s3://algoreport

Advanced - Running Algorithm Backtests Offline ==============================================

With extracted Algorithm-Ready datasets in minio (s3), redis or a file __ you can develop and tune your own algorithms offline without having redis, minio, the analysis engine, or jupyter running locally.

Run a Offline Custom Algorithm Backtest with an Algorithm-Ready File


::

# extract with: sa -t SPY -e file:/tmp/SPY-latest.json sa -t SPY -b file:/tmp/SPY-latest.json -g /opt/sa/analysisengine/mocks/examplealgo_minute.py

Run the Intraday Minute-by-Minute Algorithm and Publish the Algorithm-Ready Dataset to S3


Run the included standalone algorithm engine/mocks/examplealgominute.py>_ with the latest pricing datasets use:

::

sa -t SPY -g /opt/sa/analysisengine/mocks/examplealgo_minute.py -e s3://algoready/SPY-$(date +"%Y-%m-%d").json

And to debug an algorithm's historical trading performance add the -d debug flag:

::

sa -d -t SPY -g /opt/sa/analysisengine/mocks/examplealgo_minute.py -e s3://algoready/SPY-$(date +"%Y-%m-%d").json

Extract Algorithm-Ready Datasets ================================

With pricing data cached in redis, you can extract algorithm-ready datasets and save them to a local file for offline historical backtesting analysis. This also serves as a local backup where all cached data for a single ticker is in a single local file.

Extract an Algorithm-Ready Dataset from Redis and Save it to a File


::

sa -t SPY -e ~/SPY-latest.json

Create a Daily Backup


::

sa -t SPY -e ~/SPY-$(date +"%Y-%m-%d").json

Validate the Daily Backup by Examining the Dataset File


::

sa -t SPY -l ~/SPY-$(date +"%Y-%m-%d").json

Validate the Daily Backup by Examining the Dataset File


::

sa -t SPY -l ~/SPY-$(date +"%Y-%m-%d").json

Restore Backup to Redis


Use this command to cache missing pricing datasets so algorithms have the correct data ready-to-go before making buy and sell predictions.

.. note:: By default, this command will not overwrite existing datasets in redis. It was built as a tool for merging redis pricing datasets after a VM restarted and pricing data was missing from the past few days (gaps in pricing data is bad for algorithms).

::

sa -t SPY -L ~/SPY-$(date +"%Y-%m-%d").json

Fetch


With redis and minio running (./compose/start.sh), you can fetch, cache, archive and return all of the newest datasets for tickers:

.. code-block:: python

from analysis_engine.fetch import fetch d = fetch(ticker='SPY') for k in d['SPY']: print(f'dataset key: {k}\nvalue {d["SPY"][k]}\n')

Backfill Historical Minute Data from IEX Cloud ==============================================

.. note:: IEX Cloud supports pulling from 30 days before today __

::

fetch -t TICKER -F PASTDATE -g iexmin # example: # fetch -t SPY -F 2019-02-07 -g iex_min

Please refer to the Stock Analysis Intro Extracting Datasets Jupyter Notebook __ for the latest usage examples.

.. list-table:: :header-rows: 1

* - Build __ * - .. image:: https://api.travis-ci.org/AlgoTraders/stock-analysis-engine.svg :alt: Travis Tests :target: https://travis-ci.org/AlgoTraders/stock-analysis-engine

Getting Started ===============

This section outlines how to get the Stock Analysis stack running locally with:

  • Redis
  • Minio (S3)
  • Stock Analysis engine
  • Jupyter
For background, the stack provides a data pipeline that automatically archives pricing data in
minio (s3) __ and caches pricing data in redis. Once cached or archived, custom algorithms can use the pricing information to determine buy or sell conditions and track internal trading performance across historical backtests.

From a technical perspective, the engine uses Celery workers to process heavyweight, asynchronous tasks and scales horizontally with support for many transports and backends depending on where you need to run it . The stack deploys with Kubernetes or docker compose and supports publishing trading alerts to Slack .

With the stack already running, please refer to the Intro Stock Analysis using Jupyter Notebook __ for more getting started examples.

Setting up Your Tradier Account with Docker Compose ===================================================

Please set your Tradier account token in the docker environment files before starting the stack:

::

grep -r SETYOURTRADIERTOKENHERE compose/* compose/envs/backtester.env:TD_TOKEN=SETYOURTRADIERTOKENHERE compose/envs/workers.env:TD_TOKEN=SETYOURTRADIERTOKENHER

Please export the variable for developing locally:

::

export TDTOKEN=<TRADIERACCOUNT_TOKEN>

.. note:: Please restart the stack with ./compose/stop.sh then ./compose/start.sh after setting the Tradier token environment variable

#. Start Redis and Minio

.. note:: The Redis and Minio container are set up to save data to /data so files can survive a restart/reboot. On Mac OS X, please make sure to add /data (and /data/sa/notebooks for Jupyter notebooks) on the Docker Preferences -> File Sharing tab and let the docker daemon restart before trying to start the containers. If not, you will likely see errors like:

::

ERROR: for minio Cannot start service minio: b'Mounts denied: \r\nThe path /data/minio/data\r\nis not shared from OS X

Here is the command to manully creaate the shared volume directories:

::

sudo mkdir -p -m 777 /data/redis/data /data/minio/data /data/sa/notebooks/dev /data/registry/auth /data/registry/data

::

./compose/start.sh

#. Verify Redis and Minio are Running

::

docker ps | grep -E "redis|minio"

Running on Ubuntu and CentOS ============================

#. Install Packages

Ubuntu

::

sudo apt-get install make cmake gcc python3-distutils python3-tk python3 python3-apport python3-certifi python3-dev python3-pip python3-venv python3.6 redis-tools virtualenv libcurl4-openssl-dev libssl-dev

CentOS 7

::

sudo yum install cmake gcc gcc-c++ make tkinter curl-devel make cmake python-devel python-setuptools python-pip python-virtualenv redis python36u-libs python36u-devel python36u-pip python36u-tkinter python36u-setuptools python36u openssl-devel

#. Install TA-Lib

Follow the TA-Lib install guide __ or use the included install tool as root:

::

sudo su /opt/sa/tools/linux-install-talib.sh exit

#. Create and Load Python 3 Virtual Environment

::

virtualenv -p python3 /opt/venv source /opt/venv/bin/activate pip install --upgrade pip setuptools

#. Install Analysis Pip

::

pip install -e .

#. Verify Pip installed

::

pip list | grep stock-analysis-engine

Running on Mac OS X ===================

#. Download Python 3.6

.. note:: Python 3.7 is not supported by celery so please ensure it is python 3.6

https://www.python.org/downloads/mac-osx/

#. Install Packages

::

brew install openssl pyenv-virtualenv redis freetype pkg-config gcc ta-lib

.. note:: Mac OS X users just a note keras, tensorflow and h5py installs have not been debugged yet. Please let us know if you have issues setting up your environment. We likely have not hit the issue yet.

#. Create and Load Python 3 Virtual Environment

::

python3 -m venv /opt/venv source /opt/venv/bin/activate pip install --upgrade pip setuptools

#. Install Certs

After hitting ssl verify errors, I found this stack overflow __ which shows there's an additional step for setting up python 3.6:

::

/Applications/Python\ 3.6/Install\ Certificates.command

#. Install PyCurl with OpenSSL

::

PYCURLSSLLIBRARY=openssl LDFLAGS="-L/usr/local/opt/openssl/lib" CPPFLAGS="-I/usr/local/opt/openssl/include" pip install --no-cache-dir pycurl

#. Install Analysis Pip

::

pip install --upgrade pip setuptools pip install -e .

#. Verify Pip installed

::

pip list | grep stock-analysis-engine

Start Workers =============

::

./start-workers.sh

Get and Publish Pricing data ============================

Please refer to the lastest API docs in the repo:

https://github.com/AlgoTraders/stock-analysis-engine/blob/master/analysisengine/apirequests.py

Fetch New Stock Datasets ========================

Run the ticker analysis using the ./analysisengine/scripts/fetchnewstockdatasets.py engine/scripts/fetchnewstockdatasets.py>__:

Collect all datasets for a Ticker or Symbol


Collect all datasets for the ticker SPY:

::

fetch -t SPY

.. note:: This requires the following services are listening on:

- redis localhost:6379 - minio localhost:9000

View the Engine Worker Logs


::

docker logs ae-workers

Running Inside Docker Containers


If you are using an engine that is running inside a docker container, then localhost is probably not the correct network hostname for finding redis and minio.

Please set these values as needed to publish and archive the dataset artifacts if you are using the integration or notebook integration docker compose files for deploying the analysis engine stack:

::

fetch -t SPY -a 0.0.0.0:9000 -r 0.0.0.0:6379

.. warning:: It is not recommended sharing the same Redis server with multiple engine workers from inside docker containers and outside docker. This is because the REDISADDRESS and S3ADDRESS can only be one string value at the moment. So if a job is picked up by the wrong engine (which cannot connect to the correct Redis and Minio), then it can lead to data not being cached or archived correctly and show up as connectivity failures.

Detailed Usage Example


The fetchnewstockdatasets.py script engine/scripts/fetchnewstockdatasets.py> supports many parameters. Here is how to set it up if you have custom redis and minio deployments like on kubernetes as minio-service:9000 and redis-master:6379 _:

  • S3 authentication (-k and -s)
  • S3 endpoint (-a)
  • Redis endoint (-r)
  • Custom S3 Key and Redis Key Name (-n)
::

fetch -t SPY -g all -u pricing -k trexaccesskey -s trex123321 -a localhost:9000 -r localhost:6379 -m 0 -n SPY_demo -P 1 -N 1 -O 1 -U 1 -R 1

Usage


Please refer to the fetchnewstockdatasets.py script engine/scripts/fetchnewstockdatasets.py>_ for the latest supported usage if some of these are out of date:

::

fetch -h 2019-02-11 01:55:33,791 - fetch - INFO - start - fetchnewstock_datasets usage: fetchnewstockdatasets.py [-h] [-t TICKER] [-g FETCHMODE] [-i TICKERID] [-e EXPDATE_STR] [-l LOGCONFIGPATH] [-b BROKER_URL] [-B BACKENDURL] [-k S3ACCESS_KEY] [-s S3SECRETKEY] [-a S3_ADDRESS] [-S S3SECURE] [-u S3BUCKET_NAME] [-G S3REGIONNAME] [-p REDIS_PASSWORD] [-r REDIS_ADDRESS] [-n KEYNAME] [-m REDISDB] [-x REDISEXPIRE] [-z STRIKE] [-c CONTRACTTYPE] [-P GETPRICING] [-N GETNEWS] [-O GETOPTIONS] [-U S3ENABLED] [-R REDISENABLED] [-A ANALYSIS_TYPE] [-L URLS] [-Z] [-d]

Download and store the latest stock pricing, news, and options chain data and store it in Minio (S3) and Redis. Also includes support for getting FinViz screener tickers

optional arguments: -h, --help show this help message and exit -t TICKER ticker -g FETCH_MODE optional - fetch mode: initial = default fetch from initial data feeds (IEX and Tradier), intra = fetch intraday from IEX and Tradier, daily = fetch daily from IEX, weekly = fetch weekly from IEX, all = fetch from all data feeds, td = fetch from Tradier feeds only, iex = fetch from IEX Cloud feeds only, iex_min = fetch IEX Cloud intraday per-minute feed https://iexcloud.io/docs/api/#historical-prices iex_day = fetch IEX Cloud daily feed https://iexcloud.io/docs/api/#historical-prices iex_quote = fetch IEX Cloud quotes feed https://iexcloud.io/docs/api/#quote iex_stats = fetch IEX Cloud key stats feed https://iexcloud.io/docs/api/#key-stats iex_peers = fetch from just IEX Cloud peers feed https://iexcloud.io/docs/api/#peers iex_news = fetch IEX Cloud news feed https://iexcloud.io/docs/api/#news iex_fin = fetch IEX Cloud financials feedhttps://iexcloud.io/docs/api/#financials iex_earn = fetch from just IEX Cloud earnings feeed https://iexcloud.io/docs/api/#earnings iex_div = fetch from just IEX Cloud dividends feedhttps://iexcloud.io/docs/api/#dividends iex_comp = fetch from just IEX Cloud company feed https://iexcloud.io/docs/api/#company -i TICKER_ID optional - ticker id not used without a database -e EXPDATESTR optional - options expiration date -l LOGCONFIGPATH optional - path to the log config file -b BROKER_URL optional - broker url for Celery -B BACKEND_URL optional - backend url for Celery -k S3ACCESSKEY optional - s3 access key -s S3SECRETKEY optional - s3 secret key -a S3_ADDRESS optional - s3 address format: <host:port> -S S3_SECURE optional - s3 ssl or not -u S3BUCKETNAME optional - s3 bucket name -G S3REGIONNAME optional - s3 region name -p REDISPASSWORD optional - redispassword -r REDISADDRESS optional - redisaddress format: <host:port> -n KEYNAME optional - redis and s3 key name -m REDIS_DB optional - redis database number (0 by default) -x REDIS_EXPIRE optional - redis expiration in seconds -z STRIKE optional - strike price -c CONTRACT_TYPE optional - contract type "C" for calls "P" for puts -P GET_PRICING optional - get pricing data if "1" or "0" disabled -N GET_NEWS optional - get news data if "1" or "0" disabled -O GET_OPTIONS optional - get options data if "1" or "0" disabled -U S3_ENABLED optional - s3 enabled for publishing if "1" or "0" is disabled -R REDIS_ENABLED optional - redis enabled for publishing if "1" or "0" is disabled -A ANALYSIS_TYPE optional - run an analysis supported modes: scn -L URLS optional - screener urls to pull tickers for analysis -Z disable run without an engine for local testing and demos -d debug

Run FinViz Screener-driven Analysis ===================================

This is a work in progress, but the screener-driven workflow is:

#. Convert FinViz screeners into a list of tickers and a pandas.DataFrames from each ticker's html row #. Build unique list of tickers #. Pull datasets for each ticker #. Run sale-side processing - coming soon #. Run buy-side processing - coming soon #. Issue alerts to slack - coming soon

Here is how to run an analysis on all unique tickers found in two FinViz screener urls:

https://finviz.com/screener.ashx?v=111&f=capmidunder,exchnyse,fadivo6,idx_sp500&ft=4 and https://finviz.com/screener.ashx?v=111&f=capmidunder,exchnyse,fadivo8,idx_sp500&ft=4

::

fetch -A scn -L 'https://finviz.com/screener.ashx?v=111&f=capmidunder,exchnyse,fadivo6,idxsp500&ft=4|https://finviz.com/screener.ashx?v=111&f=capmidunder,exchnyse,fadivo8,idxsp500&ft=4'

Run Publish from an Existing S3 Key to Redis ============================================

#. Upload Integration Test Key to S3

::

export INT_TESTS=1 python -m unittest tests.testpublishpricingupdate.TestPublishPricingData.testintegrations3upload

#. Confirm the Integration Test Key is in S3

http://localhost:9000/minio/integration-tests/

#. Run an analysis with an existing S3 key using ./analysisengine/scripts/publishfroms3toredis.py engine/scripts/publishfroms3toredis.py>__

::

publishfroms3toredis.py -t SPY -u integration-tests -k trexaccesskey -s trex123321 -a localhost:9000 -r localhost:6379 -m 0 -n integration-test-v1

#. Confirm the Key is now in Redis

::

./tools/redis-cli.sh 127.0.0.1:6379> keys * keys * 1) "SPYdemodaily" 2) "SPYdemominute" 3) "SPYdemocompany" 4) "integration-test-v1" 5) "SPYdemostats" 6) "SPY_demo" 7) "SPYdemoquote" 8) "SPYdemopeers" 9) "SPYdemodividends" 10) "SPYdemonews1" 11) "SPYdemonews" 12) "SPYdemooptions" 13) "SPYdemopricing" 127.0.0.1:6379>

Run Aggregate and then Publish data for a Ticker from S3 to Redis =================================================================

#. Run an analysis with an existing S3 key using ./analysisengine/scripts/publishtickeraggregatefroms3.py engine/scripts/publishtickeraggregatefroms3.py>__

::

publishtickeraggregatefroms3.py -t SPY -k trexaccesskey -s trex123321 -a localhost:9000 -r localhost:6379 -m 0 -u pricing -c compileddatasets

#. Confirm the aggregated Ticker is now in Redis

::

./tools/redis-cli.sh 127.0.0.1:6379> keys latest 1) "SPY_latest" 127.0.0.1:6379>

View Archives in S3 - Minio ===========================

Here's a screenshot showing the stock market dataset archives created while running on the 3-node Kubernetes cluster for distributed AI predictions __

.. image:: https://i.imgur.com/wDyPKAp.png

http://localhost:9000/minio/pricing/

Login

  • username: trexaccesskey
  • password: trex123321
Using the AWS CLI to List the Pricing Bucket

Please refer to the official steps for using the awscli pip with minio:

https://docs.minio.io/docs/aws-cli-with-minio.html

#. Export Credentials

::

export AWSSECRETACCESS_KEY=trex123321 export AWSACCESSKEY_ID=trexaccesskey

#. List Buckets

::

aws --endpoint-url http://localhost:9000 s3 ls 2018-10-02 22:24:06 company 2018-10-02 22:24:02 daily 2018-10-02 22:24:06 dividends 2018-10-02 22:33:15 integration-tests 2018-10-02 22:24:03 minute 2018-10-02 22:24:05 news 2018-10-02 22:24:04 peers 2018-10-02 22:24:06 pricing 2018-10-02 22:24:04 stats 2018-10-02 22:24:04 quote

#. List Pricing Bucket Contents

::

aws --endpoint-url http://localhost:9000 s3 ls s3://pricing

#. Get the Latest SPY Pricing Key

::

aws --endpoint-url http://localhost:9000 s3 ls s3://pricing | grep -i spy_demo SPY_demo

View Caches in Redis ====================

::

./tools/redis-cli.sh 127.0.0.1:6379> keys * 1) "SPY_demo"

Jupyter =======

You can run the Jupyter notebooks by starting the notebook-integration.yml stack __ with the command:

.. warning:: On Mac OS X, Jupyter does not work with the Analysis Engine at the moment. PR's are welcomed, but we have not figured out how to share the notebooks and access redis and minio with the known docker compose issue with networkhost on Mac OS X _

For Linux users, the Jupyter container hosts the Stock Analysis Intro notebook __ at the url (default login password is admin):

http://localhost:8888/notebooks/Stock-Analysis-Intro.ipynb

Jupyter Presentations with RISE ===============================

The docker container comes with RISE installed __ for running notebook presentations from a browser. Here's the button on the notebook for starting the web presentation:

.. image:: https://i.imgur.com/IDMW2Oc.png

Distributed Automation with Docker ==================================

.. note:: Automation requires the integration stack running (redis + minio + engine) and docker-compose.

Dataset Collection ==================

Start automated dataset collection with docker compose:

::

./compose/start.sh -c

Datasets in Redis =================

After running the dataset collection container, the datasets should be auto-cached in Minio (http://localhost:9000/minio/pricing/) and Redis:

::

./tools/redis-cli.sh 127.0.0.1:6379> keys *

Publishing to Slack ===================

Please refer to the Publish Stock Alerts to Slack Jupyter Notebook __ for the latest usage examples.

Publish FinViz Screener Tickers to Slack


Here is sample code for trying out the Slack integration.

.. code-block:: python

import analysisengine.finviz.fetchapi as fv from analysisengine.sendtoslack import postdf # simple NYSE Dow Jones Index Financials with a P/E above 5 screener url url = 'https://finviz.com/screener.ashx?v=111&f=exchnyse,fapeo5,idxdji,sec_financial&ft=4' res = fv.fetchtickersfrom_screener(url=url) df = res['rec']['data']

# please make sure the SLACK_WEBHOOK environment variable is set correctly: post_df( df=df[SLACKFINVIZCOLUMNS], columns=SLACKFINVIZCOLUMNS)

Running on Kubernetes =====================

Kubernetes Deployments - Engine


Deploy the engine with:

::

kubectl apply -f ./k8/engine/deployment.yml

Kubernetes Job - Dataset Collection


Start the dataset collection job with:

::

kubectl apply -f ./k8/datasets/job.yml

Kubernetes Deployments - Jupyter


Deploy Jupyter to a Kubernetes cluster with:

::

./k8/jupyter/run.sh

Kubernetes with a Private Docker Registry =========================================

You can deploy a private docker registry that can be used to pull images from outside a kubernetes cluster with the following steps:

#. Deploy Docker Registry

::

./compose/start.sh -r

#. Configure Kubernetes hosts and other docker daemons for insecure registries

::

cat /etc/docker/daemon.json { "insecure-registries": [ "<public ip address/fqdn for host running the registry container>:5000" ] }

#. Restart all Docker daemons

::

sudo systemctl restart docker

#. Login to Docker Registry from all Kubernetes hosts and other daemons that need access to the registry

.. note:: Change the default registry password by either changing the ./compose/start.sh file that uses trex and 123321 as the credentials or you can edit the volume mounted file /data/registry/auth/htpasswd. Here is how to find the registry's default login set up:

::

grep docker compose/start.sh | grep htpass

::

docker login <public ip address/fqdn for host running the registry container>:5000

#. Setup Kubernetes Secrets for All Credentials

Set each of the fields according to your own buckets, docker registry and Tradier account token:

::

cat /opt/sa/k8/secrets/secrets.yml | grep SETYOUR awsaccesskey_id: SETYOURENCODEDAWSACCESSKEYID awssecretaccess_key: SETYOURENCODEDAWSSECRETACCESSKEY .dockerconfigjson: SETYOURDOCKERCREDS td_token: SETYOURTDTOKEN

#. Deploy Kubernetes Secrets

::

kubectl apply -f /opt/sa/k8/secrets/secrets.yml

#. Confirm Kubernetes Secrets are Deployed

::

kubectl get secrets ae.docker.creds NAME TYPE DATA AGE ae.docker.creds kubernetes.io/dockerconfigjson 1 4d1h

::

kubectl get secrets | grep "ae\." ae.docker.creds kubernetes.io/dockerconfigjson 1 4d1h ae.k8.aws.s3 Opaque 3 4d1h ae.k8.minio.s3 Opaque 3 4d1h ae.k8.tradier Opaque 4 4d1h

#. Configure Kubernetes Deployments for using an External Private Docker Registry

Add these lines to a Kubernetes deployment yaml file based off your set up:

::

imagePullSecrets: - name: ae.docker.creds containers: - image: <public ip address/fqdn for host running the registry container>:5000/my-own-stock-ae:latest imagePullPolicy: Always

.. tip:: After spending a sad amount of time debugging, please make sure to delete pods before applying new ones that are pulling docker images from an external registry. After running the kubectl delete pod <name>, you can apply/create the pod to get the latest image running.

Testing =======

To show debug, trace logging please export SHAREDLOGCFG to a debug logger json file. To turn on debugging for this library, you can export this variable to the repo's included file with the command:

::

export SHAREDLOGCFG=/opt/sa/analysis_engine/log/debug-logging.json

.. note:: There is a known pandas issue that logs a warning about timelex `_, and it will show as a warning until it is fixed in pandas. Please ignore this warning for now.

::

DeprecationWarning: _timelex is a private class and may break without warning, it will be moved and or renamed in future versions.

Run all

::

py.test --maxfail=1

Run a test case

::

python -m unittest tests.testpublishpricingupdate.TestPublishPricingData.testsuccesspublishpricing_data

Test Publishing


S3 Upload


::

python -m unittest tests.testpublishpricingupdate.TestPublishPricingData.testsuccesss3upload

Publish from S3 to Redis


::

python -m unittest tests.testpublishfroms3toredis.TestPublishFromS3ToRedis.testsuccesspublishfroms3to_redis

Redis Cache Set


::

python -m unittest tests.testpublishpricingupdate.TestPublishPricingData.testsuccessredisset

Prepare Dataset


::

python -m unittest tests.testpreparepricingdataset.TestPreparePricingDataset.testpreparepricingdata_success

Test Algo Saving All Input Datasets to File


::

python -m unittest tests.testbasealgo.TestBaseAlgo.testalgocansaveallinputdatasetstofile

End-to-End Integration Testing ==============================

Start all the containers for full end-to-end integration testing with real docker containers with the script:

::

./compose/start.sh -a

Verify Containers are running:

::

docker ps | grep -E "stock-analysis|redis|minio"

Stop End-to-End Stack:

::

./compose/stop.sh ./compose/stop.sh -s

Integration UnitTests =====================

.. note:: please start redis and minio before running these tests.

Please enable integration tests

::

export INT_TESTS=1

Redis


::

python -m unittest tests.testpublishpricingupdate.TestPublishPricingData.testintegrationredisset

S3 Upload


::

python -m unittest tests.testpublishpricingupdate.TestPublishPricingData.testintegrations3upload

Publish from S3 to Redis


::

python -m unittest tests.testpublishfroms3toredis.TestPublishFromS3ToRedis.testintegrationpublishfroms3to_redis

IEX Test - Fetching All Datasets


::

python -m unittest tests.testiexfetch_data

IEX Test - Fetch Daily


::

python -m unittest tests.testiexfetchdata.TestIEXFetchData.testintegrationfetchdaily

IEX Test - Fetch Minute


::

python -m unittest tests.testiexfetchdata.TestIEXFetchData.testintegrationfetchminute

IEX Test - Fetch Stats


::

python -m unittest tests.testiexfetchdata.TestIEXFetchData.testintegrationfetchstats

IEX Test - Fetch Peers


::

python -m unittest tests.testiexfetchdata.TestIEXFetchData.testintegrationfetchpeers

IEX Test - Fetch News


::

python -m unittest tests.testiexfetchdata.TestIEXFetchData.testintegrationfetchnews

IEX Test - Fetch Financials


::

python -m unittest tests.testiexfetchdata.TestIEXFetchData.testintegrationfetchfinancials

IEX Test - Fetch Earnings


::

python -m unittest tests.testiexfetchdata.TestIEXFetchData.testintegrationfetchearnings

IEX Test - Fetch Dividends


::

python -m unittest tests.testiexfetchdata.TestIEXFetchData.testintegrationfetchdividends

IEX Test - Fetch Company


::

python -m unittest tests.testiexfetchdata.TestIEXFetchData.testintegrationfetchcompany

IEX Test - Fetch Financials Helper


::

python -m unittest tests.testiexfetchdata.TestIEXFetchData.testintegrationgetfinancials_helper

IEX Test - Extract Daily Dataset


::

python -m unittest tests.testiexdatasetextraction.TestIEXDatasetExtraction.testintegrationextractdaily_dataset

IEX Test - Extract Minute Dataset


::

python -m unittest tests.testiexdatasetextraction.TestIEXDatasetExtraction.testintegrationextractminute_dataset

IEX Test - Extract Quote Dataset


::

python -m unittest tests.testiexdatasetextraction.TestIEXDatasetExtraction.testintegrationextractquote_dataset

IEX Test - Extract Stats Dataset


::

python -m unittest tests.testiexdatasetextraction.TestIEXDatasetExtraction.testintegrationextractstats_dataset

IEX Test - Extract Peers Dataset


::

python -m unittest tests.testiexdatasetextraction.TestIEXDatasetExtraction.testintegrationextractpeers_dataset

IEX Test - Extract News Dataset


::

python -m unittest tests.testiexdatasetextraction.TestIEXDatasetExtraction.testintegrationextractnews_dataset

IEX Test - Extract Financials Dataset


::

python -m unittest tests.testiexdatasetextraction.TestIEXDatasetExtraction.testintegrationextractfinancials_dataset

IEX T


README truncated. View on GitHub
🔗 More in this category

© 2026 GitRepoTrend · AlgoTraders/stock-analysis-engine · Updated daily from GitHub