├── README.md ├── Readme.md └── AWS_Chalice.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # Alpaca Trading Bot with AWS Chalice & TradingView Webhooks 2 | 3 | ## 12-8-20 4 | ### Group: 5 | * Sheldon Harracksingh 6 | * Xavier Spurlock 7 | * Richard Ripley 8 | 9 | ![Algo Trading image](https://www.tradersdna.com/wp-content/uploads/2016/10/algorithmic-trading.jpg) 10 | 11 | # Objective: 12 | 13 | **TO MAKE MONEY!!!** By backtesting simple trading strategies (such as SMA/EMA) against 3 known stocks (SPY, QQQ, & AAPL) to observe which yield the most profitable returns for future deployment. Then, initiate a trading bot utilizing: Python, AWS Chalice, TradingView, and link it to our Alpaca Paper Trading Account. We are hoping to launch a successful algo trading bot which can execute simple trades while we are busy with work, school, or life. 14 | 15 | **What *is* day trading?** - please see article from [Investopedia](https://www.investopedia.com/articles/trading/05/011705.asp) eloquently explaining how stock trading works. 16 | 17 | # Applications & Resources: 18 | 19 | Before we began, we needed to download the following apps in order to achieve our objective: 20 | 21 | 1 - [Alpaca](https://alpaca.markets) for our online brokerage/paper trading account 22 | 23 | 2 - [Insomnia Rest](https://insomnia.rest) allowed us to test our AWS Chalice on a local network 24 | 25 | 3 - [Amazon AWS](https://aws.amazon.com) to create a resting URL with AWS Chalice 26 | 27 | 4 - [TradingView](https://www.tradingview.com) for researching stocks and creating alerts utilizing Webhooks which succesfully bought our stocks 28 | 29 | * **Resources:** We found this "hacking the markets" [Github page](https://github.com/hackingthemarkets) to be extemely useful with troubleshooting the launch of our trading bot. 30 | 31 | # Process: 32 | 33 | **See attached Notebook files for our Backtrader charts and how to successfully deploy and launch our trading both with Chalice** 34 | 35 | After backtesting the Simple Moving Average Strategy and Exponential Moving Average Strategy on SPY, QQQ, and AAPl, we found that the 3 EMA strategy of 9, 21, & 55, respectively, provided the most profitable returns over a 4 year window. With a starting balance of $100,000 our 3 EMA strategy gave us a 62% return on ticker: QQQ; which isn't half bad for such a basic strategy. Knowing this, we looked up QQQ in TradingView and confirmed that it was trading above our 3 EMA lines, so we deployed our trading bot and successfully purchased 1 stock based on the alert parameters we initiated (we set sell instructions if our stock hits a certain price for profit vs loss). Now we can continue to execute trades with differing stipulations of our choosing and monitor the gains vs losses in our paper trading account to iron out any flaws, and continually test prior to linking a proper brokerage account with real funds. 36 | 37 | # Live Demonstration: 38 | 39 | **Please see the [Youtube Link](https://www.youtube.com/watch?v=rRJ36R7YbCA&feature=youtu.be) of the recorded live deployment of our bot. We wanted to demonstrate how easily it can be used when the markets are open to execute trades.** 40 | 41 | # Conclusion: 42 | 43 | After experimenting with Backtrader, our paper trading account, and TradingView, we only want to further test more elaborate trading strategies with our Bot. Admittedly, these simple strategies are not as aggressive as we would like; however, it has been a great success to launch this bot to set the foundation for future trades. We did a ton of investigating other trading strategies and would love to find a way to deploy a bot that understood the [Ichimoku Could Strategy](https://tradingstrategyguides.com/best-ichimoku-strategy/), or the [3 Bar Reversal and Go](https://tradingsim.com/blog/three-bar-reversal-and-go/). Our goal is to continue working on this bot and improving it so we can earn side income to better our quality of life. 44 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Alpaca Trading Bot with AWS Chalice & TradingView Webhooks 2 | 3 | ## 12-8-20 4 | ### Group: 5 | * Sheldon Harracksingh 6 | * Xavier Spurlock 7 | * Richard Ripley 8 | 9 | ![Algo Trading image](https://www.tradersdna.com/wp-content/uploads/2016/10/algorithmic-trading.jpg) 10 | 11 | # Objective: 12 | 13 | **TO MAKE MONEY!!!** By backtesting simple trading strategies (such as SMA/EMA) against 3 known stocks (SPY, QQQ, & AAPL) to observe which yield the most profitable returns for future deployment. Then, initiate a trading bot utilizing: Python, AWS Chalice, TradingView, and link it to our Alpaca Paper Trading Account. We are hoping to launch a successful algo trading bot which can execute simple trades while we are busy with work, school, or life. 14 | 15 | **What *is* day trading?** - please see article from [Investopedia](https://www.investopedia.com/articles/trading/05/011705.asp) eloquently explaining how stock trading works. 16 | 17 | # Applications & Resources: 18 | 19 | Before we began, we needed to download the following apps in order to achieve our objective: 20 | 21 | 1 - [Alpaca](https://alpaca.markets) for our online brokerage/paper trading account 22 | 23 | 2 - [Insomnia Rest](https://insomnia.rest) allowed us to test our AWS Chalice on a local network 24 | 25 | 3 - [Amazon AWS](https://aws.amazon.com) to create a resting URL with AWS Chalice 26 | 27 | 4 - [TradingView](https://www.tradingview.com) for researching stocks and creating alerts utilizing Webhooks which succesfully bought our stocks 28 | 29 | * **Resources:** We found this "hacking the markets" [Github page](https://github.com/hackingthemarkets) to be extemely useful with troubleshooting the launch of our trading bot. 30 | 31 | # Process: 32 | 33 | **See attached Notebook files for our Backtrader charts and how to successfully deploy and launch our trading both with Chalice** 34 | 35 | After backtesting the Simple Moving Average Strategy and Exponential Moving Average Strategy on SPY, QQQ, and AAPl, we found that the 3 EMA strategy of 9, 21, & 55, respectively, provided the most profitable returns over a 4 year window. With a starting balance of $100,000 our 3 EMA strategy gave us a 62% return on ticker: QQQ; which isn't half bad for such a basic strategy. Knowing this, we looked up QQQ in TradingView and confirmed that it was trading above our 3 EMA lines, so we deployed our trading bot and successfully purchased 1 stock based on the alert parameters we initiated (we set sell instructions if our stock hits a certain price for profit vs loss). Now we can continue to execute trades with differing stipulations of our choosing and monitor the gains vs losses in our paper trading account to iron out any flaws, and continually test prior to linking a proper brokerage account with real funds. 36 | 37 | # Live Demonstration: 38 | 39 | **Please see the [Youtube Link](https://www.youtube.com/watch?v=rRJ36R7YbCA&feature=youtu.be) of the recorded live deployment of our bot. We wanted to demonstrate how easily it can be used when the markets are open to execute trades.** 40 | 41 | # Conclusion: 42 | 43 | After experimenting with Backtrader, our paper trading account, and TradingView, we only want to further test more elaborate trading strategies with our Bot. Admittedly, these simple strategies are not as aggressive as we would like; however, it has been a great success to launch this bot to set the foundation for future trades. We did a ton of investigating other trading strategies and would love to find a way to deploy a bot that understood the [Ichimoku Could Strategy](https://tradingstrategyguides.com/best-ichimoku-strategy/), or the [3 Bar Reversal and Go](https://tradingsim.com/blog/three-bar-reversal-and-go/). Our goal is to continue working on this bot and improving it so we can earn side income to better our quality of life. 44 | -------------------------------------------------------------------------------- /AWS_Chalice.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Creating ``Chalice``\n", 8 | "***Follow this [link](https://aws.github.io/chalice/quickstart.html) for an easy instulation guide***" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "* Open a terminal, or perfered user-interface\n", 16 | "* Verify that chalice is installed" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 11, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "name": "stdout", 26 | "output_type": "stream", 27 | "text": [ 28 | "chalice 1.21.4, python 3.8.3, windows 10\n" 29 | ] 30 | } 31 | ], 32 | "source": [ 33 | "!chalice --version" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "* Use the command **``mkdir .aws``** to make a directory to store AWS keys" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 12, 46 | "metadata": {}, 47 | "outputs": [ 48 | { 49 | "name": "stderr", 50 | "output_type": "stream", 51 | "text": [ 52 | "A subdirectory or file .aws already exists.\n" 53 | ] 54 | } 55 | ], 56 | "source": [ 57 | "!mkdir .aws" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "* Use the **``touch .aws/config``** to create a document inside of the **``.aws``** file" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 13, 70 | "metadata": {}, 71 | "outputs": [], 72 | "source": [ 73 | "!touch .aws/config" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "* Launch the **``config``** file with your perfered user-inter face\n", 81 | "* Store your keys in the file like so\n", 82 | " * **``aws_access_key_id=\"PUBLIC_KEY\"``**\n", 83 | " * **``aws_secret_access_key=\"SECRET_KEY\"``**\n", 84 | " * **``region=SET_REGION``**" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "* Create a new directory \n", 92 | " * ``mkdir \"Name of directory\"``
\n", 93 | "(optional, used for organization)" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 14, 99 | "metadata": {}, 100 | "outputs": [ 101 | { 102 | "name": "stderr", 103 | "output_type": "stream", 104 | "text": [ 105 | "A subdirectory or file running_chalice already exists.\n" 106 | ] 107 | } 108 | ], 109 | "source": [ 110 | "!mkdir running_chalice" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "* ``cd`` into the new directory" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 15, 123 | "metadata": {}, 124 | "outputs": [], 125 | "source": [ 126 | "!cd running_chalice" 127 | ] 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "metadata": {}, 132 | "source": [ 133 | "* Use the chalice command to create a new project\n", 134 | " * **``chalice new-project \"NAME_OF_PROJECT\"``**" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 16, 140 | "metadata": {}, 141 | "outputs": [ 142 | { 143 | "name": "stderr", 144 | "output_type": "stream", 145 | "text": [ 146 | "Directory already exists: Algo_trade\n", 147 | "Aborted!\n" 148 | ] 149 | } 150 | ], 151 | "source": [ 152 | "!chalice new-project Algo_trade" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": {}, 158 | "source": [ 159 | "* ``cd`` into the new project\n", 160 | "* Locate the **``app.py``** and launch it with perfered user-interface " 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "metadata": {}, 166 | "source": [ 167 | "---\n", 168 | "# Connecting Alpaca" 169 | ] 170 | }, 171 | { 172 | "cell_type": "markdown", 173 | "metadata": {}, 174 | "source": [ 175 | "***Using the ``app.py`` file launched above we are going to connect to Alpaca***
\n", 176 | "***Start by importing the modules and libraries need***" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 17, 182 | "metadata": {}, 183 | "outputs": [], 184 | "source": [ 185 | "from chalice import Chalice\n", 186 | "import requests, json" 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "metadata": {}, 192 | "source": [ 193 | "* Create the headers Alpaca/Chalice needs " 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": 18, 199 | "metadata": {}, 200 | "outputs": [], 201 | "source": [ 202 | "app = Chalice(app_name='YOUR_PROJECT_NAME')\n", 203 | "API_KEY=\"YOUR_PUBLIC_ALPACA_KEY\"\n", 204 | "SECRET_KEY=\"YOUR_SECRET_ALPACA_KEY\"\n", 205 | "BASE_URL = \"https://paper-api.alpaca.markets\"\n", 206 | "ORDERS_URL = \"{}/v2/orders\".format(BASE_URL)\n", 207 | "HEADERS = {'APCA-API-KEY-ID': API_KEY, 'APCA-API-SECRET-KEY': SECRET_KEY}" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "* Creating the braket order to sit on the resting URL" 215 | ] 216 | }, 217 | { 218 | "cell_type": "code", 219 | "execution_count": 19, 220 | "metadata": {}, 221 | "outputs": [], 222 | "source": [ 223 | "@app.route('/buy_stock', methods=['POST'])\n", 224 | "# ^^^Naming the URL^^^\n", 225 | "\n", 226 | "def buy_stock(): \n", 227 | "# ^^^Creating the function\n", 228 | "\n", 229 | " request = app.current_request \n", 230 | "# ^^^Receving the information about the request^^^\n", 231 | " \n", 232 | " webhook_message = request.json_body \n", 233 | "# ^^^The json request being sent in (in our case from TRADING_VIEW)^^^\n", 234 | " \n", 235 | " data = { \n", 236 | " \"symbol\": webhook_message[\"ticker\"], \n", 237 | "# ^^^ticker symbol that alert sends us^^^\n", 238 | " \"qty\": 1, \n", 239 | "# ^^^number of shares^^^\n", 240 | " \"side\": \"buy\", \n", 241 | "# ^^^buying the stock^^^\n", 242 | " \"type\": \"limit\", \n", 243 | "# ^^^setting limit order^^^\n", 244 | " \"limit_price\":webhook_message[\"close\"], \n", 245 | "# ^^^setting buying price^^^\n", 246 | " \"time_in_force\": \"gtc\", \n", 247 | "# ^^^Length of order^^^\n", 248 | " \"order_class\": \"bracket\", \n", 249 | "# ^^^type of order^^^\n", 250 | " \"take_profit\": {\n", 251 | " \"limit_price\": webhook_message[\"close\"] * 1.05}, \n", 252 | "# ^^^Setting profit taking^^^\n", 253 | " \"stop_loss\": {\n", 254 | " \"stop_price\": webhook_message[\"close\"] * 0.98,} \n", 255 | "# ^^^Setting stop loss^^^\n", 256 | " }\n", 257 | " \n", 258 | " r = requests.post(ORDERS_URL, json=data, headers=HEADERS) \n", 259 | "# ^^^Sending Request^^^\n", 260 | "\n", 261 | " response = json.loads(r.content) \n", 262 | "# ^^^Recieving Request Response^^^\n", 263 | " print(response)\n", 264 | " print(response.content)\n", 265 | "\n", 266 | " return {\n", 267 | " 'message':'I bought the stock', \n", 268 | "# ^^^Returning personal message (Optional)^^^\n", 269 | "\n", 270 | " 'webhook': webhook_message \n", 271 | "# ^^^Returning the json message (Optional)^^^\n", 272 | " }" 273 | ] 274 | }, 275 | { 276 | "cell_type": "markdown", 277 | "metadata": {}, 278 | "source": [ 279 | "### **Your final ``app.py`` file should look like this**
\n", 280 | "![app.py](Images/app.png)" 281 | ] 282 | }, 283 | { 284 | "cell_type": "markdown", 285 | "metadata": {}, 286 | "source": [ 287 | "* Save the **``app.py``** file \n", 288 | "* In the terminal deploy the chalie\n", 289 | " * ``chalice deploy``\n", 290 | "* Coppy the \"Rest\" URL provided
\n", 291 | "![URL](Images/chalice_deploy.png)" 292 | ] 293 | }, 294 | { 295 | "cell_type": "markdown", 296 | "metadata": {}, 297 | "source": [ 298 | "# ***Creating Alerts and adding the weebhook with ``trading_view``***" 299 | ] 300 | } 301 | ], 302 | "metadata": { 303 | "kernelspec": { 304 | "display_name": "Python 3", 305 | "language": "python", 306 | "name": "python3" 307 | }, 308 | "language_info": { 309 | "codemirror_mode": { 310 | "name": "ipython", 311 | "version": 3 312 | }, 313 | "file_extension": ".py", 314 | "mimetype": "text/x-python", 315 | "name": "python", 316 | "nbconvert_exporter": "python", 317 | "pygments_lexer": "ipython3", 318 | "version": "3.8.3" 319 | } 320 | }, 321 | "nbformat": 4, 322 | "nbformat_minor": 4 323 | } 324 | --------------------------------------------------------------------------------