diff --git a/README.md b/README.md index 2859e5084..1abc5c2d6 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,13 @@ LiuAlgoTrader `quickstart` wizard installs samples allowing a first-time experie Additional samples can we found in the [examples](examples) directory. +## Analysis & Analytics + +The framework includes a wide ranges of analysis `Jupyter Notebooks`, as well as `streamlit` applications for analysis for both trading and back-testing sessions. To name a few of the visual analytical tools: +* tear-sheet analysis, +* anchored-vwaps, +* indicators & distributions + ## What's Next? Read the [documentation](https://liualgotrader.readthedocs.io/en/latest/) and learn how to use LiuAlgoTrader to develop, deploy & testing money making strategies. diff --git a/analysis/notebooks/anchored-vwap-lab.ipynb b/analysis/notebooks/anchored-vwap-lab.ipynb new file mode 100644 index 000000000..511e2e5a3 --- /dev/null +++ b/analysis/notebooks/anchored-vwap-lab.ipynb @@ -0,0 +1,232 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Select stock symbol and date range" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "symbol = 'AAPL'\n", + "start_date = \"2020-11-12\"\n", + "end_date = \"2020-11-12\"\n", + "anchored_vwaps_start = ['2020-11-12 11:00:00', '2020-11-12 14:00:00']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Imports" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# silence warnings\n", + "import warnings\n", + "import liualgotrader.analytics.analysis as ana\n", + "import matplotlib.pyplot as plt\n", + "import nest_asyncio\n", + "import numpy as np\n", + "import pandas as pd\n", + "import pytz\n", + "from empyrical import roll_max_drawdown\n", + "from scipy.stats import kurtosis, skew\n", + "import plotly.graph_objects as go\n", + "from plotly.subplots import make_subplots\n", + "import chart_studio.plotly as py\n", + "from datetime import datetime\n", + "import alpaca_trade_api as tradeapi\n", + "from liualgotrader.common.market_data import get_symbol_data\n", + "from liualgotrader.fincalcs.vwap import anchored_vwap\n", + "%matplotlib inline\n", + "warnings.filterwarnings(\"ignore\")\n", + "\n", + "\n", + "nest_asyncio.apply()\n", + "est = pytz.timezone(\"US/Eastern\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Load symbol data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "start_date = datetime.strptime(start_date, \"%Y-%m-%d\")\n", + "end_date = datetime.strptime(end_date, \"%Y-%m-%d\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "api = tradeapi.REST(base_url=\"https://api.alpaca.markets\")\n", + "ohlc_data = get_symbol_data(api, symbol, start_date, end_date)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if ohlc_data is None or ohlc_data.empty:\n", + " assert False, \"No data loaded\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Calculate indicators" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "anchored_vwap_starts = [\n", + " datetime.strptime(anchored_vwap_start, \"%Y-%m-%d %H:%M:%S\").replace(tzinfo=est)\n", + " for anchored_vwap_start in anchored_vwaps_start\n", + "]\n", + "anchored_vwap_indicators = [\n", + " anchored_vwap(ohlc_data, anchored_vwap_start)\n", + " for anchored_vwap_start in anchored_vwap_starts\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Visuals" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "trace1 = {\n", + " \"x\": ohlc_data.index,\n", + " \"open\": ohlc_data.open,\n", + " \"high\": ohlc_data.high,\n", + " \"low\": ohlc_data.low,\n", + " \"close\": ohlc_data.close,\n", + " \"type\": \"candlestick\",\n", + " \"name\": symbol,\n", + " \"yaxis\": \"y2\",\n", + " \"showlegend\": True,\n", + "}\n", + "trace2 = [{\n", + " \"x\": anchored_vwap_indicator.index,\n", + " \"y\": anchored_vwap_indicator,\n", + " \"type\": \"scatter\",\n", + " \"mode\": \"lines\",\n", + " \"line\": {\"width\": 2, \"color\": \"black\"},\n", + " \"yaxis\": \"y2\",\n", + " \"name\": f\"VWAP-{indx+1}\",\n", + " \"showlegend\": True,\n", + "} for indx, anchored_vwap_indicator in enumerate(anchored_vwap_indicators)]\n", + "fig = dict ( data = [trace1], layout = dict())\n", + "\n", + "fig['layout']['plot_bgcolor'] = 'rgb(200, 200, 200)'\n", + "fig['layout']['xaxis'] = dict( rangeselector = dict( visible = True ) )\n", + "fig['layout']['yaxis'] = dict( domain = [0, 0.2], showticklabels = False )\n", + "fig['layout']['yaxis2'] = dict( domain = [0.2, 0.8] )\n", + "fig['layout']['legend'] = dict( orientation = 'h', y=0.9, x=0.3, yanchor='bottom' )\n", + "fig['layout']['margin'] = dict( t=40, b=40, r=40, l=40 )\n", + "\n", + "rangeselector=dict(\n", + " #visibe = True,\n", + " x = 0, y = 0.9,\n", + " bgcolor = 'rgba(150, 200, 250, 0.4)',\n", + " font = dict( size = 13 ),\n", + " buttons=list([\n", + " dict(count=1,\n", + " label='1 yr',\n", + " step='year'),\n", + " dict(count=3,\n", + " label='3 mo',\n", + " step='month',\n", + " stepmode='backward'),\n", + " dict(count=1,\n", + " label='1 mo',\n", + " step='month',\n", + " stepmode='backward'),\n", + " dict(count=7,\n", + " label='1 wk',\n", + " step='day',\n", + " stepmode='backward'),\n", + " dict(step='all')\n", + " ]))\n", + " \n", + "fig['layout']['xaxis']['rangeselector'] = rangeselector\n", + "\n", + "fig['data'] += trace2\n", + "\n", + "colors = []\n", + "\n", + "for i in range(len(ohlc_data.close)):\n", + " if i != 0:\n", + " if ohlc_data.close[i] > ohlc_data.close[i-1]:\n", + " colors.append(\"green\")\n", + " else:\n", + " colors.append(\"red\")\n", + " else:\n", + " colors.append(\"red\")\n", + "\n", + "fig['data'].append( dict( x=ohlc_data.index, y=ohlc_data.volume, \n", + " marker=dict( color=colors ),\n", + " type='bar', yaxis='y', name='Volume' ) )\n", + "\n", + "f = go.Figure(data=fig['data'], layout=fig['layout'])\n", + "f.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/source/Analysis.rst b/docs/source/Analysis.rst index 5452a241a..f543200d7 100644 --- a/docs/source/Analysis.rst +++ b/docs/source/Analysis.rst @@ -5,7 +5,7 @@ Liu Analysis Tool-box for analysing portfolio, trader, and back-testing sessions. .. _notebooks: - https://github.com/amor71/LiuAlgoTrader/blob/master/analyis_notebooks/portfolio_performance_analysis.ipynb + https://github.com/amor71/LiuAlgoTrader/blob/master/analysis/notebooks/portfolio_performance_analysis.ipynb .. # define a hard line break for HTML .. |br| raw:: html @@ -18,14 +18,52 @@ prerequisites 1. Both `APCA_API_KEY_ID` and `APCA_API_SECRET_KEY` environment variables should be properly set and include the credentials to Alpaca Markets account (can be either PAPER or LIVE), 2. Environment variable `DSN` holds valid DB connection string, +Anchored-VWAP Notebook +---------------------- -Tear Sheet ----------- +The `anchored vwap`_ analysis notebook calculates and visualizes anchored vwaps on top of an interactive stock candlestick diagram, with volume . + +.. _anchored vwap: + https://github.com/amor71/LiuAlgoTrader/tree/master/analysis/notebooks/anchored-vwap-lab.ipynb + +prerequisites +************* +if you do not have `pyplot` installed: + +.. code-block:: bash + + pip install pyplot + +running the notebook +******************** + +once loaded, the top of the notebook looks like: + + +.. image:: /images/anchored-1.png + :width: 1000 + :align: left + :alt: anchored vwap top of notebook + + +The list `anchored_vwaps_start` holds start timestamps for anchored VWAPs, per `symbol` between the `start_date` and `end_date`. + +Once executed, the output generated includes an interactive candlestick diagram including the selected anchored VWAPs: + +.. image:: /images/anchored-2.png + :width: 1000 + :align: left + :alt: anchored vwaps example + + + +Tear Sheet Notebook +------------------- The `tear sheet`_ analysis notebook provide basic means to analyze your portfolio performance over time. .. _tear sheet: - https://github.com/amor71/LiuAlgoTrader/tree/master/analyis/notebooks/tear_sheet.ipynb + https://github.com/amor71/LiuAlgoTrader/tree/master/analysis/notebooks/tear_sheet.ipynb The top of the notebook looks like: @@ -137,7 +175,7 @@ Prerequisites 3. Download the latest version of backtester analysis notebook_. .. _notebook : - https://github.com/amor71/LiuAlgoTrader/blob/master/analyis_notebooks/backtest_performance_analysis.ipynb + https://github.com/amor71/LiuAlgoTrader/blob/master/analysis/notebooks/backtest_performance_analysis.ipynb Usage ***** diff --git a/docs/source/Quickstart.rst b/docs/source/Quickstart.rst index 60b0224b2..c80407709 100644 --- a/docs/source/Quickstart.rst +++ b/docs/source/Quickstart.rst @@ -50,7 +50,7 @@ if you follow the installation till the end, the wizard will direct you how to r .. code-block:: bash - streamlit run https://raw.github.com/amor71/LiuAlgoTrader/master/analyis/backtester_ui.py + streamlit run https://raw.github.com/amor71/LiuAlgoTrader/master/analysis/backtester_ui.py Once executed, your screen should look like this: @@ -63,8 +63,8 @@ Once executed, your screen should look like this: Select the `Analyzer` app on the upper-right drop-down and enter '2398380c-5146-4b58-843a-a50c458c8071' as a pre-loaded batch-id. -Voila! -^^^^^^ +`Voila!` +^^^^^^^^ You should be now seeing a pre-loaded session from your local database. You're all set now. diff --git a/docs/source/Usage.rst b/docs/source/Usage.rst index 90304fb5f..8ed534b48 100644 --- a/docs/source/Usage.rst +++ b/docs/source/Usage.rst @@ -253,7 +253,7 @@ To run the tool type: .. code-block:: bash - streamlit run https://raw.github.com/amor71/LiuAlgoTrader/master/analyis/backtester_ui.py + streamlit run https://raw.github.com/amor71/LiuAlgoTrader/master/analysis/backtester_ui.py Once the browser opens, it would look like: diff --git a/docs/source/What's New.rst b/docs/source/What's New.rst index b72261138..0e11f4472 100644 --- a/docs/source/What's New.rst +++ b/docs/source/What's New.rst @@ -4,6 +4,9 @@ What's New +------------------+----------------------------------------------+ | Release | Notes | +------------------+----------------------------------------------+ +| 0.0.76 | adding `anchored-vwap` calculation, and | +| | notebook w/ advanced visuals. | ++------------------+----------------------------------------------+ | 0.0.74 | 1. adding `symbol` and `duration` parameters | | | to `backtester`, updated documentation, | | | 2. clean-ups to back-testing notebook. | diff --git a/docs/source/images/anchored-1.png b/docs/source/images/anchored-1.png new file mode 100644 index 000000000..e627151dc Binary files /dev/null and b/docs/source/images/anchored-1.png differ diff --git a/docs/source/images/anchored-2.png b/docs/source/images/anchored-2.png new file mode 100644 index 000000000..3d2526c01 Binary files /dev/null and b/docs/source/images/anchored-2.png differ diff --git a/liualgotrader/__init__.py b/liualgotrader/__init__.py index 7715123d0..a981d1114 100644 --- a/liualgotrader/__init__.py +++ b/liualgotrader/__init__.py @@ -1 +1 @@ -__version__ = "0.0.75" +__version__ = "0.0.76" diff --git a/liualgotrader/liu b/liualgotrader/liu index 5805d4712..026447987 100644 --- a/liualgotrader/liu +++ b/liualgotrader/liu @@ -265,7 +265,7 @@ def quickstart(): print("2. run the env-vars script ('env_vars.bat'),") else: print("2. run the env-vars script ('source env_vars.sh'),") - print(f"3.`streamlit run https://raw.github.com/amor71/LiuAlgoTrader/master/analyis/backtester_ui.py`") + print(f"3.`streamlit run https://raw.github.com/amor71/LiuAlgoTrader/master/analysis/backtester_ui.py`") if restore_sample_db: print("4. On the app selection select the 'analyzer` app") print("5. copy and paste the batch-id '2398380c-5146-4b58-843a-a50c458c8071' and press ")