Skip to content

Instantly share code, notes, and snippets.

@yhilpisch
Last active December 6, 2024 08:03
Show Gist options
  • Select an option

  • Save yhilpisch/4ba8d5b3e17d8480e8a1d552c8b4567e to your computer and use it in GitHub Desktop.

Select an option

Save yhilpisch/4ba8d5b3e17d8480e8a1d552c8b4567e to your computer and use it in GitHub Desktop.

Executive Program in Algorithmic Trading (QuantInsti)

Python Sessions by Dr. Yves J. Hilpisch | The Python Quants GmbH

Online, 08. & 09. December 2018

Python for Finance (2nd ed.)

Sign up under http://py4fi.pqp.io to access all the Jupyter Notebooks and codes and execute them on our Quant Platform.

Short Link

http://bit.ly/epat_dec_2018

Resources

Slides & Materials

You find the introduction slides under http://hilpisch.com/epat.pdf

You find the materials about OOP under http://hilpisch.com/py4fi_oop_epat.html

Python

If you have either Miniconda or Anaconda already installed, there is no need to install anything new.

The code that follows uses Python 3.6. For example, download and install Miniconda 3.6 from https://conda.io/miniconda.html if you do not have conda already installed.

In any case, for Linux/Mac you should execute the following lines on the shell to create a new environment with the needed packages:

conda create -n epat python=3.6
source activate epat
conda install numpy pandas matplotlib statsmodels
pip install plotly==2.4.0 cufflinks
conda install ipython jupyter
jupyter notebook

On Windows, execute the following lines on the Anaconda prompt:

conda create -n epat python=3.6
activate epat
conda install numpy pandas matplotlib statsmodels
pip install plotly==2.4.0 cufflinks
pip install win-unicode-console
set PYTHONIOENCODING=UTF-8
conda install ipython jupyter
jupyter notebook

Read more about the management of environments under https://conda.io/docs/using/envs.html

Docker

To install Docker see https://docs.docker.com/install/.

To run a Ubuntu-based Docker container, execute on the shell the following:

docker run -ti -p 9000:9000 -h epat -v /Users/yves/Temp/:/root/tmp ubuntu:latest /bin/bash

Make sure to adjust the folder to be mounted accordingly.

ZeroMQ

The major resource for the ZeroMQ distributed messaging package based on sockets is http://zeromq.org/

Cloud

Use this link to get a 10 USD bonus on DigitalOcean when signing up for a new account.

Books & Resources

An overview of the Python Data Model is found under: Python Data Model

Good book about everything important in Python data analysis: Python Data Science Handbook, O'Reilly

Good book covering object-oriented programming in Python: Fluent Python, O'Reilly

Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"http://hilpisch.com/tpq_logo.png\" alt=\"The Python Quants\" width=\"35%\" align=\"right\" border=\"0\"><br>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# EPAT Session 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Executive Program in Algorithmic Trading**\n",
"\n",
"**_Vectorized Backtesting & Object Oriented Programming_**\n",
"\n",
"Dr. Yves J. Hilpisch | The Python Quants GmbH | http://tpq.io\n",
"\n",
"<img src=\"http://hilpisch.com/images/tpq_bootcamp.png\" width=\"350px\" align=\"left\">"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Basic Imports"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"from pylab import plt\n",
"plt.style.use('seaborn')\n",
"%matplotlib inline\n",
"pd.set_option('mode.chained_assignment', None)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Reading Financial Data"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"url = 'http://hilpisch.com/tr_eikon_eod_data.csv'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"raw = pd.read_csv(url, index_col=0, parse_dates=True).dropna()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"raw.head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"raw.info()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"raw.tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"raw.describe().round(4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"(raw / raw.iloc[0]).plot(figsize=(10, 6));"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Trading Strategy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"symbol = 'AAPL.O'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data = pd.DataFrame(raw[symbol])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.plot(figsize=(10, 6));"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data['SMA1'] = data[symbol].rolling(42).mean()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data['SMA2'] = data[symbol].rolling(252).mean()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.plot(figsize=(10, 6));"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.dropna(inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# data['Position'] = np.where(data['SMA1'] > data['SMA2'], 'long', 'short')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data['Position'] = np.where(data['SMA1'] > data['SMA2'], 1, -1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.plot(figsize=(10, 6), secondary_y='Position');"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sum(data['Position'].diff() != 0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Vectorized Backtesting"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data['Returns'] = np.log(data[symbol] / data[symbol].shift(1))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.dropna(inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data['Strategy'] = data['Position'].shift(1) * data['Returns']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.dropna(inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data[['Returns', 'Strategy']].sum() # simple sum of log returns"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.exp(data[['Returns', 'Strategy']].sum()) # gross performance of the stock & strategy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.exp(data[['Returns', 'Strategy']].sum()) - 1 # net performance of the stock & strategy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data[['Returns', 'Strategy']].cumsum().apply(np.exp).plot(figsize=(10, 6));"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ax = data[['Returns', 'Strategy']].cumsum().apply(np.exp).plot(figsize=(10, 6))\n",
"data['Position'].plot(ax=ax, secondary_y='Position');"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.arange(10)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a.cumsum()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Momentum Strategy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"symbol = 'GLD'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data = pd.DataFrame(raw[symbol])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data['Returns'] = np.log(data[symbol] / data[symbol].shift(1))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.dropna(inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"momentum = 3"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data['Momentum'] = data['Returns'].rolling(momentum).mean()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.head(8)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.dropna(inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data['Position'] = np.sign(data['Momentum'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data['Strategy'] = data['Position'].shift(1) * data['Returns']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data.dropna(inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data[['Returns', 'Strategy']].cumsum().apply(np.exp).plot(figsize=(10, 6));"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sum(data['Position'].diff() != 0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Financial Data Class"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# url = 'http://hilpisch.com/tr_eikon_eod_data.csv'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# raw = pd.read_csv(url, index_col=0, parse_dates=True).dropna()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"n = 3"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def f(x):\n",
" y = x ** n # y local variable, n global variable\n",
" return y"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"f(5)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# y # local variable not accessible"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class SimpleClass:\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sc = SimpleClass()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sc.attribute = 'my value and text' # data attribute"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sc.attribute"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class FinancialData:\n",
" url = 'http://hilpisch.com/tr_eikon_eod_data.csv'\n",
" def __init__(self, symbol):\n",
" self.symbol = symbol\n",
" self.retrieve_data()\n",
" self.prepare_data()\n",
" def retrieve_data(self):\n",
" self.raw = pd.read_csv(self.url, index_col=0,\n",
" parse_dates=True).dropna()\n",
" def prepare_data(self):\n",
" self.data = pd.DataFrame(self.raw[self.symbol])\n",
" self.data['Returns'] = np.log(self.data / self.data.shift(1))\n",
" self.data.dropna(inplace=True)\n",
" def plot_data(self, cols=None, subplots=False):\n",
" if cols is None:\n",
" cols = [self.symbol]\n",
" self.data[cols].plot(figsize=(10, 6), subplots=subplots)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# instantiation\n",
"fd = FinancialData('SPY')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fd.url # class attribute"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fd.symbol # instance attribute"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fd.raw.head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fd.data.head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fd.data.plot(subplots=True, figsize=(10, 6));"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fd.plot_data()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fd.plot_data([fd.symbol, 'Returns'], subplots=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Class for SMA Backtesting"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class FinancialData:\n",
" url = 'http://hilpisch.com/tr_eikon_eod_data.csv'\n",
" def __init__(self, symbol):\n",
" self.symbol = symbol\n",
" self.retrieve_data()\n",
" self.prepare_data()\n",
" def retrieve_data(self):\n",
" self.raw = pd.read_csv(self.url, index_col=0,\n",
" parse_dates=True).dropna()\n",
" def prepare_data(self):\n",
" self.data = pd.DataFrame(self.raw[self.symbol])\n",
" self.data['Returns'] = np.log(self.data / self.data.shift(1))\n",
" self.data.dropna(inplace=True)\n",
" def plot_data(self, cols=None, subplots=False):\n",
" if cols is None:\n",
" cols = [self.symbol]\n",
" self.data[cols].plot(figsize=(10, 6), subplots=subplots)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class SMABacktester(FinancialData):\n",
" def __init__(self, symbol, SMA1, SMA2):\n",
" super(SMABacktester, self).__init__(symbol)\n",
" self.SMA1 = SMA1\n",
" self.SMA2 = SMA2\n",
" def run_strategy(self):\n",
" self.results = self.data.copy()\n",
" self.results['SMA1'] = self.results[self.symbol].rolling(self.SMA1).mean()\n",
" self.results['SMA2'] = self.results[self.symbol].rolling(self.SMA2).mean()\n",
" self.results.dropna(inplace=True)\n",
" self.results['Position'] = np.where(self.results['SMA1'] > self.results['SMA2'], 1, -1)\n",
" self.results['Strategy'] = self.results['Position'].shift(1) * self.results['Returns']\n",
" self.results.dropna(inplace=True)\n",
" return self.results[['Returns', 'Strategy']].sum().apply(np.exp)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma = SMABacktester('AAPL.O', 42, 252)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma.symbol"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# sma.plot_data()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma.run_strategy()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# sma.results.info()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma_list = [(42, 252), (30, 252), (30, 180), (42, 180)]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma_list"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for SMA1, SMA2 in sma_list:\n",
" print('\\nBACKTEST FOR: SMA1={} | SMA2={}'.format(SMA1, SMA2))\n",
" print(50 * '=')\n",
" sma = SMABacktester('AAPL.O', SMA1, SMA2)\n",
" res = sma.run_strategy()\n",
" print(res)\n",
" print(50 * '=')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Optimization\n",
"\n",
"... of the code (to some extent) and of the strategy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class SMABacktester(FinancialData):\n",
" #def __init__(self, symbol):\n",
" # super(SMABacktester, self).__init__(symbol)\n",
" \n",
" def run_strategy(self, SMA1, SMA2):\n",
" self.SMA1 = SMA1\n",
" self.SMA2 = SMA2\n",
" self.results = self.data.copy()\n",
" self.results['SMA1'] = self.results[self.symbol].rolling(self.SMA1).mean()\n",
" self.results['SMA2'] = self.results[self.symbol].rolling(self.SMA2).mean()\n",
" self.results.dropna(inplace=True)\n",
" self.results['Position'] = np.where(self.results['SMA1'] > self.results['SMA2'], 1, -1)\n",
" self.results['Strategy'] = self.results['Position'].shift(1) * self.results['Returns']\n",
" self.results.dropna(inplace=True)\n",
" return self.results[['Returns', 'Strategy']].sum().apply(np.exp)\n",
" def plot_results(self):\n",
" self.results[['Returns', 'Strategy']].cumsum().apply(np.exp).plot(\n",
" figsize=(10, 6), title='{} | SMA1={} | SMA2={}'.format(\n",
" self.symbol, self.SMA1, self.SMA2))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma = SMABacktester('AAPL.O')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma.run_strategy(42, 180)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma.plot_results()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from itertools import product"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma1 = [30, 42]\n",
"sma2 = [180, 252]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for SMA1, SMA2 in product(sma1, sma2):\n",
" print(SMA1, SMA2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"for SMA1, SMA2 in product(sma1, sma2):\n",
" print('\\nBACKTEST FOR: SMA1={} | SMA2={}'.format(SMA1, SMA2))\n",
" print(50 * '=')\n",
" sma = SMABacktester('AAPL.O')\n",
" res = sma.run_strategy(SMA1, SMA2)\n",
" # sma.plot_results()\n",
" print(res)\n",
" print(50 * '=')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Improved Version"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class SMABacktester(SMABacktester):\n",
" def backtest_program(self, sma1, sma2):\n",
" self.program = pd.DataFrame()\n",
" for SMA1, SMA2 in product(sma1, sma2):\n",
" res = self.run_strategy(SMA1, SMA2)\n",
" self.program = self.program.append(\n",
" pd.DataFrame({'SMA1': SMA1, 'SMA2': SMA2,\n",
" 'Benchmark': res['Returns'],\n",
" 'Strategy': res['Strategy'],\n",
" 'Outperf': res['Strategy'] - res['Returns']},\n",
" index = [0]), ignore_index=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma = SMABacktester('AAPL.O')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma.run_strategy(42, 252)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma1 = range(20, 61, 1)\n",
"#list(sma1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma2 = range(150, 301, 1)\n",
"#list(sma2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%time sma.backtest_program(sma1, sma2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma.program.info()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sma.program.sort_values('Strategy', ascending=False).head(10)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for sym in ['AAPL.O', 'MSFT.O', 'SPY']:\n",
" print('\\nTESTING FOR {}'.format(sym))\n",
" sma = SMABacktester(sym)\n",
" sma.backtest_program(sma1, sma2)\n",
" print(sma.program.sort_values('Strategy', ascending=False).head())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"http://hilpisch.com/tpq_logo.png\" alt=\"The Python Quants\" width=\"35%\" align=\"right\" border=\"0\"><br>"
]
}
],
"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.6.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
#
# Simple Tick Data Client
#
import zmq
import datetime
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect('tcp://127.0.0.1:5555')
socket.setsockopt_string(zmq.SUBSCRIBE, 'AAPL')
while True:
msg = socket.recv_string()
t = datetime.datetime.now()
print(str(t.time()) + ' | ' + msg)
#
# Simple Tick Data Collector
#
import zmq
import datetime
import pandas as pd
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect('tcp://127.0.0.1:5555')
socket.setsockopt_string(zmq.SUBSCRIBE, 'AAPL')
raw = pd.DataFrame()
while True:
msg = socket.recv_string()
tr = datetime.datetime.now()
print(str(tr.time()) + ' | ' + msg)
sym, price, ts = msg.split()
raw = raw.append(pd.DataFrame(
{'ts': pd.Timestamp(ts),
'sym': sym, 'price': float(price)},
index=[tr,]))
#
# Simple Tick Data Server
#
import zmq
import time
import random
import datetime
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind('tcp://127.0.0.1:5555')
AAPL = 100.
while True:
AAPL += random.gauss(0, 1) * 0.5
t = datetime.datetime.now()
msg = 'AAPL {:.3f} {}'.format(AAPL, t.time())
socket.send_string(msg)
print(msg)
time.sleep(random.random() * 2)
#
# Simple Tick Data Collector
#
import zmq
import datetime
import pandas as pd
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect('tcp://127.0.0.1:5555')
socket.setsockopt_string(zmq.SUBSCRIBE, 'AAPL')
raw = pd.DataFrame()
SMA1 = 3
SMA2 = 6
min_length = SMA2 + 1
position = 0
while True:
msg = socket.recv_string()
tr = datetime.datetime.now()
print(str(tr.time()) + ' | ' + msg)
sym, price, ts = msg.split()
raw = raw.append(pd.DataFrame(
{'ts': pd.Timestamp(ts),
'sym': sym, 'price': float(price)},
index=[tr,]))
data = raw.resample('5s', label='right').last().ffill()
if len(data) > min_length:
min_length += 1
data['SMA1'] = data['price'].rolling(SMA1).mean()
data['SMA2'] = data['price'].rolling(SMA2).mean()
if data['SMA1'].iloc[-2] > data['SMA2'].iloc[-2]:
print('\n**** GOING/STAYING LONG ****')
elif data['SMA1'].iloc[-2] < data['SMA2'].iloc[-2]:
print('\n**** GOING/STAYING SHORT ****')
print(data[['SMA1', 'SMA2']].tail(), '\n\n')
gist -u 4ba8d5b3e17d8480e8a1d552c8b4567e *
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment