Skip to content

Instantly share code, notes, and snippets.

@yhilpisch
Last active May 5, 2023 20:25
Show Gist options
  • Save yhilpisch/8f26f0af4f9a150cef15993020dad202 to your computer and use it in GitHub Desktop.
Save yhilpisch/8f26f0af4f9a150cef15993020dad202 to your computer and use it in GitHub Desktop.

Algorithmic Trading

In Less Than 100 Lines of Python Code

Dr. Yves J. Hilpisch | The Python Quants GmbH

Online, April 2021

(short link to this Gist: http://bit.ly/algo_100_lecture)

Article & Slides

You find the article under http://bit.ly/100_algo

You find the slides under http://certificate.tpq.io/algo_100_lecture.pdf

Resources

This Gist contains selected resources used during the webinar.

Dislaimer

All the content, Python code, Jupyter Notebooks and other materials (the “Material”) come without warranties or representations, to the extent permitted by applicable law.

None of the Material represents any kind of recommendation or investment advice.

The Material is only meant as a technical illustration.

Leveraged and unleveraged trading of financial instruments, and of contracts for difference (CFDs) in particular, involves a number of risks (for example, losses in excess of deposits). Make sure to understand and manage these risks.

Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src='http://hilpisch.com/taim_logo.png' width=\"350px\" align=\"right\">"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Algorithmic Trading\n",
"\n",
"**In Less Than 100 Lines of Code**"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Dr Yves J Hilpisch | The AI Machine\n",
"\n",
"http://aimachine.io | http://twitter.com/dyjh"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The Article\n",
"\n",
"You find the Medium article under http://bit.ly/100_algo"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Oanda API "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import tpqoa\n",
"oanda = tpqoa.tpqoa('../oanda.cfg')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The Data "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data = oanda.get_history(\n",
" instrument='EUR_USD',\n",
" start='2021-04-20',\n",
" end='2021-04-21',\n",
" granularity='M1',\n",
" price='M'\n",
")\n",
"data.info()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The Strategy "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"data['r'] = np.log(data['c'] / data['c'].shift(1)) \n",
"cols = []\n",
"for momentum in [15, 30, 60, 120, 150]:\n",
" col = f'p_{momentum}'\n",
" data[col] = np.sign(data['r'].rolling(momentum).mean())\n",
" cols.append(col)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pylab import plt\n",
"plt.style.use('seaborn')\n",
"strats = ['r']\n",
"for col in cols:\n",
" strat = f's_{col[2:]}' \n",
" data[strat] = data[col].shift(1) * data['r']\n",
" strats.append(strat)\n",
"data[strats].dropna().cumsum().apply(np.exp).plot(cmap='coolwarm');"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Trading Code"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"oanda.on_success??"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"oanda.stream_data('BTC_USD', stop=10) # streaming data"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"oanda.create_order('EUR_USD', units=10) # opening long position"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"oanda.create_order('EUR_USD', units=-10) # closing long position"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"class MomentumTrader(tpqoa.tpqoa):\n",
" def __init__(self, config_file, momentum):\n",
" super(MomentumTrader, self).__init__(config_file)\n",
" self.momentum = momentum\n",
" self.min_length = momentum + 1\n",
" self.position = 0\n",
" self.units = 10000\n",
" self.tick_data = pd.DataFrame()\n",
" def on_success(self, time, bid, ask):\n",
" trade = False\n",
" print(self.ticks, end=' ')\n",
" self.tick_data = self.tick_data.append(\n",
" pd.DataFrame({'b': bid, 'a': ask, 'm': (ask + bid) / 2},\n",
" index=[pd.Timestamp(time).tz_localize(tz=None)])\n",
" )\n",
" self.data = self.tick_data.resample('5s', label='right').last().ffill()\n",
" self.data['r'] = np.log(self.data['m'] / self.data['m'].shift(1))\n",
" self.data['m'] = self.data['r'].rolling(self.momentum).mean()\n",
" self.data.dropna(inplace=True)\n",
" if len(self.data) > self.min_length:\n",
" self.min_length += 1\n",
" if self.data['m'].iloc[-2] > 0 and self.position in [0, -1]:\n",
" o = oanda.create_order(self.stream_instrument,\n",
" units=(1 - self.position) * self.units,\n",
" suppress=True, ret=True)\n",
" print('\\n*** GOING LONG ***')\n",
" self.print_transactions(tid=int(o['id']) - 1)\n",
" self.position = 1\n",
" if self.data['m'].iloc[-2] < 0 and self.position in [0, 1]:\n",
" o = oanda.create_order(self.stream_instrument,\n",
" units=-(1 + self.position) * self.units,\n",
" suppress=True, ret=True)\n",
" print('\\n*** GOING SHORT ***')\n",
" self.print_transactions(tid=int(o['id']) - 1)\n",
" self.position = -1 "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mt = MomentumTrader('../oanda.cfg', momentum=5)\n",
"mt.stream_data('EUR_USD', stop=200)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pprint import pprint\n",
"o = mt.create_order('EUR_USD', units=-mt.position * mt.units,\n",
" suppress=True, ret = True)\n",
"print('\\n*** POSITION CLOSED ***')\n",
"mt.print_transactions(tid=int(o['id']) - 1)\n",
"print('\\n')\n",
"pprint(o)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src='http://hilpisch.com/taim_logo.png' width=\"350px\" align=\"right\">"
]
}
],
"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.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
[oanda]
access_token = c71f59_YOURACCESSTOKEN_13da5b8f60fac1397232
account_id = 101-004-YOURID-001
account_type = practice
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment