python-pour-finance/10-Plateforme-Quantopian/03-Premier-Algorithme-Tradi...

541 lines
298 KiB
Plaintext
Raw Permalink Normal View History

2023-08-21 15:12:19 +00:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Premier Algorithme de Trading\n",
"## Trading de Paires\n",
"\n",
"Le trading de paires est une stratégie qui utilise deux actions qui sont fortement corrélées. Nous pouvons alors utiliser la différence de prix entre les deux actions comme signal si l'une d'entre elles sort de la corrélation avec l'autre. Il s'agit d'une stratégie plus ancienne qui est utilisée classiquement comme guide pour commencer le trading algorithmique. Il existe un guide complet fantastique et vous pouvez le trouvez sur Investopedia [ici](http://www.investopedia.com/university/guide-pairs-trading/)! **Je vous recommande vivement de lire l'article dans son intégralité avant de continuer, il est divertissant et instructif !**\n",
"\n",
"\n",
"Créons notre premier algorithme de Trading base ! Il s'agit d'un exercice d'utilisation de l'algorithme quantique, **PAS** d'une représentation réaliste de ce qu'est un bon algorithme ! N'utilisez jamais quelque chose d'aussi simple que cela dans le monde réel ! Il s'agit d'une version extrêmement simplifiée du Trading de paires, nous ne prendrons pas en compte des facteurs tels que la co-intégration !"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## United Airlines et American Airlines"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"start = '07-01-2015'\n",
"end = '07-01-2017'"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# en local\n",
"# united = quandl.get('WIKI/UAL',start_date=start,end_date=end)\n",
"# american = quandl.get('WIKI/AAL',start_date=start,end_date=end)\n",
"\n",
"united = get_pricing('UAL',start_date=start,end_date=end)\n",
"american = get_pricing('AAL',start_date=start,end_date=end)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open_price</th>\n",
" <th>high</th>\n",
" <th>low</th>\n",
" <th>close_price</th>\n",
" <th>volume</th>\n",
" <th>price</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2015-07-01 00:00:00+00:00</th>\n",
" <td>54.05</td>\n",
" <td>54.14</td>\n",
" <td>50.10</td>\n",
" <td>51.69</td>\n",
" <td>12129258.0</td>\n",
" <td>51.69</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2015-07-02 00:00:00+00:00</th>\n",
" <td>51.88</td>\n",
" <td>52.51</td>\n",
" <td>50.98</td>\n",
" <td>51.48</td>\n",
" <td>4551677.0</td>\n",
" <td>51.48</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2015-07-06 00:00:00+00:00</th>\n",
" <td>52.05</td>\n",
" <td>53.95</td>\n",
" <td>52.05</td>\n",
" <td>53.80</td>\n",
" <td>5458762.0</td>\n",
" <td>53.80</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2015-07-07 00:00:00+00:00</th>\n",
" <td>53.99</td>\n",
" <td>54.49</td>\n",
" <td>52.54</td>\n",
" <td>54.25</td>\n",
" <td>5373987.0</td>\n",
" <td>54.25</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2015-07-08 00:00:00+00:00</th>\n",
" <td>53.44</td>\n",
" <td>53.72</td>\n",
" <td>52.25</td>\n",
" <td>52.82</td>\n",
" <td>4050933.0</td>\n",
" <td>52.82</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open_price high low close_price volume \\\n",
"2015-07-01 00:00:00+00:00 54.05 54.14 50.10 51.69 12129258.0 \n",
"2015-07-02 00:00:00+00:00 51.88 52.51 50.98 51.48 4551677.0 \n",
"2015-07-06 00:00:00+00:00 52.05 53.95 52.05 53.80 5458762.0 \n",
"2015-07-07 00:00:00+00:00 53.99 54.49 52.54 54.25 5373987.0 \n",
"2015-07-08 00:00:00+00:00 53.44 53.72 52.25 52.82 4050933.0 \n",
"\n",
" price \n",
"2015-07-01 00:00:00+00:00 51.69 \n",
"2015-07-02 00:00:00+00:00 51.48 \n",
"2015-07-06 00:00:00+00:00 53.80 \n",
"2015-07-07 00:00:00+00:00 54.25 \n",
"2015-07-08 00:00:00+00:00 52.82 "
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"united.head()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open_price</th>\n",
" <th>high</th>\n",
" <th>low</th>\n",
" <th>close_price</th>\n",
" <th>volume</th>\n",
" <th>price</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2015-07-01 00:00:00+00:00</th>\n",
" <td>39.846</td>\n",
" <td>40.091</td>\n",
" <td>37.052</td>\n",
" <td>38.023</td>\n",
" <td>23439886.0</td>\n",
" <td>38.023</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2015-07-02 00:00:00+00:00</th>\n",
" <td>38.248</td>\n",
" <td>39.018</td>\n",
" <td>37.640</td>\n",
" <td>38.253</td>\n",
" <td>10226556.0</td>\n",
" <td>38.253</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2015-07-06 00:00:00+00:00</th>\n",
" <td>38.317</td>\n",
" <td>39.209</td>\n",
" <td>38.307</td>\n",
" <td>38.934</td>\n",
" <td>8025562.0</td>\n",
" <td>38.934</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2015-07-07 00:00:00+00:00</th>\n",
" <td>39.140</td>\n",
" <td>39.934</td>\n",
" <td>38.483</td>\n",
" <td>39.865</td>\n",
" <td>9341995.0</td>\n",
" <td>39.865</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2015-07-08 00:00:00+00:00</th>\n",
" <td>39.503</td>\n",
" <td>39.513</td>\n",
" <td>38.366</td>\n",
" <td>38.542</td>\n",
" <td>9976525.0</td>\n",
" <td>38.542</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open_price high low close_price \\\n",
"2015-07-01 00:00:00+00:00 39.846 40.091 37.052 38.023 \n",
"2015-07-02 00:00:00+00:00 38.248 39.018 37.640 38.253 \n",
"2015-07-06 00:00:00+00:00 38.317 39.209 38.307 38.934 \n",
"2015-07-07 00:00:00+00:00 39.140 39.934 38.483 39.865 \n",
"2015-07-08 00:00:00+00:00 39.503 39.513 38.366 38.542 \n",
"\n",
" volume price \n",
"2015-07-01 00:00:00+00:00 23439886.0 38.023 \n",
"2015-07-02 00:00:00+00:00 10226556.0 38.253 \n",
"2015-07-06 00:00:00+00:00 8025562.0 38.934 \n",
"2015-07-07 00:00:00+00:00 9341995.0 39.865 \n",
"2015-07-08 00:00:00+00:00 9976525.0 38.542 "
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"american.head()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x7f5c657cdd68>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAtEAAAHKCAYAAADFMBfCAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XlglPW1//H3TCaZyb4nkBAgLGEJ+yIqAq5otVatWm0R\n9V7b3t7itdVfN1vRarWt2t6qV21rLVr32qqoqLiCsshiWGQxECCBEEL2PTOTmcz8/pjMJEMSSMhk\nEobP658mzzzzPCdP1J45Od/zNbjdbjciIiIiItJjxoEOQERERETkVKMkWkRERESkl5REi4iIiIj0\nkpJoEREREZFeUhItIiIiItJLSqJFRERERHrJFMybud1u7rnnHvbu3UtERAT33nsvkZGR/PSnP8Xt\ndpOamspDDz1EeHh4MMMSEREREemVoCbRH3/8MY2NjbzyyisUFxfzwAMPkJiYyOLFi1m4cCEPP/ww\nr732Gtdff30wwxIRERER6ZWgtnMUFRUxZcoUALKysigpKWHz5s2cd955AFxwwQWsX78+mCGJiIiI\niPRaUJPonJwc1qxZg8vl4sCBAxw+fJiSkhJf+0ZqaioVFRXBDElEREREpNeC2s4xf/58tm7dyg03\n3MC4ceMYNWoUBQUFvtfdbjcGg+GE18nLy+vPMEVEREREfGbOnNnpWFCTaIAf/ehHvq8vuugi0tPT\naWlpISIigrKyMlJTU3t0na5+GDk5eXl5ep4BpmcaOHqWgaXnGVh6noGnZxoYeo6B013xNqjtHPn5\n+fzyl78E4LPPPiM3N5ezzjqLlStXAvD+++8zb968YIYkIiIiItJrQa1Ejxs3DrfbzfXXX09cXBy/\n//3vaW1t5ec//zmvvvoqGRkZXHXVVcEMSURERESk14KaRBsMBn73u991Or5s2bJghiEiIiISMG63\nG7vdPtBhdGKz2QY6hFOO2Wzu0fo80I6FIiIiIn1it9sHXRKdm5s70CGccnr7ewz6wkIRERGRUGM2\nm7FYLAMdhgSRKtEiIiIiIr2kJFpEREREpJeURIuIiIiI9JKSaBEREZEQ8fbbbzNp0iRqa2sDet2n\nnnqK7du3B/SaXkuXLu004njJkiWdznv88cd58cUXyc/P5/HHH++XWHpDCwtFREREQsQ777zD8OHD\nef/997nuuusCdt3vf//7AbtWR06nk9WrV2M2myksLCQ7OxuAJ554otv3jB8/nvHjx/dLPL2hJFpE\nREQkBNTV1bFjxw5++9vf8vTTT/uS6MWLFzNnzhzWr1+P0Wjkyiuv5I033iAsLIx//OMfNDc3c+ed\nd9LQ0IDT6WTp0qXk5ORw8cUXs2DBApKSkjh48CCXXHIJc+fO5ec//zlHjhzBYrHw4IMPEhUVxU9+\n8hOsVis2m4277rqLyZMns3DhQq677jpWrVqFw+HgmWeeISoqyi9m7w7W48eP55133uHWW28F4Mwz\nz2TDhg0sXryYnJwcDAYDCQkJAGzatIkXXniBxx57jIULF3LhhReyZcsW4uLieOqpp2hqaury53nq\nqaf46KOPMBqNnH/++X3+YKAkWkRERCSAlr29i3XbSwJ6zblTM/nPy48/+/m9997j/PPPZ968eSxd\nupTy8nLS0tIASE9P56WXXuLb3/429fX1vPjii9xwww3s2bOHTz75hPnz53PNNdewf/9+HnjgAZYt\nW4bD4WDBggXMnTuXO++8E4A33niDtLQ0/vjHP/Luu+/yySefcNZZZ3HttddywQUXsGHDBv72t7/x\n2GOP4XQ6GTNmDLfccgt33HEHn3/+ORdccIFfzCtWrOCyyy5jwoQJ3Hrrrb4kuuOGJzk5OVx33XV+\nLRze14uLi7nqqqv42c9+xvXXX09+fn63P88zzzzDunXrMBqNvPLKK33+nSiJFhEREQkBK1asYMmS\nJRiNRhYuXMh7773HTTfdBMDkyZMBSE1NZcKECQAkJSXR2NjI1q1bqamp4c033wSgpaXFd03v+7x2\n797N2WefDcCll14KQGNjI0888QR///vfaWlp8as2z5w5E/Ak8Q0NDX7XslqtrF+/nvvvv5+oqCgi\nIiLIz8/v1KoxZcqUbn/mmJgYxo4d67vH8X6eSy65hJtuuonLL7+cr3/968d/mD2gJFpEREQkgP7z\n8twTVo0D7ejRo3z55Zc8+OCDgGfL77i4OF8SbTK1p3wdv3a5XERERLB06VKmTp3a6brh4eF+34eF\nheFyufyOPfvsswwZMoSHHnqInTt38tBDD/md350PP/wQl8vFokWLcLvd1NbWsmLFik5J9LExHBuP\nl9vtPu7Pc88991BYWMi7777L4sWLee211zAaT37GhqZziIiIiJziVqxYwaJFi1i+fDnLly9n5cqV\n1NXVUVxcfNz3GQwGpk6dyocffgjAvn37ePbZZ7s9f/LkyWzYsAGA1atX89e//pXa2lqysrIAT2Ls\ncDh6HPPDDz/MG2+8wfLly3n55ZdZuXIl4EmIT0Z3P4+3Wp6dnc2SJUtITEyksbHxpO7hpSRaRERE\n5BT37rvvcvXVV/sdu/LKK3nnnXf8+ou7+nrRokUcOnSIRYsWsXTpUmbPnt3pXK9LL72U5uZmFi9e\nzD/+8Q+uuuoqrrjiCp555hluueUWpk2bRmVlJa+//nq39wWora2loKCAefPm+Y5lZmaSlZXFli1b\nfOd3FUNHPf15YmJiqKmp4dprr+Xmm29m6tSpxMXFHffaJ2Jwn2yqP4Dy8vJ8PTbSd3qegadnGjh6\nloGl5xlYep6Bdyo+U5vNBoDFYhngSKQvuvs9dvfPpCrRIiIiIiK9pCRaRERERKSXlESLiIiIiPSS\nkmgRERERkV5SEi0iIiIi0ktKokVEREREeklJtIiIiMgpbtOmTdx2221+xx5//HFefPHFbt/z1FNP\nsX37dgA++OCDHt/rwQcfZPny5V2+tnTpUq666iq/Y0uWLOl0nje2/Px8Hn/88R7fezDRtt8iIiIi\nIeBEG5Mc6/vf/z4Ahw8fZsWKFSxcuLBP93c6naxevRqz2UxhYSHZ2dkAPPHEE92+Z/z48Z22+T5V\nKIkWERERCWElJSX84he/ICsri/z8fHJzc/nNb37DnXfeycUXX8zLL7/Mjh07ePLJJ7npppu48847\naWhowOl0snTpUnJycnjzzTf5+9//zsiRI3G73YwbN67TfT777DNyc3MZP34877zzDrfeeisAZ555\nJhs2bGDx4sXk5ORgMBhISEgAPBX0F154gccee4yFCxdy4YUXsmXLFuLi4njqqadoamrqMp6nnnqK\njz76CKPRyPnnn+/7QBBMSqJFREREAuj5ba+xoXhLQK95ZtYMFk+7+sQndmPXrl08+uijJCYmsmDB\nAhobGwFP9fqWW27hxRdf5Ic//CFPPvkk8+fP55prrmH//v088MADLFu2jEceeYTXX3+d2NhYvvnN\nb3Z5jxUrVnDZZZcxYcIEbr31Vl8S3bFCnpOTw3XXXefXwuF9vbi4mKuuuoqf/exnXH/99eTn5/PJ\nJ590Gc8zzzzDunXrMBqNvPLKKyf9XPpCSbSIiIhIiPImqCNGjCApKQmAtLQ0Ghoaujx/69at1NTU\n8OabbwLQ0tJCTU0NMTExJCYmAjBjxoxO77Naraxfv57777+fqKgoIiIiyM/P79SqMWXKlG5jjYmJ\nYezYsQCkp6fT2NjYZTwAl1xyCTfddBOXX345X//613v8PAJJSbSIiIhIAC2ednWfqsYnIykpifr6\ner9j1dXVviQ2LCzM7zW3293ldcLDw1m6dClTp071u05HLper0/s+/PBDXC4XixYtwu12U1tby4oV\nKzol0eHh4d3+DB1jdLvduFwuIiIiOsUDcM8991BYWMi7777L4sWLee211zAagzsvQ9M5RERERE5x\nI0eOpKysjOLiYsCT+G7cuNFXNe6YNB+bQBuNRux2OwBTp07lww8/BGDfvn08++yzJCYm0tTURGNj\nIw6Hg61bt3a6/4oVK3j
"text/plain": [
"<matplotlib.figure.Figure at 0x7f5c66da4278>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# american['Adj. Close'].plot(label='American Airlines',figsize=(12,8))\n",
"# united['Adj. Close'].plot(label='United Airlines')\n",
"american['close_price'].plot(label='American Airlines',figsize=(12,8))\n",
"united['close_price'].plot(label='United Airlines')\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Dispersion et Corrélation"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 1. , 0.91653673],\n",
" [ 0.91653673, 1. ]])"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# np.corrcoef(american['Adj. Close'],united['Adj. Close'])\n",
"np.corrcoef(american['close_price'],united['close_price'])"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x7f5c600bf400>"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\ncF015NLxBdF8TTSN/ia
"text/plain": [
"<matplotlib.figure.Figure at 0x7f5c65da57b8>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# spread = american['Adj. Close'] - united['Adj. Close']\n",
"spread = american['close_price'] - united['close_price']\n",
"spread.plot(label='Spread',figsize=(12,8))\n",
"plt.axhline(spread.mean(),c='r')\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Normaliser avec un z-score"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"def zscore(stocks):\n",
" return (stocks - stocks.mean()) / np.std(stocks)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\nmT9/Pl988QU///nP+eS
"text/plain": [
"<matplotlib.figure.Figure at 0x7f5c64b152e8>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"zscore(spread).plot(figsize=(14,8))\n",
"plt.axhline(zscore(spread).mean(), color='black')\n",
"plt.axhline(1.0, c='r', ls='--')\n",
"plt.axhline(-1.0, c='g', ls='--')\n",
"plt.legend(['Spread z-score', 'Mean', '+1', '-1']);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Rolling Z-Score\n",
"\n",
"Notre écart est actuellement American-United. Décidons de la façon de calculer ce spread sur une base continue pour notre utilisation en Quantopian"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\nYsBviTtGX3eaqnNEiNW
"text/plain": [
"<matplotlib.figure.Figure at 0x7f5c6acb6a20>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Moyenne mobile sur 1 jour de l'écart de prix\n",
"spread_mavg1 = spread.rolling(1).mean()\n",
"\n",
"# Moyenne mobile sur 30 jours de l'écart de prix\n",
"spread_mavg30 = spread.rolling(30).mean()\n",
"\n",
"# Prendre un écart-type mobile de 30 jours\n",
"std_30 = spread.rolling(30).std()\n",
"\n",
"# Calculer le z score pour chaque jour\n",
"zscore_30_1 = (spread_mavg1 - spread_mavg30)/std_30\n",
"\n",
"\n",
"\n",
"zscore_30_1.plot(figsize=(12,8),label='Rolling 30 day Z score')\n",
"plt.axhline(0, color='black')\n",
"plt.axhline(1.0, color='red', linestyle='--');"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Implémentation de la Stratégie sur l'IDE Quantopian\n",
"\n",
"#### AVERTISSEMENT : VOUS NE DEVEZ PAS FAIRE DE TRADING AVEC ÇA !"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
" \n",
"def initialize(context):\n",
" \"\"\"\n",
" Appelé une fois au début de l'algorithme.\n",
" \"\"\" \n",
" \n",
" # Chaque jour, nous vérifions le status de la paire\n",
" schedule_function(check_pairs, date_rules.every_day(), time_rules.market_close(minutes=60))\n",
" \n",
" # Nos 2 compagnies aériennes\n",
" context.aa = sid(45971) #aal\n",
" context.ual = sid(28051) #ual \n",
" \n",
" # Flags pour nous dire si on est dans une position de Trading\n",
" context.long_on_spread = False\n",
" context.shorting_spread = False\n",
"\n",
"\n",
"def check_pairs(context, data):\n",
" \n",
" # Par commodité\n",
" aa = context.aa\n",
" ual = context.ual\n",
" \n",
" # Obtenir l'historique des prix\n",
" prices = data.history([aa, ual], \"price\", 30, '1d')\n",
" \n",
" \n",
" # Nécessité d'utiliser .iloc[-1 :] pour obtenir un dataframe au lieu de séries\n",
" short_prices = prices.iloc[-1:]\n",
" \n",
" # Obtenir la moyenne mobile longue sur 30 jours\n",
" mavg_30 = np.mean(prices[aa] - prices[ual])\n",
" \n",
" # Obtenez l'écart-type' de la fenêtre de 30 jours\n",
" std_30 = np.std(prices[aa] - prices[ual])\n",
" \n",
" # Obtenir la moyenne mobile courte sur 30 jours\n",
" mavg_1 = np.mean(short_prices[aa] - short_prices[ual])\n",
" \n",
" # Calculer le z-score\n",
" if std_30 > 0:\n",
" zscore = (mavg_1 - mavg_30)/std_30\n",
" \n",
" # Nos 2 cas d'entrée\n",
" if zscore > 0.5 and not context.shorting_spread:\n",
" # spread = aa - ual\n",
" order_target_percent(aa, -0.5) # short top\n",
" order_target_percent(ual, 0.5) # long bottom\n",
" context.shorting_spread = True\n",
" context.long_on_spread = False\n",
" \n",
" elif zscore < -0.5 and not context.long_on_spread:\n",
" # spread = aa - ual\n",
" order_target_percent(aa, 0.5) # long top\n",
" order_target_percent(ual, -0.5) # short bottom\n",
" context.shorting_spread = False\n",
" context.long_on_spread = True\n",
" \n",
" # Notre cas de sortie\n",
" elif abs(zscore) < 0.1:\n",
" order_target_percent(aa, 0)\n",
" order_target_percent(ual, 0)\n",
" context.shorting_spread = False\n",
" context.long_on_spread = False\n",
" \n",
" record('zscore', zscore)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.5",
"language": "python",
"name": "py35"
},
"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.5"
}
},
"nbformat": 4,
"nbformat_minor": 1
}