├── .gitignore ├── LICENSE ├── README.md ├── ai └── stock-prediction-ai-1.ipynb ├── bb-rsi-obv ├── RSI-OBV-BB-Strategy.ipynb └── TA Strategy Combination Tester 1.ipynb ├── crypto ├── Binance Filters 1.ipynb ├── Crypto Snapshot CoinGecko 1.ipynb ├── binance_api_websockets.py └── crypto-market-cap-1.ipynb ├── data ├── ETH-USD_1d_1m.csv ├── coingecko-list.json ├── nasdaq.csv └── nasdaq_100.csv ├── data_loads └── Load-Historic-Crypto-Prices.ipynb ├── news_analysis └── news_correlation_tester.py ├── samples ├── crypto-screener-report │ └── screener-coins-report.html └── trending-crypto-report │ ├── baby-doge-coin-ohlc-day.png │ ├── baby-doge-coin-ohlc-month.png │ ├── constitutiondao-ohlc-day.png │ ├── constitutiondao-ohlc-month.png │ ├── fantom-ohlc-day.png │ ├── fantom-ohlc-month.png │ ├── gods-unchained-ohlc-day.png │ ├── gods-unchained-ohlc-month.png │ ├── green-satoshi-token-ohlc-day.png │ ├── green-satoshi-token-ohlc-month.png │ ├── terra-luna-ohlc-day.png │ ├── terra-luna-ohlc-month.png │ ├── terrausd-ohlc-day.png │ ├── terrausd-ohlc-month.png │ └── trending-coins-report.html ├── screeners ├── Stock Value Screener 1.ipynb └── performance_screener.py ├── strategies ├── 2017_strategy_evaluation.csv ├── 2021_strategy_evaluation.csv ├── BB-Strategy-With-Stop-Loss.ipynb ├── Crypto BB-RSI-STC.ipynb ├── Crypto Chandelier Exit.ipynb └── Keltner-channel-Breakout.ipynb ├── trends ├── Market-Index-1.ipynb ├── Primary Market Trends.ipynb ├── aaii_survey_results_1.ipynb └── market_index_sentiment.py └── visualization └── Company Snapshot.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Chris Scheid 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python-algorithmic-trading -------------------------------------------------------------------------------- /bb-rsi-obv/TA Strategy Combination Tester 1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "beb1c264", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [] 10 | } 11 | ], 12 | "metadata": { 13 | "kernelspec": { 14 | "display_name": "Python [conda env:tradesystem1]", 15 | "language": "python", 16 | "name": "conda-env-tradesystem1-py" 17 | }, 18 | "language_info": { 19 | "codemirror_mode": { 20 | "name": "ipython", 21 | "version": 3 22 | }, 23 | "file_extension": ".py", 24 | "mimetype": "text/x-python", 25 | "name": "python", 26 | "nbconvert_exporter": "python", 27 | "pygments_lexer": "ipython3", 28 | "version": "3.9.5" 29 | } 30 | }, 31 | "nbformat": 4, 32 | "nbformat_minor": 5 33 | } 34 | -------------------------------------------------------------------------------- /crypto/Binance Filters 1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 253, 6 | "id": "fa526b1d", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import os\n", 11 | "import sys\n", 12 | "import time\n", 13 | "import pandas as pd\n", 14 | "import asyncio\n", 15 | "from binance import Client, AsyncClient, BinanceSocketManager\n", 16 | "from binance.exceptions import BinanceAPIException\n", 17 | "from pprint import pformat\n", 18 | "from binance.helpers import round_step_size\n", 19 | "from binance.enums import *" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 254, 25 | "id": "c1e19b24", 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "TEST_API_KEY = 'Your API Key'\n", 30 | "TEST_API_SECRET = 'Your API Secret'\n" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 255, 36 | "id": "f26c2fb9", 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "# Instantiate Binance API client TESTNET US Market\n", 41 | "client = Client(api_key=TEST_API_KEY, api_secret=TEST_API_SECRET, testnet=True, tld='us')" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 256, 47 | "id": "2bb31bd3", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "def convert_scientific_to_decimal(num):\n", 52 | " if 'e' in str(num):\n", 53 | " return \"{:.15f}\".format(float(str(num)))\n", 54 | " else:\n", 55 | " return str(num)" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 268, 61 | "id": "9d08d01b", 62 | "metadata": { 63 | "scrolled": true 64 | }, 65 | "outputs": [ 66 | { 67 | "name": "stdout", 68 | "output_type": "stream", 69 | "text": [ 70 | "{'allowTrailingStop': True,\n", 71 | " 'baseAsset': 'BTC',\n", 72 | " 'baseAssetPrecision': 8,\n", 73 | " 'baseCommissionPrecision': 8,\n", 74 | " 'filters': [{'filterType': 'PRICE_FILTER',\n", 75 | " 'maxPrice': '1000000.00000000',\n", 76 | " 'minPrice': '0.01000000',\n", 77 | " 'tickSize': '0.01000000'},\n", 78 | " {'avgPriceMins': 5,\n", 79 | " 'filterType': 'PERCENT_PRICE',\n", 80 | " 'multiplierDown': '0.2',\n", 81 | " 'multiplierUp': '5'},\n", 82 | " {'filterType': 'LOT_SIZE',\n", 83 | " 'maxQty': '900.00000000',\n", 84 | " 'minQty': '0.00000100',\n", 85 | " 'stepSize': '0.00000100'},\n", 86 | " {'applyToMarket': True,\n", 87 | " 'avgPriceMins': 5,\n", 88 | " 'filterType': 'MIN_NOTIONAL',\n", 89 | " 'minNotional': '10.00000000'},\n", 90 | " {'filterType': 'ICEBERG_PARTS', 'limit': 10},\n", 91 | " {'filterType': 'MARKET_LOT_SIZE',\n", 92 | " 'maxQty': '100.00000000',\n", 93 | " 'minQty': '0.00000000',\n", 94 | " 'stepSize': '0.00000000'},\n", 95 | " {'filterType': 'TRAILING_DELTA',\n", 96 | " 'maxTrailingAboveDelta': 2000,\n", 97 | " 'maxTrailingBelowDelta': 2000,\n", 98 | " 'minTrailingAboveDelta': 10,\n", 99 | " 'minTrailingBelowDelta': 10},\n", 100 | " {'filterType': 'MAX_NUM_ORDERS', 'maxNumOrders': 200},\n", 101 | " {'filterType': 'MAX_NUM_ALGO_ORDERS', 'maxNumAlgoOrders': 5}],\n", 102 | " 'icebergAllowed': True,\n", 103 | " 'isMarginTradingAllowed': False,\n", 104 | " 'isSpotTradingAllowed': True,\n", 105 | " 'ocoAllowed': True,\n", 106 | " 'orderTypes': ['LIMIT',\n", 107 | " 'LIMIT_MAKER',\n", 108 | " 'MARKET',\n", 109 | " 'STOP_LOSS_LIMIT',\n", 110 | " 'TAKE_PROFIT_LIMIT'],\n", 111 | " 'permissions': ['SPOT'],\n", 112 | " 'quoteAsset': 'USDT',\n", 113 | " 'quoteAssetPrecision': 8,\n", 114 | " 'quoteCommissionPrecision': 8,\n", 115 | " 'quoteOrderQtyMarketAllowed': True,\n", 116 | " 'quotePrecision': 8,\n", 117 | " 'status': 'TRADING',\n", 118 | " 'symbol': 'BTCUSDT'}\n" 119 | ] 120 | } 121 | ], 122 | "source": [ 123 | "# Get filter info in raw format\n", 124 | "info = client.get_symbol_info('BTCUSDT')\n", 125 | "print(pformat(info))" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 265, 131 | "id": "87293131", 132 | "metadata": {}, 133 | "outputs": [ 134 | { 135 | "name": "stdout", 136 | "output_type": "stream", 137 | "text": [ 138 | "{'BTCUSDT': {'lot_size_max_quantity': 900.0,\n", 139 | " 'lot_size_min_quantity': 1e-06,\n", 140 | " 'lot_size_step_size': 1e-06,\n", 141 | " 'min_notional': 10.0,\n", 142 | " 'price_filter_max_quantity': 1000000.0,\n", 143 | " 'price_filter_min_quantity': 0.01,\n", 144 | " 'price_filter_tick_size': 0.01}}\n" 145 | ] 146 | } 147 | ], 148 | "source": [ 149 | "symbol_info = {}\n", 150 | "def get_symbol_info(symbols):\n", 151 | " global symbol_info\n", 152 | " for symbol in symbols:\n", 153 | " info = client.get_symbol_info(symbol)\n", 154 | " base_asset = info['baseAsset']\n", 155 | "\n", 156 | " # PRICE_FILTER\n", 157 | " price_filter_min_quantity = float(info['filters'][0]['minPrice'])\n", 158 | " price_filter_max_quantity = float(info['filters'][0]['maxPrice'])\n", 159 | " price_filter_tick_size = float(info['filters'][0]['tickSize'])\n", 160 | " \n", 161 | " # LOT_SIZE (for market- and limit orders)\n", 162 | " lot_size_min_quantity = float(info['filters'][2]['minQty'])\n", 163 | " lot_size_max_quantity = float(info['filters'][2]['maxQty'])\n", 164 | " lot_size_step_size = float(info['filters'][2]['stepSize'])\n", 165 | " \n", 166 | " # MIN NOTIONAL\n", 167 | " min_notional = float(info['filters'][3]['minNotional'])\n", 168 | " \n", 169 | "\n", 170 | " symbol_info[symbol] = {'price_filter_min_quantity': price_filter_min_quantity, 'price_filter_max_quantity': price_filter_max_quantity,\\\n", 171 | " 'price_filter_tick_size': price_filter_tick_size,'lot_size_min_quantity': lot_size_min_quantity, \\\n", 172 | " 'lot_size_min_quantity': lot_size_min_quantity, 'lot_size_max_quantity': lot_size_max_quantity, \\\n", 173 | " 'lot_size_step_size': lot_size_step_size, 'min_notional': min_notional, }\n", 174 | " \n", 175 | "symbols = ['BTCUSDT']\n", 176 | "get_symbol_info(symbols)\n", 177 | "print(pformat(symbol_info))" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 258, 183 | "id": "1e5c5541", 184 | "metadata": {}, 185 | "outputs": [ 186 | { 187 | "name": "stdout", 188 | "output_type": "stream", 189 | "text": [ 190 | "BTC 1.00696400\n", 191 | "USDT 9495.52236687\n" 192 | ] 193 | } 194 | ], 195 | "source": [ 196 | "# Get the balances for both coins\n", 197 | "btc_balance = client.get_asset_balance(asset='BTC').get('free')\n", 198 | "print('BTC ',btc_balance)\n", 199 | "usdt_balance = client.get_asset_balance(asset='USDT').get('free')\n", 200 | "print('USDT ',usdt_balance)" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 259, 206 | "id": "541d2aa4", 207 | "metadata": {}, 208 | "outputs": [ 209 | { 210 | "name": "stdout", 211 | "output_type": "stream", 212 | "text": [ 213 | "One BTC can buy 40447.71 USDT\n" 214 | ] 215 | } 216 | ], 217 | "source": [ 218 | "# What's the exchange rate between BTC and USDT? \n", 219 | "price = float(client.get_symbol_ticker(symbol='BTCUSDT')['price'])\n", 220 | "print('One BTC can buy ',price,' USDT')" 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": 260, 226 | "id": "1fe77b36", 227 | "metadata": {}, 228 | "outputs": [ 229 | { 230 | "name": "stdout", 231 | "output_type": "stream", 232 | "text": [ 233 | "2.4723278524297173e-07\n" 234 | ] 235 | } 236 | ], 237 | "source": [ 238 | "# How many BTC do we want to spend? Let's say $0.01 worth\n", 239 | "quantity = float(0.01 / price)\n", 240 | "print(quantity)" 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": 261, 246 | "id": "35d0562f", 247 | "metadata": { 248 | "scrolled": true 249 | }, 250 | "outputs": [ 251 | { 252 | "ename": "BinanceAPIException", 253 | "evalue": "APIError(code=-1100): Illegal characters found in parameter 'quantity'; legal range is '^([0-9]{1,20})(\\.[0-9]{1,20})?$'.", 254 | "output_type": "error", 255 | "traceback": [ 256 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 257 | "\u001b[1;31mBinanceAPIException\u001b[0m Traceback (most recent call last)", 258 | "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_47544/3040500745.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# Create a Buy Order\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m order = client.create_order(\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[0msymbol\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'BTCUSDT'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mquantity\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mquantity\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mside\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mSIDE_BUY\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 259 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36mcreate_order\u001b[1;34m(self, **params)\u001b[0m\n\u001b[0;32m 1395\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1396\u001b[0m \"\"\"\n\u001b[1;32m-> 1397\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_post\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'order'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;32mTrue\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1398\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1399\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0morder_limit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtimeInForce\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mTIME_IN_FORCE_GTC\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 260 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_post\u001b[1;34m(self, path, signed, version, **kwargs)\u001b[0m\n\u001b[0;32m 372\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 373\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_post\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mPUBLIC_API_VERSION\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 374\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_request_api\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'post'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 375\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 376\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_put\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mPUBLIC_API_VERSION\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 261 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_request_api\u001b[1;34m(self, method, path, signed, version, **kwargs)\u001b[0m\n\u001b[0;32m 332\u001b[0m ):\n\u001b[0;32m 333\u001b[0m \u001b[0muri\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_create_api_uri\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 334\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_request\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmethod\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0muri\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 335\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 336\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_request_futures_api\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 262 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_request\u001b[1;34m(self, method, uri, signed, force_params, **kwargs)\u001b[0m\n\u001b[0;32m 313\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 314\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresponse\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msession\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0muri\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 315\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_handle_response\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresponse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 316\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 317\u001b[0m \u001b[1;33m@\u001b[0m\u001b[0mstaticmethod\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 263 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_handle_response\u001b[1;34m(response)\u001b[0m\n\u001b[0;32m 322\u001b[0m \"\"\"\n\u001b[0;32m 323\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m200\u001b[0m \u001b[1;33m<=\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus_code\u001b[0m \u001b[1;33m<\u001b[0m \u001b[1;36m300\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 324\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mBinanceAPIException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresponse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus_code\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 325\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 326\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjson\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 264 | "\u001b[1;31mBinanceAPIException\u001b[0m: APIError(code=-1100): Illegal characters found in parameter 'quantity'; legal range is '^([0-9]{1,20})(\\.[0-9]{1,20})?$'." 265 | ] 266 | } 267 | ], 268 | "source": [ 269 | "# Create a Buy Order\n", 270 | "order = client.create_order(\n", 271 | " symbol='BTCUSDT',\n", 272 | " quantity=quantity,\n", 273 | " side=SIDE_BUY,\n", 274 | " type=ORDER_TYPE_MARKET,\n", 275 | ")" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "execution_count": 263, 281 | "id": "44cc48ab", 282 | "metadata": {}, 283 | "outputs": [ 284 | { 285 | "name": "stdout", 286 | "output_type": "stream", 287 | "text": [ 288 | "0.000000247232785\n" 289 | ] 290 | }, 291 | { 292 | "ename": "BinanceAPIException", 293 | "evalue": "APIError(code=-1111): Precision is over the maximum defined for this asset.", 294 | "output_type": "error", 295 | "traceback": [ 296 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 297 | "\u001b[1;31mBinanceAPIException\u001b[0m Traceback (most recent call last)", 298 | "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_47544/842803346.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;31m# Create a Buy Order\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m order = client.create_order(\n\u001b[0m\u001b[0;32m 7\u001b[0m \u001b[0msymbol\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'BTCUSDT'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 8\u001b[0m \u001b[0mquantity\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mquantity\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 299 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36mcreate_order\u001b[1;34m(self, **params)\u001b[0m\n\u001b[0;32m 1395\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1396\u001b[0m \"\"\"\n\u001b[1;32m-> 1397\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_post\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'order'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;32mTrue\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1398\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1399\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0morder_limit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtimeInForce\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mTIME_IN_FORCE_GTC\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 300 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_post\u001b[1;34m(self, path, signed, version, **kwargs)\u001b[0m\n\u001b[0;32m 372\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 373\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_post\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mPUBLIC_API_VERSION\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 374\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_request_api\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'post'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 375\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 376\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_put\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mPUBLIC_API_VERSION\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 301 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_request_api\u001b[1;34m(self, method, path, signed, version, **kwargs)\u001b[0m\n\u001b[0;32m 332\u001b[0m ):\n\u001b[0;32m 333\u001b[0m \u001b[0muri\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_create_api_uri\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 334\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_request\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmethod\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0muri\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 335\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 336\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_request_futures_api\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 302 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_request\u001b[1;34m(self, method, uri, signed, force_params, **kwargs)\u001b[0m\n\u001b[0;32m 313\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 314\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresponse\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msession\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0muri\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 315\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_handle_response\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresponse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 316\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 317\u001b[0m \u001b[1;33m@\u001b[0m\u001b[0mstaticmethod\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 303 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_handle_response\u001b[1;34m(response)\u001b[0m\n\u001b[0;32m 322\u001b[0m \"\"\"\n\u001b[0;32m 323\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m200\u001b[0m \u001b[1;33m<=\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus_code\u001b[0m \u001b[1;33m<\u001b[0m \u001b[1;36m300\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 324\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mBinanceAPIException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresponse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus_code\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 325\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 326\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjson\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 304 | "\u001b[1;31mBinanceAPIException\u001b[0m: APIError(code=-1111): Precision is over the maximum defined for this asset." 305 | ] 306 | } 307 | ], 308 | "source": [ 309 | "# Convert scientific notation to decimal\n", 310 | "quantity = convert_scientific_to_decimal(quantity)\n", 311 | "print(quantity)\n", 312 | "\n", 313 | "# Create a Buy Order\n", 314 | "order = client.create_order(\n", 315 | " symbol='BTCUSDT',\n", 316 | " quantity=quantity,\n", 317 | " side=SIDE_BUY,\n", 318 | " type=ORDER_TYPE_MARKET,\n", 319 | ")" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 271, 325 | "id": "37948273", 326 | "metadata": {}, 327 | "outputs": [ 328 | { 329 | "name": "stdout", 330 | "output_type": "stream", 331 | "text": [ 332 | "quantity: 0.00000025\n" 333 | ] 334 | }, 335 | { 336 | "ename": "BinanceAPIException", 337 | "evalue": "APIError(code=-1013): Filter failure: LOT_SIZE", 338 | "output_type": "error", 339 | "traceback": [ 340 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 341 | "\u001b[1;31mBinanceAPIException\u001b[0m Traceback (most recent call last)", 342 | "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_47544/1393133353.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;31m# Create a Buy Order\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m order = client.create_order(\n\u001b[0m\u001b[0;32m 7\u001b[0m \u001b[0msymbol\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'BTCUSDT'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 8\u001b[0m \u001b[0mquantity\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mquantity\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 343 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36mcreate_order\u001b[1;34m(self, **params)\u001b[0m\n\u001b[0;32m 1395\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1396\u001b[0m \"\"\"\n\u001b[1;32m-> 1397\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_post\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'order'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;32mTrue\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1398\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1399\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0morder_limit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtimeInForce\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mTIME_IN_FORCE_GTC\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 344 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_post\u001b[1;34m(self, path, signed, version, **kwargs)\u001b[0m\n\u001b[0;32m 372\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 373\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_post\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mPUBLIC_API_VERSION\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 374\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_request_api\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'post'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 375\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 376\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_put\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mPUBLIC_API_VERSION\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 345 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_request_api\u001b[1;34m(self, method, path, signed, version, **kwargs)\u001b[0m\n\u001b[0;32m 332\u001b[0m ):\n\u001b[0;32m 333\u001b[0m \u001b[0muri\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_create_api_uri\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 334\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_request\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmethod\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0muri\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 335\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 336\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_request_futures_api\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 346 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_request\u001b[1;34m(self, method, uri, signed, force_params, **kwargs)\u001b[0m\n\u001b[0;32m 313\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 314\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresponse\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msession\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0muri\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 315\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_handle_response\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresponse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 316\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 317\u001b[0m \u001b[1;33m@\u001b[0m\u001b[0mstaticmethod\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 347 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_handle_response\u001b[1;34m(response)\u001b[0m\n\u001b[0;32m 322\u001b[0m \"\"\"\n\u001b[0;32m 323\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m200\u001b[0m \u001b[1;33m<=\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus_code\u001b[0m \u001b[1;33m<\u001b[0m \u001b[1;36m300\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 324\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mBinanceAPIException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresponse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus_code\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 325\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 326\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjson\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 348 | "\u001b[1;31mBinanceAPIException\u001b[0m: APIError(code=-1013): Filter failure: LOT_SIZE" 349 | ] 350 | } 351 | ], 352 | "source": [ 353 | "# Format quantity to a decimal string\n", 354 | "quantity = '{:.8f}'.format(float(quantity))\n", 355 | "print('quantity: ',quantity)\n", 356 | "\n", 357 | "# Create a Buy Order\n", 358 | "order = client.create_order(\n", 359 | " symbol='BTCUSDT',\n", 360 | " quantity=quantity,\n", 361 | " side=SIDE_BUY,\n", 362 | " type=ORDER_TYPE_MARKET,\n", 363 | ")" 364 | ] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "execution_count": 272, 369 | "id": "20b32030", 370 | "metadata": {}, 371 | "outputs": [ 372 | { 373 | "name": "stdout", 374 | "output_type": "stream", 375 | "text": [ 376 | "min_quantity: 1e-06 , max_quantity: 900.0 , quantity: 0.00000025\n", 377 | "Quantity too small\n" 378 | ] 379 | } 380 | ], 381 | "source": [ 382 | "# Check quantity filters\n", 383 | "info = symbol_info['BTCUSDT']\n", 384 | "min_quantity = info['lot_size_min_quantity']\n", 385 | "max_quantity = info['lot_size_max_quantity']\n", 386 | "print('min_quantity: ',min_quantity,', max_quantity: ',max_quantity,', quantity: ',quantity)\n", 387 | "quantity = float(quantity)\n", 388 | "if quantity < min_quantity:\n", 389 | " print('Quantity too small')\n", 390 | "if quantity > max_quantity:\n", 391 | " print('Quantity too large')\n" 392 | ] 393 | }, 394 | { 395 | "cell_type": "code", 396 | "execution_count": 274, 397 | "id": "1f0c18e0", 398 | "metadata": {}, 399 | "outputs": [ 400 | { 401 | "name": "stdout", 402 | "output_type": "stream", 403 | "text": [ 404 | "quantity: 0.00000247\n" 405 | ] 406 | }, 407 | { 408 | "ename": "BinanceAPIException", 409 | "evalue": "APIError(code=-1013): Filter failure: LOT_SIZE", 410 | "output_type": "error", 411 | "traceback": [ 412 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 413 | "\u001b[1;31mBinanceAPIException\u001b[0m Traceback (most recent call last)", 414 | "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_47544/3230416160.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 8\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 10\u001b[1;33m order = client.create_order(\n\u001b[0m\u001b[0;32m 11\u001b[0m \u001b[0msymbol\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'BTCUSDT'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 12\u001b[0m \u001b[0mquantity\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mquantity\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 415 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36mcreate_order\u001b[1;34m(self, **params)\u001b[0m\n\u001b[0;32m 1395\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1396\u001b[0m \"\"\"\n\u001b[1;32m-> 1397\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_post\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'order'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;32mTrue\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1398\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1399\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0morder_limit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtimeInForce\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mTIME_IN_FORCE_GTC\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 416 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_post\u001b[1;34m(self, path, signed, version, **kwargs)\u001b[0m\n\u001b[0;32m 372\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 373\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_post\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mPUBLIC_API_VERSION\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 374\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_request_api\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'post'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 375\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 376\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_put\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mPUBLIC_API_VERSION\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 417 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_request_api\u001b[1;34m(self, method, path, signed, version, **kwargs)\u001b[0m\n\u001b[0;32m 332\u001b[0m ):\n\u001b[0;32m 333\u001b[0m \u001b[0muri\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_create_api_uri\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 334\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_request\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmethod\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0muri\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 335\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 336\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_request_futures_api\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 418 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_request\u001b[1;34m(self, method, uri, signed, force_params, **kwargs)\u001b[0m\n\u001b[0;32m 313\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 314\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresponse\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msession\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0muri\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 315\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_handle_response\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresponse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 316\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 317\u001b[0m \u001b[1;33m@\u001b[0m\u001b[0mstaticmethod\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 419 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_handle_response\u001b[1;34m(response)\u001b[0m\n\u001b[0;32m 322\u001b[0m \"\"\"\n\u001b[0;32m 323\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m200\u001b[0m \u001b[1;33m<=\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus_code\u001b[0m \u001b[1;33m<\u001b[0m \u001b[1;36m300\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 324\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mBinanceAPIException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresponse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus_code\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 325\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 326\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjson\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 420 | "\u001b[1;31mBinanceAPIException\u001b[0m: APIError(code=-1013): Filter failure: LOT_SIZE" 421 | ] 422 | } 423 | ], 424 | "source": [ 425 | "# Increase quantity to $0.1\n", 426 | "quantity = float(0.1 / price_btc)\n", 427 | "quantity = '{:.8f}'.format(float(quantity))\n", 428 | "print('quantity: ', quantity)\n", 429 | "\n", 430 | "if float(quantity) < min_quantity:\n", 431 | " print('Quantity too small')\n", 432 | "\n", 433 | "\n", 434 | "order = client.create_order(\n", 435 | " symbol='BTCUSDT',\n", 436 | " quantity=quantity,\n", 437 | " side=SIDE_BUY,\n", 438 | " type=ORDER_TYPE_MARKET,\n", 439 | ")" 440 | ] 441 | }, 442 | { 443 | "cell_type": "code", 444 | "execution_count": 275, 445 | "id": "69b10347", 446 | "metadata": {}, 447 | "outputs": [ 448 | { 449 | "name": "stdout", 450 | "output_type": "stream", 451 | "text": [ 452 | "step_size: 1e-06\n", 453 | "quantity 2e-06\n" 454 | ] 455 | }, 456 | { 457 | "ename": "BinanceAPIException", 458 | "evalue": "APIError(code=-1013): Filter failure: MIN_NOTIONAL", 459 | "output_type": "error", 460 | "traceback": [ 461 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 462 | "\u001b[1;31mBinanceAPIException\u001b[0m Traceback (most recent call last)", 463 | "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_47544/2960427698.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'quantity'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbtc_quantity\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 8\u001b[1;33m order = client.create_order(\n\u001b[0m\u001b[0;32m 9\u001b[0m \u001b[0msymbol\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'BTCUSDT'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[0mquantity\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mquantity\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 464 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36mcreate_order\u001b[1;34m(self, **params)\u001b[0m\n\u001b[0;32m 1395\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1396\u001b[0m \"\"\"\n\u001b[1;32m-> 1397\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_post\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'order'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;32mTrue\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1398\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1399\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0morder_limit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtimeInForce\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mTIME_IN_FORCE_GTC\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 465 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_post\u001b[1;34m(self, path, signed, version, **kwargs)\u001b[0m\n\u001b[0;32m 372\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 373\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_post\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mPUBLIC_API_VERSION\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 374\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_request_api\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'post'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 375\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 376\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_put\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mBaseClient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mPUBLIC_API_VERSION\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 466 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_request_api\u001b[1;34m(self, method, path, signed, version, **kwargs)\u001b[0m\n\u001b[0;32m 332\u001b[0m ):\n\u001b[0;32m 333\u001b[0m \u001b[0muri\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_create_api_uri\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mversion\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 334\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_request\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmethod\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0muri\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 335\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 336\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_request_futures_api\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msigned\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mDict\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 467 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_request\u001b[1;34m(self, method, uri, signed, force_params, **kwargs)\u001b[0m\n\u001b[0;32m 313\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 314\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresponse\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msession\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0muri\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 315\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_handle_response\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresponse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 316\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 317\u001b[0m \u001b[1;33m@\u001b[0m\u001b[0mstaticmethod\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 468 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\binance\\client.py\u001b[0m in \u001b[0;36m_handle_response\u001b[1;34m(response)\u001b[0m\n\u001b[0;32m 322\u001b[0m \"\"\"\n\u001b[0;32m 323\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m200\u001b[0m \u001b[1;33m<=\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus_code\u001b[0m \u001b[1;33m<\u001b[0m \u001b[1;36m300\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 324\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mBinanceAPIException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresponse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstatus_code\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtext\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 325\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 326\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjson\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 469 | "\u001b[1;31mBinanceAPIException\u001b[0m: APIError(code=-1013): Filter failure: MIN_NOTIONAL" 470 | ] 471 | } 472 | ], 473 | "source": [ 474 | "# Need to round up quantity to meet step size\n", 475 | "step_size = info['lot_size_step_size']\n", 476 | "print('step_size: ',step_size)\n", 477 | "btc_quantity = round_step_size(quantity, step_size)\n", 478 | "quantity = '{:.6f}'.format(float(quantity))\n", 479 | "print('quantity', btc_quantity)\n", 480 | "\n", 481 | "order = client.create_order(\n", 482 | " symbol='BTCUSDT',\n", 483 | " quantity=quantity,\n", 484 | " side=SIDE_BUY,\n", 485 | " type=ORDER_TYPE_MARKET,\n", 486 | ")" 487 | ] 488 | }, 489 | { 490 | "cell_type": "code", 491 | "execution_count": 276, 492 | "id": "3bf3c407", 493 | "metadata": {}, 494 | "outputs": [ 495 | { 496 | "name": "stdout", 497 | "output_type": "stream", 498 | "text": [ 499 | "Min Notional 10.0, My notional: 0.08089542\n", 500 | "Notional is too small\n", 501 | "Min Notional 10.0, My notional: 14.9656527\n" 502 | ] 503 | } 504 | ], 505 | "source": [ 506 | "# The Min Notional filter defines the minimum value calculated in the quote asset for a symbol.\n", 507 | "# For our symbol BTCUSDT the quote symbol is USDT, so the min notional values is in USDT.\n", 508 | "# notional_value = price * quantity\n", 509 | "min_notional = info['min_notional']\n", 510 | "my_notional = price * float(quantity)\n", 511 | "print(f\"Min Notional {min_notional}, My notional: {my_notional}\")\n", 512 | "if my_notional < min_notional:\n", 513 | " print('Notional is too small')\n", 514 | " \n", 515 | "# To fix this, we need to again increase our initial investment amount\n", 516 | "# Let's try $10\n", 517 | "quantity = float(15 / price)\n", 518 | "quantity = round_step_size(quantity, step_size)\n", 519 | "quantity = '{:.6f}'.format(float(quantity))\n", 520 | "\n", 521 | "my_notional = price * float(quantity)\n", 522 | "print(f\"Min Notional {min_notional}, My notional: {my_notional}\")\n", 523 | "if my_notional < min_notional:\n", 524 | " print('Notional is too small')" 525 | ] 526 | }, 527 | { 528 | "cell_type": "code", 529 | "execution_count": 277, 530 | "id": "a1f3f356", 531 | "metadata": {}, 532 | "outputs": [ 533 | { 534 | "name": "stdout", 535 | "output_type": "stream", 536 | "text": [ 537 | "{'clientOrderId': 'mmeixLfR2iPs95zKd8LlZI',\n", 538 | " 'cummulativeQuoteQty': '14.93689630',\n", 539 | " 'executedQty': '0.00037000',\n", 540 | " 'fills': [{'commission': '0.00000000',\n", 541 | " 'commissionAsset': 'BTC',\n", 542 | " 'price': '40369.99000000',\n", 543 | " 'qty': '0.00037000',\n", 544 | " 'tradeId': 1388670}],\n", 545 | " 'orderId': 4537488,\n", 546 | " 'orderListId': -1,\n", 547 | " 'origQty': '0.00037000',\n", 548 | " 'price': '0.00000000',\n", 549 | " 'side': 'BUY',\n", 550 | " 'status': 'FILLED',\n", 551 | " 'symbol': 'BTCUSDT',\n", 552 | " 'timeInForce': 'GTC',\n", 553 | " 'transactTime': 1650099083542,\n", 554 | " 'type': 'MARKET'}\n" 555 | ] 556 | } 557 | ], 558 | "source": [ 559 | "# Create a Buy Order\n", 560 | "order = client.create_order(\n", 561 | " symbol='BTCUSDT',\n", 562 | " quantity=quantity,\n", 563 | " side=SIDE_BUY,\n", 564 | " type=ORDER_TYPE_MARKET,\n", 565 | ")\n", 566 | "print(pformat(order))" 567 | ] 568 | }, 569 | { 570 | "cell_type": "code", 571 | "execution_count": 278, 572 | "id": "4763aa75", 573 | "metadata": {}, 574 | "outputs": [ 575 | { 576 | "name": "stdout", 577 | "output_type": "stream", 578 | "text": [ 579 | "btc_balance: 1.00733400\n", 580 | "usdt_balance: 9480.58547057\n" 581 | ] 582 | } 583 | ], 584 | "source": [ 585 | "btc_balance = client.get_asset_balance(asset='BTC').get('free')\n", 586 | "print('btc_balance: ',btc_balance)\n", 587 | "usdt_balance = client.get_asset_balance(asset='USDT').get('free')\n", 588 | "print('usdt_balance: ',usdt_balance)" 589 | ] 590 | }, 591 | { 592 | "cell_type": "code", 593 | "execution_count": null, 594 | "id": "30b6fb40", 595 | "metadata": {}, 596 | "outputs": [], 597 | "source": [] 598 | } 599 | ], 600 | "metadata": { 601 | "kernelspec": { 602 | "display_name": "Python [conda env:tradesystem1]", 603 | "language": "python", 604 | "name": "conda-env-tradesystem1-py" 605 | }, 606 | "language_info": { 607 | "codemirror_mode": { 608 | "name": "ipython", 609 | "version": 3 610 | }, 611 | "file_extension": ".py", 612 | "mimetype": "text/x-python", 613 | "name": "python", 614 | "nbconvert_exporter": "python", 615 | "pygments_lexer": "ipython3", 616 | "version": "3.9.5" 617 | } 618 | }, 619 | "nbformat": 4, 620 | "nbformat_minor": 5 621 | } 622 | -------------------------------------------------------------------------------- /crypto/Crypto Snapshot CoinGecko 1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 571, 6 | "id": "899b1b9b", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "from datetime import datetime\n", 11 | "import sys\n", 12 | "import os\n", 13 | "import math\n", 14 | "import numpy as np\n", 15 | "import pandas as pd\n", 16 | "import pandas_ta as ta\n", 17 | "import datetime\n", 18 | "from pandas.tseries.holiday import USFederalHolidayCalendar\n", 19 | "from pandas.tseries.offsets import CustomBusinessDay\n", 20 | "US_BUSINESS_DAY = CustomBusinessDay(calendar=USFederalHolidayCalendar())\n", 21 | "import matplotlib.pyplot as plt\n", 22 | "import plotly.graph_objects as go\n", 23 | "from plotly.subplots import make_subplots\n", 24 | "import itertools\n", 25 | "import matplotlib.dates as mpl_dates\n", 26 | "import yfinance as yf\n", 27 | "from os.path import exists\n", 28 | "from pycoingecko import CoinGeckoAPI\n", 29 | "from IPython import display\n", 30 | "import time\n", 31 | "from yattag import Doc" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 572, 37 | "id": "d95483d2", 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "def get_trending_results(cg):\n", 42 | " results_df = pd.DataFrame()\n", 43 | " response = cg.get_search_trending()\n", 44 | " trending_list = response['coins']\n", 45 | " for obj in trending_list:\n", 46 | " # Parse trending results\n", 47 | " item = obj['item']\n", 48 | " item_row = pd.DataFrame({'id': [item['id']], 'name':[item['name']],'symbol': [item['symbol']],'market_cap_rank': [item['market_cap_rank']],'thumb': [item['thumb']]})\n", 49 | " results_df = pd.concat([results_df, item_row], axis=0, ignore_index=True)\n", 50 | " return results_df" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 573, 56 | "id": "843b7448", 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [ 60 | "def plot_candlestick(coin_id, df, period):\n", 61 | " plot_info = f\"{coin_id}-ohlc-{period}\"\n", 62 | " fig = make_subplots(rows=1, cols=1, subplot_titles=[plot_info])\n", 63 | "\n", 64 | " # Plot close price\n", 65 | " fig.add_trace(go.Candlestick(x=df['epoch'],\n", 66 | " open=df['open'],\n", 67 | " high=df['high'],\n", 68 | " low=df['low'],\n", 69 | " close=df['close']), row = 1, col = 1) \n", 70 | " \n", 71 | " fig.update_layout(\n", 72 | " title={'text':'', 'x':0.5},\n", 73 | " autosize=False,\n", 74 | " width=800,height=600)\n", 75 | " fig.update_yaxes(range=[0,1000000000],secondary_y=True)\n", 76 | " fig.update_yaxes(visible=False, secondary_y=True) #hide range slider\n", 77 | " \n", 78 | " #fig.show()\n", 79 | " fig.write_image(f\"{plot_info}.png\", format=\"png\")" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 574, 85 | "id": "8dbf368c", 86 | "metadata": {}, 87 | "outputs": [], 88 | "source": [ 89 | "def get_coin_info(cg, coin_id):\n", 90 | " response = cg.get_coin_by_id(coin_id)\n", 91 | " categories = response['categories']\n", 92 | " public_notice = response['public_notice']\n", 93 | " name = response['name']\n", 94 | " description = response['description']['en']\n", 95 | " links = response['links']\n", 96 | " homepage_link = links['homepage']\n", 97 | " blockchain_site = \",\".join(links['blockchain_site'])\n", 98 | " official_forum_url = links['official_forum_url']\n", 99 | " chat_url = links['chat_url']\n", 100 | " announcement_url = links['announcement_url']\n", 101 | " twitter_screen_name = links['twitter_screen_name']\n", 102 | " facebook_username = links['facebook_username']\n", 103 | " telegram_channel_identifier = links['telegram_channel_identifier']\n", 104 | " subreddit_url = links['subreddit_url']\n", 105 | " sentiment_votes_up_percentage = response['sentiment_votes_up_percentage']\n", 106 | " sentiment_votes_down_percentage = response['sentiment_votes_down_percentage']\n", 107 | " market_cap_rank = response['market_cap_rank']\n", 108 | " coingecko_rank = response['coingecko_rank']\n", 109 | " coingecko_score = response['coingecko_score']\n", 110 | " community_score = response['community_score']\n", 111 | " liquidity_score = response['liquidity_score']\n", 112 | " public_interest_score = response['public_interest_score']\n", 113 | " \n", 114 | " row = pd.DataFrame({'id':[coin_id],'name':[name],'categories': [categories],'public_notice':[public_notice],\\\n", 115 | " 'description': [description],'homepage_link': [homepage_link], \\\n", 116 | " 'blockchain_site':[blockchain_site],'official_forum_url':[official_forum_url], \\\n", 117 | " 'chat_url': [chat_url],'announcement_url':[announcement_url], \\\n", 118 | " 'twitter_screen_name':[twitter_screen_name],'facebook_username':[facebook_username], \\\n", 119 | " 'telegram_channel_identifier': [telegram_channel_identifier],'subreddit_url':[subreddit_url], \\\n", 120 | " 'sentiment_votes_up_percentage':[sentiment_votes_up_percentage], \\\n", 121 | " 'sentiment_votes_down_percentage':[sentiment_votes_down_percentage], \\\n", 122 | " 'market_cap_rank': [market_cap_rank], \\\n", 123 | " 'coingecko_rank': [coingecko_rank], \\\n", 124 | " 'coingecko_score':[coingecko_score],'coingecko_score': [coingecko_score], \\\n", 125 | " 'community_score':[community_score],'liquidity_score': [liquidity_score], \\\n", 126 | " 'public_interest_score':[public_interest_score]})\n", 127 | " row = row.set_index('id')\n", 128 | " return row" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 575, 134 | "id": "0c53b544", 135 | "metadata": {}, 136 | "outputs": [], 137 | "source": [ 138 | "def get_ohlc(cg, coin_id, vs_currency, days):\n", 139 | " response = cg.get_coin_ohlc_by_id(coin_id, vs_currency=\"usd\", days=days)\n", 140 | " \n", 141 | " ohlc_df = pd.DataFrame()\n", 142 | " for ohlc in response:\n", 143 | " epoch = ohlc[0]\n", 144 | " #timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(epoch))\n", 145 | " #time = datetime.datetime.utcfromtimestamp(epoch).strftime('%Y-%m-%d %H:%M:%S')\n", 146 | " row = pd.DataFrame({'epoch':[ohlc[0]],'open':[ohlc[1]],'high':[ohlc[2]],'low':[ohlc[3]],'close':[ohlc[4]]})\n", 147 | " ohlc_df = pd.concat([ohlc_df, row], axis=0, ignore_index=True)\n", 148 | " \n", 149 | " return ohlc_df\n", 150 | " " 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": 576, 156 | "id": "fd407710", 157 | "metadata": {}, 158 | "outputs": [], 159 | "source": [ 160 | "def build_coin_section(coin_id, coin_info_df):\n", 161 | " doc, tag, text = Doc().tagtext()\n", 162 | " with tag('h1'):\n", 163 | " text(f\"{coin_id} report\")\n", 164 | "\n", 165 | " return doc.getvalue()\n", 166 | " " 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 577, 172 | "id": "dfdf3e1b", 173 | "metadata": {}, 174 | "outputs": [], 175 | "source": [ 176 | "def build_report(coin_ids, info_map):\n", 177 | " #doc, tag, text, line = Doc().tagtext()\n", 178 | " doc, tag, text, line = Doc().ttl()\n", 179 | " now_str = datetime.datetime.now().strftime(\"%d/%m/%Y %H:%M:%S\") \n", 180 | " \n", 181 | " with tag('html'):\n", 182 | " with tag('head'):\n", 183 | " with tag('style'):\n", 184 | " text(\"\"\"div{ width: 100%; }\n", 185 | " html { margin: 0; padding: 10px; background: #1e81b0;}\n", 186 | " body { font: 12px verdana, sans-serif;line-height: 1.88889; margin: 5%; background: #ffffff; padding: 1%; width: 90%; }\n", 187 | " p { margin-top: 5px; text-align: justify; font: normal 0.9em verdana, sans-serif;color:#484848}\n", 188 | " li { font: normal 0.8em verdana, sans-serif;color:#484848}\n", 189 | " h1 { font: normal 1.8em verdana, sans-serif; letter-spacing: 1px; margin-bottom: 0; color: #063970,}\n", 190 | " h2 { font: normal 1.6em verdana, sans-serif; letter-spacing: 1px; margin-bottom: 0; color: #154c79}\n", 191 | " h3 { font: normal 1.6em verdana, sans-serif; letter-spacing: 1px; margin-bottom: 0; color: #154c79}\n", 192 | " p.bold_text{ font: normal 0.9em verdana, sans-serif; letter-spacing: 1px; margin-bottom: 0; color: #154c79; font-weight: bold}\"\"\")\n", 193 | "\n", 194 | " with tag('body', id = 'body'):\n", 195 | " with tag('h1'):\n", 196 | " text(f\"Trending Crypto Report for {now_str}\")\n", 197 | " with tag('hr'):\n", 198 | " text('')\n", 199 | "\n", 200 | " for coin_id in coin_ids:\n", 201 | " coin_df = info_map[coin_id]\n", 202 | " with tag('h2'):\n", 203 | " text(f\"{coin_id.upper()}\")\n", 204 | " with tag('div'):\n", 205 | " line('p',f\"Name: {coin_df['name'].values[0]}\",klass=\"bold_text\")\n", 206 | " line('p',coin_df['name'].values[0])\n", 207 | " line('p',f\"Description:\",klass=\"bold_text\")\n", 208 | " line('p',coin_df['description'].values[0])\n", 209 | " line('p',f\"Categories:\",klass=\"bold_text\")\n", 210 | " category_list = \"\"\n", 211 | " if coin_df['categories'].values[0] is not None:\n", 212 | " for category_str in coin_df['categories'].values[0]:\n", 213 | " if category_str is None:\n", 214 | " continue\n", 215 | " if len(category_list) > 0:\n", 216 | " category_list += \", \"\n", 217 | " category_list += category_str \n", 218 | " line('p',f\"{category_list}\")\n", 219 | " line('p',f\"Public Notice:\",klass=\"bold_text\")\n", 220 | " line('p',f\"{coin_df['public_notice'].values[0]}\")\n", 221 | " line('p',f\"Links:\",klass=\"bold_text\")\n", 222 | " with tag('ul', id='links-list'):\n", 223 | " url_list = \"\"\n", 224 | " if coin_df['homepage_link'].values[0] is not None:\n", 225 | " for link_str in coin_df['homepage_link'].values[0]:\n", 226 | " url_list += link_str\n", 227 | " line('li', f\"Home Page: {url_list}\")\n", 228 | " line('li', f\"Blockchain Site: {coin_df['blockchain_site'].values[0]}\")\n", 229 | " url_list = \"\"\n", 230 | " if coin_df['official_forum_url'].values[0] is not None:\n", 231 | " for link_str in coin_df['official_forum_url'].values[0]:\n", 232 | " url_list += link_str\n", 233 | " line('li', f\"Official Forum URLs: {url_list}\")\n", 234 | " url_list = \"\"\n", 235 | " if coin_df['chat_url'].values[0] is not None:\n", 236 | " for link_str in coin_df['chat_url'].values[0]:\n", 237 | " url_list += link_str \n", 238 | " line('li', f\"Chat URLs: {url_list}\")\n", 239 | " line('p',f\"Social Media:\",klass=\"bold_text\")\n", 240 | " with tag('ul', id='social-list'):\n", 241 | " line('li', f\"Twitter: {coin_df['twitter_screen_name'].values[0]}\")\n", 242 | " line('li', f\"Facebook: {coin_df['facebook_username'].values[0]}\")\n", 243 | " line('li', f\"Telegram: {coin_df['telegram_channel_identifier'].values[0]}\")\n", 244 | " line('p',f\"Sentiment:\",klass=\"bold_text\")\n", 245 | " with tag('ul', id='sentiment-list'):\n", 246 | " line('li', f\"Votes Up: {coin_df['sentiment_votes_up_percentage'].values[0]}\")\n", 247 | " line('li', f\"Votes Down: {coin_df['sentiment_votes_down_percentage'].values[0]}\")\n", 248 | " line('p',f\"Ranks:\",klass=\"bold_text\")\n", 249 | " with tag('ul', id='sentiment-list'):\n", 250 | " line('li', f\"Market Cap Rank: {coin_df['market_cap_rank'].values[0]}\")\n", 251 | " line('li', f\"Gecko Rank: {coin_df['coingecko_rank'].values[0]}\")\n", 252 | " line('li', f\"Gecko Score: {coin_df['coingecko_score'].values[0]}\")\n", 253 | " line('li', f\"Community Score: {coin_df['community_score'].values[0]}\")\n", 254 | " line('li', f\"Public Interest Score: {coin_df['public_interest_score'].values[0]}\")\n", 255 | " with tag('div', id='photo-container'):\n", 256 | " line('p',f\"Day Plot:\",klass=\"bold_text\")\n", 257 | " doc.stag('img', src=f\"{coin_id}-ohlc-day.png\", klass=\"day_plot\")\n", 258 | " line('p',f\"Month Plot:\",klass=\"bold_text\")\n", 259 | " doc.stag('img', src=f\"{coin_id}-ohlc-month.png\", klass=\"day_plot\")\n", 260 | " with tag('hr'):\n", 261 | " text('')\n", 262 | "\n", 263 | " \n", 264 | " # Save report\n", 265 | " report_file = open(\"trending-coins-report.html\", \"w\")\n", 266 | " report_file.write(doc.getvalue() )\n", 267 | " report_file.close()\n", 268 | " " 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": 578, 274 | "id": "4a32147d", 275 | "metadata": {}, 276 | "outputs": [ 277 | { 278 | "name": "stdout", 279 | "output_type": "stream", 280 | "text": [ 281 | "Report generation complete\n" 282 | ] 283 | } 284 | ], 285 | "source": [ 286 | "# Initialize client\n", 287 | "cg = CoinGeckoAPI()\n", 288 | "\n", 289 | "# Get trending crypto\n", 290 | "results_df = get_trending_results(cg)\n", 291 | "results_df['coin_id'] = results_df['id']\n", 292 | "results_df = results_df.set_index('id')\n", 293 | "\n", 294 | "# Get coin info\n", 295 | "day_ohlc_map = {}\n", 296 | "month_ohlc_map = {}\n", 297 | "info_map = {}\n", 298 | "coin_ids = np.array(results_df['coin_id'])\n", 299 | "coin_sections_html = \"\"\n", 300 | "for coin_id in coin_ids:\n", 301 | " info_df = get_coin_info(cg, coin_id)\n", 302 | " info_map[coin_id] = info_df\n", 303 | "\n", 304 | " # Get daily prices - 30 min period\n", 305 | " day_ohlc_df = get_ohlc(cg, coin_id, vs_currency='usd', days=1)\n", 306 | " day_ohlc_map[coin_id] = day_ohlc_df\n", 307 | " plot_candlestick(coin_id, day_ohlc_df, 'day')\n", 308 | " \n", 309 | " # Get monthly prices - 4 hour period\n", 310 | " month_ohlc_df = get_ohlc(cg, coin_id, vs_currency='usd', days=30)\n", 311 | " month_ohlc_map[coin_id] = month_ohlc_df\n", 312 | " plot_candlestick(coin_id, month_ohlc_df, 'month')\n", 313 | "\n", 314 | "# Build report\n", 315 | "build_report(coin_ids, info_map)\n", 316 | "print('Report generation complete')" 317 | ] 318 | } 319 | ], 320 | "metadata": { 321 | "kernelspec": { 322 | "display_name": "Python [conda env:tradesystem1]", 323 | "language": "python", 324 | "name": "conda-env-tradesystem1-py" 325 | }, 326 | "language_info": { 327 | "codemirror_mode": { 328 | "name": "ipython", 329 | "version": 3 330 | }, 331 | "file_extension": ".py", 332 | "mimetype": "text/x-python", 333 | "name": "python", 334 | "nbconvert_exporter": "python", 335 | "pygments_lexer": "ipython3", 336 | "version": "3.9.5" 337 | } 338 | }, 339 | "nbformat": 4, 340 | "nbformat_minor": 5 341 | } 342 | -------------------------------------------------------------------------------- /crypto/binance_api_websockets.py: -------------------------------------------------------------------------------- 1 | import json 2 | import threading 3 | import time 4 | from binance import Client 5 | from pprint import pformat 6 | from unicorn_binance_websocket_api.manager import BinanceWebSocketApiManager 7 | 8 | 9 | # Testnet Binance 10 | TEST_API_KEY = '' 11 | TEST_API_SECRET = '' 12 | base_endpoint = 'https://api.binance.us' # NOTE: This may be different for your exchange. Check the docs 13 | 14 | 15 | def is_empty_message(message): 16 | if message is False: 17 | return True 18 | if '"result":null' in message: 19 | return True 20 | if '"result":None' in message: 21 | return True 22 | return False 23 | 24 | 25 | def handle_price_change(symbol, timestamp, price): 26 | print(f"Handle price change for symbol: {symbol}, timestamp: {timestamp}, price: {price}") 27 | 28 | 29 | def process_stream_data(binance_websocket_api_manager): 30 | while True: 31 | if binance_websocket_api_manager.is_manager_stopping(): 32 | exit(0) 33 | oldest_data = binance_websocket_api_manager.pop_stream_data_from_stream_buffer() 34 | 35 | is_empty = is_empty_message(oldest_data) 36 | if is_empty: 37 | time.sleep(0.01) 38 | else: 39 | oldest_data_dict = json.loads(oldest_data) 40 | data = oldest_data_dict['data'] 41 | 42 | # Handle price change 43 | handle_price_change(symbol=data['s'], timestamp=data['T'], price=data['p']) 44 | 45 | 46 | def start_websocket_listener(): 47 | binance_us_websocket_api_manager = BinanceWebSocketApiManager(exchange="binance.us") 48 | channels = {'trade', } 49 | 50 | binance_us_websocket_api_manager.create_stream(channels, markets=lc_symbols, api_key=TEST_API_KEY, api_secret=TEST_API_SECRET) 51 | 52 | # Start a worker process to move the received stream_data from the stream_buffer to a print function 53 | worker_thread = threading.Thread(target=process_stream_data, args=(binance_us_websocket_api_manager,)) 54 | worker_thread.start() 55 | 56 | 57 | def compare_server_times(): 58 | server_time = client.get_server_time() 59 | aa = str(server_time) 60 | bb = aa.replace("{'serverTime': ", "") 61 | aa = bb.replace("}", "") 62 | gg = int(aa) 63 | ff = gg - 10799260 64 | uu = ff / 1000 65 | yy = int(uu) 66 | tt = time.localtime(yy) 67 | print(f"Binance Server time: {tt}") 68 | print(f"Local time: {time.localtime()}") 69 | 70 | 71 | def get_traded_symbols(): 72 | symbols = [] 73 | exchange_info = client.get_exchange_info() 74 | for s in exchange_info['symbols']: 75 | symbols.append(s['symbol']) 76 | return symbols 77 | 78 | 79 | def get_exchange_info(): 80 | info = client.get_exchange_info() 81 | print(pformat(info)) 82 | tickers = client.get_all_tickers() 83 | print(pformat(tickers)) 84 | 85 | 86 | # Define symbols 87 | symbols = ['ETHUSDT', 'BTCUSDT', 'LTCUSDT',] 88 | lc_symbols = [] 89 | for symbol in symbols: 90 | lc_symbols.append(symbol.lower()) 91 | 92 | # Initialize binance client 93 | client = Client(api_key=TEST_API_KEY, api_secret=TEST_API_SECRET, testnet=True, tld='us') 94 | 95 | # Compare server and local times 96 | compare_server_times() 97 | 98 | # Get traded symbols 99 | traded_symbols = get_traded_symbols() 100 | print("Traded symbols: ", traded_symbols) 101 | 102 | start_websocket_listener() 103 | -------------------------------------------------------------------------------- /crypto/crypto-market-cap-1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 25, 6 | "id": "b26ae530", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import requests\n", 11 | "import pandas as pd" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 26, 17 | "id": "0d6d9430", 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "def getCoinMarketCapData(sort_by, sort_type, convert_to, convert_type, aux, limit):\n", 22 | " url = f\"https://api.coinmarketcap.com/data-api/v3/cryptocurrency/listing?start=0&limit={limit}&sortBy={sort_by}&sortType={sort_type}&convert={convert_to}&cryptoType={convert_type}&aux{aux}\"\n", 23 | " response = requests.request(\"GET\", url)\n", 24 | " coins = []\n", 25 | " for crypto in response.json()['data']['cryptoCurrencyList']:\n", 26 | " crypto_data = {\n", 27 | " 'name': crypto['name'],\n", 28 | " 'price': f\"{crypto['quotes'][2]['price']:.2f}\", # [0 for BTC / 1 for ETH / 2 for USD]\n", 29 | " 'change_1d': f\"{crypto['quotes'][2]['percentChange24h']:.2f}\", # [0 for BTC / 1 for ETH / 2 for USD]\n", 30 | " 'change_7d': f\"{crypto['quotes'][2]['percentChange7d']:.2f}\", # [0 for BTC / 1 for ETH / 2 for USD]\n", 31 | " 'market_cap': f\"{crypto['quotes'][2]['marketCap']:.0f}\", # [0 for BTC / 1 for ETH / 2 for USD]\n", 32 | " 'volume_1d': f\"{crypto['quotes'][2]['volume24h']:.0f}\", # [0 for BTC / 1 for ETH / 2 for USD]\n", 33 | " 'circulating_supply': f\"{crypto['circulatingSupply']:.0f}\"\n", 34 | " }\n", 35 | " coins.append(crypto_data)\n", 36 | " df = pd.DataFrame(coins)\n", 37 | " return df\n" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 27, 43 | "id": "e9193dc1", 44 | "metadata": {}, 45 | "outputs": [ 46 | { 47 | "name": "stdout", 48 | "output_type": "stream", 49 | "text": [ 50 | " name price change_1d change_7d market_cap volume_1d \\\n", 51 | "0 Bitcoin 36933.70 -5.12 -7.81 702904193404 39678671607 \n", 52 | "1 Ethereum 2755.30 -3.09 -6.63 332447411935 21472509083 \n", 53 | "2 Tether 1.00 -0.01 -0.02 83151888782 80852847471 \n", 54 | "3 BNB 380.15 -2.98 -6.30 62069907972 2255431854 \n", 55 | "4 USD Coin 1.00 0.02 -0.02 48734362715 4900073672 \n", 56 | "... ... ... ... ... ... ... \n", 57 | "10121 VIKTAMA 0.00 4.94 21.55 0 0 \n", 58 | "10122 Astronaut 0.00 0.00 0.00 0 0 \n", 59 | "10123 Tierra Meta 0.13 -0.47 0.52 0 0 \n", 60 | "10124 TOKAMAK 0.00 3.68 8.98 0 0 \n", 61 | "10125 APEBORG 0.00 -3.23 -50.13 0 0 \n", 62 | "\n", 63 | " circulating_supply \n", 64 | "0 19031512 \n", 65 | "1 120657566 \n", 66 | "2 83152377104 \n", 67 | "3 163276975 \n", 68 | "4 48733508388 \n", 69 | "... ... \n", 70 | "10121 0 \n", 71 | "10122 0 \n", 72 | "10123 0 \n", 73 | "10124 0 \n", 74 | "10125 0 \n", 75 | "\n", 76 | "[10126 rows x 7 columns]\n" 77 | ] 78 | } 79 | ], 80 | "source": [ 81 | "sort_by = 'market_cap'\n", 82 | "sort_type = 'desc'\n", 83 | "convert_to='USD,BTC,ETH'\n", 84 | "convert_type='all'\n", 85 | "aux='ath,atl,high24h,low24h,num_market_pairs,cmc_rank,date_added,max_supply,circulating_supply,total_supply,volume_7d,volume_30d,self_reported_circulating_supply,self_reported_market_cap'\n", 86 | "limit = '20000'\n", 87 | "df = getCoinMarketCapData(sort_by, sort_type, convert_to, convert_type, aux, limit)\n", 88 | "print(df)" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "id": "34381e42", 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [] 98 | } 99 | ], 100 | "metadata": { 101 | "kernelspec": { 102 | "display_name": "Python [conda env:tradesystem1]", 103 | "language": "python", 104 | "name": "conda-env-tradesystem1-py" 105 | }, 106 | "language_info": { 107 | "codemirror_mode": { 108 | "name": "ipython", 109 | "version": 3 110 | }, 111 | "file_extension": ".py", 112 | "mimetype": "text/x-python", 113 | "name": "python", 114 | "nbconvert_exporter": "python", 115 | "pygments_lexer": "ipython3", 116 | "version": "3.9.5" 117 | } 118 | }, 119 | "nbformat": 4, 120 | "nbformat_minor": 5 121 | } 122 | -------------------------------------------------------------------------------- /data/nasdaq_100.csv: -------------------------------------------------------------------------------- 1 | Symbol,Name,Market Cap 2 | AAPL,Apple Inc. Common Stock,"2,815,757,389,400" 3 | ABNB,"Airbnb, Inc. Class A Common Stock","93,473,616,367" 4 | ADBE,Adobe Inc. Common Stock,"237,857,178,000" 5 | ADI,"Analog Devices, Inc. Common Stock","83,800,748,797" 6 | ADP,"Automatic Data Processing, Inc. Common Stock","91,495,117,039" 7 | ADSK,"Autodesk, Inc. Common Stock","52,615,441,612" 8 | AEP,"American Electric Power Company, Inc. Common Stock","44,660,166,374" 9 | ALGN,"Align Technology, Inc. Common Stock","36,491,623,272" 10 | AMAT,"Applied Materials, Inc. Common Stock","120,002,599,275" 11 | AMD,"Advanced Micro Devices, Inc. Common Stock","143,476,198,159" 12 | AMGN,Amgen Inc. Common Stock,"128,266,911,203" 13 | AMZN,"Amazon.com, Inc. Common Stock","1,446,821,159,193" 14 | ANSS,"ANSYS, Inc. Common Stock","28,421,775,933" 15 | ASML,ASML Holding N.V. New York Registry Shares,"282,390,009,933" 16 | ATVI,"Activision Blizzard, Inc. Common Stock","63,362,586,308" 17 | AVGO,Broadcom Inc. Common Stock,"220,156,785,957" 18 | BIDU,"Baidu, Inc. ADS","54,589,522,587" 19 | BIIB,Biogen Inc. Common Stock,"32,392,780,850" 20 | BKNG,Booking Holdings Inc. Common Stock,"96,329,186,922" 21 | CDNS,"Cadence Design Systems, Inc. Common Stock","41,100,010,300" 22 | CHTR,"Charter Communications, Inc. Class A Common Stock New","116,729,012,145" 23 | CMCSA,Comcast Corporation Class A Common Stock,"227,212,543,028" 24 | COST,Costco Wholesale Corporation Common Stock,"213,561,519,582" 25 | CPRT,"Copart, Inc. (DE) Common Stock","30,049,406,124" 26 | CRWD,"CrowdStrike Holdings, Inc. Class A Common Stock","37,779,065,195" 27 | CSCO,"Cisco Systems, Inc. Common Stock (DE)","239,053,939,537" 28 | CSX,CSX Corporation Common Stock,"75,633,234,315" 29 | CTAS,Cintas Corporation Common Stock,"39,367,549,918" 30 | CTSH,Cognizant Technology Solutions Corporation Class A Common Stock,"44,257,711,107" 31 | DDOG,"Datadog, Inc. Class A Common Stock","39,173,655,002" 32 | DLTR,Dollar Tree Inc. Common Stock,"28,396,203,328" 33 | DOCU,"DocuSign, Inc. Common Stock","22,979,400,616" 34 | DXCM,"DexCom, Inc. Common Stock","40,910,790,551" 35 | EA,Electronic Arts Inc. Common Stock,"39,313,159,958" 36 | EBAY,eBay Inc. Common Stock,"37,272,265,121" 37 | EXC,Exelon Corporation Common Stock,"55,539,100,768" 38 | FAST,Fastenal Company Common Stock,"32,508,232,768" 39 | FB,"Meta Platforms, Inc. Class A Common Stock","854,770,989,368" 40 | FISV,"Fiserv, Inc. Common Stock","69,231,919,970" 41 | FTNT,"Fortinet, Inc. Common Stock","47,194,214,384" 42 | GILD,"Gilead Sciences, Inc. Common Stock","85,937,815,092" 43 | GOOG,Alphabet Inc. Class C Capital Stock,"1,727,007,710,149" 44 | GOOGL,Alphabet Inc. Class A Common Stock,"1,730,452,645,278" 45 | HON,Honeywell International Inc. Common Stock,"141,195,552,173" 46 | IDXX,"IDEXX Laboratories, Inc. Common Stock","42,562,999,472" 47 | ILMN,"Illumina, Inc. Common Stock","57,196,422,000" 48 | INTC,Intel Corporation Common Stock,"211,646,680,000" 49 | INTU,Intuit Inc. Common Stock,"149,667,864,995" 50 | ISRG,"Intuitive Surgical, Inc. Common Stock","96,286,051,145" 51 | JD,"JD.com, Inc. American Depositary Shares","114,103,177,470" 52 | KDP,Keurig Dr Pepper Inc. Common Stock,"53,641,487,101" 53 | KHC,The Kraft Heinz Company Common Stock,"45,289,571,057" 54 | KLAC,KLA Corporation Common Stock,"56,559,616,210" 55 | LCID,"Lucid Group, Inc. Common Stock","62,150,352,174" 56 | LRCX,Lam Research Corporation Common Stock,"85,294,442,656" 57 | LULU,lululemon athletica inc. Common Stock,"40,471,581,273" 58 | MAR,Marriott International Class A Common Stock,"51,128,989,869" 59 | MCHP,Microchip Technology Incorporated Common Stock,"40,688,669,311" 60 | MDLZ,"Mondelez International, Inc. Class A Common Stock","95,360,294,944" 61 | MELI,"MercadoLibre, Inc. Common Stock","53,111,080,832" 62 | MNST,Monster Beverage Corporation,"45,304,891,026" 63 | MRNA,"Moderna, Inc. Common Stock","64,900,305,787" 64 | MRVL,"Marvell Technology, Inc. Common Stock","61,217,690,000" 65 | MSFT,Microsoft Corporation Common Stock,"2,222,587,450,837" 66 | MTCH,"Match Group, Inc. Common Stock","32,792,602,542" 67 | MU,"Micron Technology, Inc. Common Stock","91,743,338,622" 68 | NFLX,"Netflix, Inc. Common Stock","176,073,497,115" 69 | NTES,"NetEase, Inc. American Depositary Shares","260,313,663,837" 70 | NVDA,NVIDIA Corporation Common Stock,"584,350,000,000" 71 | NXPI,NXP Semiconductors N.V. Common Stock,"53,173,353,138" 72 | OKTA,"Okta, Inc. Class A Common Stock","29,282,677,106" 73 | ORLY,"O'Reilly Automotive, Inc. Common Stock","42,847,269,584" 74 | PANW,"Palo Alto Networks, Inc. Common Stock","47,718,031,516" 75 | PAYX,"Paychex, Inc. Common Stock","42,811,032,003" 76 | PCAR,PACCAR Inc. Common Stock,"31,787,555,694" 77 | PDD,Pinduoduo Inc. American Depositary Shares,"78,217,754,070" 78 | PEP,"PepsiCo, Inc. Common Stock","240,885,795,729" 79 | PTON,"Peloton Interactive, Inc. Class A Common Stock","8,935,160,694" 80 | PYPL,"PayPal Holdings, Inc. Common Stock","192,148,080,329" 81 | QCOM,QUALCOMM Incorporated Common Stock,"184,721,600,000" 82 | REGN,"Regeneron Pharmaceuticals, Inc. Common Stock","66,827,231,385" 83 | ROST,"Ross Stores, Inc. Common Stock","33,718,256,611" 84 | SBUX,Starbucks Corporation Common Stock,"112,990,892,000" 85 | SGEN,Seagen Inc. Common Stock,"23,323,256,652" 86 | SIRI,Sirius XM Holdings Inc. Common Stock,"24,036,957,882" 87 | SNPS,"Synopsys, Inc. Common Stock","46,539,381,692" 88 | SPLK,Splunk Inc. Common Stock,"18,304,985,649" 89 | SWKS,"Skyworks Solutions, Inc. Common Stock","23,137,676,695" 90 | TEAM,Atlassian Corporation Plc Class A Ordinary Shares,"71,528,766,192" 91 | TMUS,"T-Mobile US, Inc. Common Stock","126,928,819,617" 92 | TSLA,"Tesla, Inc. Common Stock","947,925,593,803" 93 | TXN,Texas Instruments Incorporated Common Stock,"162,208,114,895" 94 | VRSK,"Verisk Analytics, Inc. Common Stock","31,602,134,024" 95 | VRSN,"VeriSign, Inc. Common Stock","24,119,571,593" 96 | VRTX,Vertex Pharmaceuticals Incorporated Common Stock,"57,989,782,019" 97 | WBA,"Walgreens Boots Alliance, Inc. Common Stock","45,321,781,418" 98 | WDAY,"Workday, Inc. Class A Common Stock","61,422,500,000" 99 | XEL,Xcel Energy Inc. Common Stock,"36,748,447,385" 100 | XLNX,"Xilinx, Inc. Common Stock","46,549,463,133" 101 | ZM,"Zoom Video Communications, Inc. Class A Common Stock","44,001,877,911" 102 | ZS,"Zscaler, Inc. Common Stock","33,891,361,417" 103 | -------------------------------------------------------------------------------- /data_loads/Load-Historic-Crypto-Prices.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 26, 6 | "id": "033341e1", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import os\n", 11 | "import numpy as np\n", 12 | "import pandas as pd\n", 13 | "import datetime\n", 14 | "import time\n", 15 | "from datetime import date\n", 16 | "import pandas_ta as ta\n", 17 | "import matplotlib.pyplot as plt\n", 18 | "import plotly.graph_objects as go\n", 19 | "from plotly.subplots import make_subplots\n", 20 | "from yahoo_fin import stock_info as si\n", 21 | "import datetime\n", 22 | "import yfinance as yf\n", 23 | "from random import randint\n", 24 | "from time import sleep" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 29, 30 | "id": "9d6f3276", 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "def load_historic_data(symbol, start_date_str, today_date_str, period, interval, prepost):\n", 35 | " try:\n", 36 | " df = yf.download(symbol, start=start_date_str, end=today_date_str, period=period, interval=interval, prepost=prepost)\n", 37 | " # Add symbol\n", 38 | " df[\"Symbol\"] = symbol\n", 39 | " return df\n", 40 | " except:\n", 41 | " print('Error loading stock data for ' + symbols)\n", 42 | " return None" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 30, 48 | "id": "7627e070", 49 | "metadata": {}, 50 | "outputs": [ 51 | { 52 | "name": "stdout", 53 | "output_type": "stream", 54 | "text": [ 55 | "Loading data for BTC-USD\n", 56 | "[*********************100%***********************] 1 of 1 completed\n", 57 | "Loading data for ETH-USD\n", 58 | "[*********************100%***********************] 1 of 1 completed\n", 59 | "Loading data for BCH-USD\n", 60 | "[*********************100%***********************] 1 of 1 completed\n", 61 | "Loading data for LTC-USD\n", 62 | "[*********************100%***********************] 1 of 1 completed\n", 63 | "Loading data for BNB-USD\n", 64 | "[*********************100%***********************] 1 of 1 completed\n" 65 | ] 66 | }, 67 | { 68 | "ename": "PermissionError", 69 | "evalue": "[Errno 13] Permission denied: 'C:\\\\dev\\\\trading\\\\tradesystem1\\\\data\\\\crypto\\\\2022-04-28_BNB-USD_1d_1m.csv'", 70 | "output_type": "error", 71 | "traceback": [ 72 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 73 | "\u001b[1;31mPermissionError\u001b[0m Traceback (most recent call last)", 74 | "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_12448/643487205.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 21\u001b[0m \u001b[1;31m# Save df\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 22\u001b[0m \u001b[0mfile_name\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34mf\"{today_date_str}_{symbol}_{period}_{interval}.csv\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 23\u001b[1;33m \u001b[0mdf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mto_csv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34mf\"C:\\\\dev\\\\trading\\\\tradesystem1\\\\data\\\\crypto\\\\{file_name}\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 24\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 25\u001b[0m \u001b[1;31m# Avoid DOS issues\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 75 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\pandas\\core\\generic.py\u001b[0m in \u001b[0;36mto_csv\u001b[1;34m(self, path_or_buf, sep, na_rep, float_format, columns, header, index, index_label, mode, encoding, compression, quoting, quotechar, line_terminator, chunksize, date_format, doublequote, escapechar, decimal, errors, storage_options)\u001b[0m\n\u001b[0;32m 3561\u001b[0m )\n\u001b[0;32m 3562\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 3563\u001b[1;33m return DataFrameRenderer(formatter).to_csv(\n\u001b[0m\u001b[0;32m 3564\u001b[0m \u001b[0mpath_or_buf\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3565\u001b[0m \u001b[0mline_terminator\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mline_terminator\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 76 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\pandas\\io\\formats\\format.py\u001b[0m in \u001b[0;36mto_csv\u001b[1;34m(self, path_or_buf, encoding, sep, columns, index_label, mode, compression, quoting, quotechar, line_terminator, chunksize, date_format, doublequote, escapechar, errors, storage_options)\u001b[0m\n\u001b[0;32m 1178\u001b[0m \u001b[0mformatter\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfmt\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1179\u001b[0m )\n\u001b[1;32m-> 1180\u001b[1;33m \u001b[0mcsv_formatter\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msave\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1181\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1182\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mcreated_buffer\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 77 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\pandas\\io\\formats\\csvs.py\u001b[0m in \u001b[0;36msave\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 239\u001b[0m \"\"\"\n\u001b[0;32m 240\u001b[0m \u001b[1;31m# apply compression and byte/text conversion\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 241\u001b[1;33m with get_handle(\n\u001b[0m\u001b[0;32m 242\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfilepath_or_buffer\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 243\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmode\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 78 | "\u001b[1;32m~\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\pandas\\io\\common.py\u001b[0m in \u001b[0;36mget_handle\u001b[1;34m(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)\u001b[0m\n\u001b[0;32m 787\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mioargs\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mencoding\u001b[0m \u001b[1;32mand\u001b[0m \u001b[1;34m\"b\"\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mioargs\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmode\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 788\u001b[0m \u001b[1;31m# Encoding\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 789\u001b[1;33m handle = open(\n\u001b[0m\u001b[0;32m 790\u001b[0m \u001b[0mhandle\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 791\u001b[0m \u001b[0mioargs\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmode\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 79 | "\u001b[1;31mPermissionError\u001b[0m: [Errno 13] Permission denied: 'C:\\\\dev\\\\trading\\\\tradesystem1\\\\data\\\\crypto\\\\2022-04-28_BNB-USD_1d_1m.csv'" 80 | ] 81 | } 82 | ], 83 | "source": [ 84 | "# valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max\n", 85 | "# fetch data by interval (including intraday if period < 60 days)\n", 86 | " # valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo\n", 87 | "period = '1d'\n", 88 | "TE: 7 days is the max allowed\n", 89 | "days = datetime.timedelta(7)\n", 90 | "start_date = today - days\n", 91 | "start_date_str = datetime.datetime.strftime(start_date, \"%Y-%m-%d\")\n", 92 | "\n", 93 | "# Fetch data for coin symbols\n", 94 | "symbols = ['BTC-USD','ETH-USD','BCH-USD','LTC-USD','BNB-USD','BAT-USD',\n", 95 | " 'XLM-USD','DOGE-USD','DOGE-USD','COMP-USD','ALGO-USD','OMG-USD']\n", 96 | "for symbol in symbols:\n", 97 | " print(f\"Loading data for {symbol}\")\n", 98 | " df = load_historic_data(symbol, start_date_str, today_date_str, period, interval, prepost)\n", 99 | " # Save df\n", 100 | " file_name = f\"{today_date_str}_{symbol}_{period}_{interval}.csv\"\n", 101 | " df.to_csv(f\"C:\\\\dev\\\\trading\\\\tradesystem1\\\\data\\\\crypto\\\\{file_name}\")\n", 102 | " \n", 103 | " # Avoid DOS issues\n", 104 | " sleep(randint(0,3))interval = '1m'\n", 105 | "prepost = True\n", 106 | "today = datetime.date.today()\n", 107 | "today_date_str = today.strftime(\"%Y-%m-%d\")\n", 108 | "\n", 109 | "# NO" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": null, 115 | "id": "2bacca3a", 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [ 119 | "def plot_graph(df):\n", 120 | " fig = make_subplots(rows=1, cols=1)\n", 121 | "\n", 122 | " # Plot close price\n", 123 | " fig.add_trace(go.Line(x = df.index, y = df['Close'], line=dict(color=\"blue\", width=1), name=\"Close\"), row = 1, col = 1)\n", 124 | " \n", 125 | " fig.update_layout(\n", 126 | " title={'text':'7 days, 1m interval', 'x':0.5},\n", 127 | " autosize=False,\n", 128 | " width=800,height=400)\n", 129 | " fig.update_yaxes(range=[0,1000000000],secondary_y=True)\n", 130 | " fig.update_yaxes(visible=False, secondary_y=True) #hide range slider\n", 131 | " \n", 132 | " fig.show()" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": null, 138 | "id": "213ef3fa", 139 | "metadata": {}, 140 | "outputs": [], 141 | "source": [ 142 | "df = load_historic_data('BTC-USD', start_date_str, today_date_str, period, interval, prepost)\n", 143 | "plot_graph(df)" 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": null, 149 | "id": "d7f992e7", 150 | "metadata": {}, 151 | "outputs": [], 152 | "source": [] 153 | } 154 | ], 155 | "metadata": { 156 | "kernelspec": { 157 | "display_name": "Python [conda env:tradesystem1]", 158 | "language": "python", 159 | "name": "conda-env-tradesystem1-py" 160 | }, 161 | "language_info": { 162 | "codemirror_mode": { 163 | "name": "ipython", 164 | "version": 3 165 | }, 166 | "file_extension": ".py", 167 | "mimetype": "text/x-python", 168 | "name": "python", 169 | "nbconvert_exporter": "python", 170 | "pygments_lexer": "ipython3", 171 | "version": "3.9.5" 172 | } 173 | }, 174 | "nbformat": 4, 175 | "nbformat_minor": 5 176 | } 177 | -------------------------------------------------------------------------------- /news_analysis/news_correlation_tester.py: -------------------------------------------------------------------------------- 1 | 2 | import pandas as pd 3 | import math 4 | from plotly.subplots import make_subplots 5 | import plotly.graph_objects as go 6 | import numpy as np 7 | import datetime 8 | from pandas.tseries.holiday import USFederalHolidayCalendar 9 | from pandas.tseries.offsets import CustomBusinessDay 10 | US_BUSINESS_DAY = CustomBusinessDay(calendar=USFederalHolidayCalendar()) 11 | from yahoo_fin import stock_info as si 12 | from setup import * 13 | import time 14 | import requests 15 | from transformers import AutoTokenizer, AutoModelForSequenceClassification 16 | import torch 17 | import os 18 | os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" 19 | 20 | # Based on https://wandb.ai/ivangoncharov/FinBERT_Sentiment_Analysis_Project/reports/Financial-Sentiment-Analysis-on-Stock-Market-Headlines-With-FinBERT-Hugging-Face--VmlldzoxMDQ4NjM0 21 | 22 | # Init tokenizers and finbert model 23 | tokenizer = AutoTokenizer.from_pretrained("ProsusAI/finbert") 24 | model = AutoModelForSequenceClassification.from_pretrained("ProsusAI/finbert") 25 | 26 | 27 | # Newsfilter API endpoint 28 | API_KEY = "" 29 | 30 | 31 | def load_daily_data(symbol, past_days): 32 | today = datetime.date.today() 33 | today_str = today.strftime("%Y-%m-%d") 34 | start_date = today - (past_days * US_BUSINESS_DAY) 35 | start_date_str = datetime.datetime.strftime(start_date, "%Y-%m-%d") 36 | try: 37 | # Download data from Yahoo Finance 38 | df = si.get_data(symbol, start_date=start_date_str, end_date=today_str, index_as_date=False) 39 | df["date"] = pd.to_datetime(df["date"], utc=True) 40 | return df 41 | except: 42 | print('Error loading stock data for ' + symbol) 43 | return None 44 | 45 | 46 | def fetch_news(symbol, start_date_str, end_date_str, limit, offset=0): 47 | url = f'https://eodhistoricaldata.com/api/news?api_token={API_KEY}&s={symbol}&limit={limit}&offset={offset}&from={start_date_str}&to={end_date_str}' 48 | news_json = requests.get(url).json() 49 | 50 | results_df = pd.DataFrame() 51 | for item in news_json: 52 | 53 | title = item['title'] 54 | desc = item['content'] 55 | date = pd.to_datetime(item["date"], utc=True) 56 | result_df = pd.DataFrame({"title": [title], "desc": [desc], "date": [date]}) 57 | results_df = pd.concat([results_df, result_df], axis=0, ignore_index=True) 58 | 59 | return results_df 60 | 61 | 62 | def load_news(symbol, past_days): 63 | limit = 30 64 | today = datetime.datetime.today() 65 | today_date_str = today.strftime("%Y-%m-%d") 66 | news_df = pd.DataFrame() 67 | # Get news for each day 68 | for i in range(0, past_days): 69 | start_day = past_days - i 70 | end_day = past_days - i - 1 71 | start_date_str = get_biz_days_delta_date(today_date_str, - start_day) 72 | end_date_str = get_biz_days_delta_date(today_date_str, - end_day) 73 | 74 | # Fetch news 75 | if i % 10 == 0: 76 | print(f"Fetching news for day {start_day} of {past_days}") 77 | day_news_df = fetch_news(symbol, start_date_str, end_date_str, limit, 0) 78 | news_df = pd.concat([news_df, day_news_df]) 79 | # Throttle requests 80 | if i % 20 == 0: 81 | time.sleep(2) 82 | 83 | return news_df 84 | 85 | 86 | def is_empty_string(str): 87 | if str == '' or (isinstance(str, float) and math.isnan(str)): 88 | return True 89 | else: 90 | return False 91 | 92 | 93 | def perform_sentiment_analysis(df): 94 | results_df = pd.DataFrame([], columns=['date', 'positive','negative']) 95 | 96 | count = 0 97 | headlines = [] 98 | dates = [] 99 | for index, row in df.iterrows(): 100 | count += 1 101 | if count % 10 == 0: 102 | print(f"Performing sentiment analysis {count} of {len(df)}") 103 | 104 | date = row["date"] 105 | title = row["title"] 106 | desc = row["desc"] 107 | 108 | if is_empty_string(title) or is_empty_string(desc): 109 | continue 110 | 111 | headlines.append(title) 112 | dates.append(date) 113 | 114 | if len(headlines) == 0: 115 | return results_df 116 | 117 | # Run sentiment analysis 118 | inputs = tokenizer(headlines, padding=True, truncation=True, return_tensors='pt') 119 | 120 | outputs = model(** inputs) 121 | 122 | predictions = torch.nn.functional.softmax(outputs.logits, dim=-1) 123 | 124 | positive = predictions[:,0].tolist() 125 | negative = predictions[:,1].tolist() 126 | neutral = predictions[:,2].tolist() 127 | 128 | table = {"headline": headlines, 129 | "positive": positive, 130 | "negative": negative, 131 | "neutral": neutral, 132 | "date": dates} 133 | 134 | results_df = pd.DataFrame(table, columns=["headline", "positive", "negative", "neutral", "date"]) 135 | 136 | return results_df 137 | 138 | 139 | def plot_graphs(symbol, df): 140 | fig = make_subplots(rows=2, cols=1, subplot_titles=["Close", "Sentiment",]) 141 | 142 | # Plot close price 143 | fig.add_trace(go.Line(x=df.index, y=df['close'], line=dict(color="blue", width=1), name=name), 144 | row=1, col=1) 145 | 146 | # Plot the histogram 147 | fig.append_trace( 148 | go.Bar( 149 | x=df.index, 150 | y=df['positive'], 151 | name='Positive Sentiment', 152 | marker_color="green", 153 | ), row=2, col=1 154 | ) 155 | 156 | # Plot the histogram 157 | df['negative'] *= -1 158 | fig.append_trace( 159 | go.Bar( 160 | x=df.index, 161 | y=df['negative'], 162 | name='Negative Sentiment', 163 | marker_color="red", 164 | ), row=2, col=1 165 | ) 166 | 167 | fig.update_layout( 168 | title={'text': f"{name} News Correlation", 'x': 0.5}, 169 | autosize=True, 170 | width=800, height=1200) 171 | 172 | # Save file 173 | file_name = f"{symbol}_news_correlation.png" 174 | file_path = os.path.join(NEWS_RESULTS_DIR, file_name) 175 | fig.write_image(file_path, format="png") 176 | 177 | 178 | def get_biz_days_delta_date(start_date_str, delta_days): 179 | start_date = datetime.datetime.strptime(start_date_str, "%Y-%m-%d") 180 | end_date = start_date + (delta_days * US_BUSINESS_DAY) 181 | end_date_str = datetime.datetime.strftime(end_date, "%Y-%m-%d") 182 | return end_date_str 183 | 184 | 185 | symbol = 'TSLA' 186 | name = 'Telsa' 187 | past_days = 100 188 | news_df = load_news(symbol, past_days) 189 | news_df.fillna(0) 190 | news_df.to_csv('news_df.csv') 191 | 192 | # Perform sentiment analysis 193 | results_df = perform_sentiment_analysis(news_df) 194 | 195 | # Group by date 196 | grouped_df = results_df.set_index('date').groupby(pd.Grouper(freq='D')).sum() 197 | 198 | # Load daily stock price info 199 | daily_df = load_daily_data(symbol, past_days) 200 | 201 | # Merge with news df 202 | merged_df = pd.merge(daily_df, grouped_df, how="outer", on="date") 203 | merged_df = merged_df.dropna() 204 | 205 | # Plot graphs 206 | #plot_graphs(symbol, merged_df) 207 | 208 | # Normalize prices and sentiments for correlation calculation 209 | merged_df['close_norm'] = (merged_df['close'] - merged_df['close'].min()) / (merged_df['close'].max() - merged_df['close'].min()) 210 | merged_df['positive_norm'] = (merged_df['positive'] - merged_df['positive'].min()) / (merged_df['positive'].max() - merged_df['positive'].min()) 211 | merged_df['negative_norm'] = (merged_df['negative'] - merged_df['negative'].min()) / (merged_df['negative'].max() - merged_df['negative'].min()) 212 | 213 | # Calculate correlation 214 | news_pos_corr = merged_df['close_norm'].corr(merged_df['positive_norm']) 215 | news_neg_corr = merged_df['close_norm'].corr(merged_df['negative_norm']) 216 | print('Pos correlation: ', str(round(news_pos_corr, 2))) 217 | print('Neg correlation: ', str(round(news_neg_corr, 2))) 218 | 219 | 220 | -------------------------------------------------------------------------------- /samples/crypto-screener-report/screener-coins-report.html: -------------------------------------------------------------------------------- 1 |

Trending Crypto Report for 22/05/2022 19:12:46


COINSALE

Name: Coinsale

Coinsale

Description:

Coinsale is decentralized IDO platform. Coinsale is a strong solution partner for cryptocurrency projects to sell tokens, increase liquidity, and reach new investors. Coinsale allows you to invest in projects at IDO events that will be held on its platform by staking its own token. Thanks to this platform which provides the opportunity to invest first, you will be one of the first investors of the projects. It serves to solve the problems created by many similar platforms, to minimize the costs of participation in IDO events and to reach larger audiences. While some platforms do not guarantee you to invest in projects even though you stake their own token, Coinsale, on the contrary aims to ensure that all stakers participate in IDO events without any problems. There are absolutely no bot systems on the Coinsale platform and this is not tolerated. It is ensured that all investors and platform users participate in IDO sales without any problems.

Categories:

Binance Smart Chain Ecosystem

Public Notice:

None

Links:

Social Media:

  • Twitter: coinsalefinance
  • Facebook:
  • Telegram: coinsalenews

Sentiment:

  • Votes Up: None
  • Votes Down: None

Ranks:

  • Market Cap Rank: None
  • Gecko Rank: 8226
  • Gecko Score: 2.208
  • Community Score: 9.127
  • Public Interest Score: 0.0

Day Plot:

Month Plot:


CRYPTOPUNT

Name: CryptoPunt

CryptoPunt

Description:

CryptoPunt is a Polygon-based gaming and gambling platform that offers cutting-edge gaming experiences. 10 | 11 | Every game has an openly auditable algorithm allowing gamers to verify the fairness of their games.

Categories:

Public Notice:

None

Links:

Social Media:

  • Twitter: puntcrypto
  • Facebook:
  • Telegram: CryptoPunt

Sentiment:

  • Votes Up: None
  • Votes Down: None

Ranks:

  • Market Cap Rank: None
  • Gecko Rank: 9025
  • Gecko Score: 2.028
  • Community Score: 8.308
  • Public Interest Score: 0.0

Day Plot:

Month Plot:


IDLE-DAI-RISK-ADJUSTED

Name: IdleDAI (Risk Adjusted)

IdleDAI (Risk Adjusted)

Description:

Categories:

Public Notice:

None

Links:

Social Media:

  • Twitter:
  • Facebook:
  • Telegram:

Sentiment:

  • Votes Up: None
  • Votes Down: None

Ranks:

  • Market Cap Rank: None
  • Gecko Rank: 12394
  • Gecko Score: 0.2
  • Community Score: 0.0
  • Public Interest Score: 0.002

Day Plot:

Month Plot:


-------------------------------------------------------------------------------- /samples/trending-crypto-report/baby-doge-coin-ohlc-day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/baby-doge-coin-ohlc-day.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/baby-doge-coin-ohlc-month.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/baby-doge-coin-ohlc-month.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/constitutiondao-ohlc-day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/constitutiondao-ohlc-day.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/constitutiondao-ohlc-month.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/constitutiondao-ohlc-month.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/fantom-ohlc-day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/fantom-ohlc-day.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/fantom-ohlc-month.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/fantom-ohlc-month.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/gods-unchained-ohlc-day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/gods-unchained-ohlc-day.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/gods-unchained-ohlc-month.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/gods-unchained-ohlc-month.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/green-satoshi-token-ohlc-day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/green-satoshi-token-ohlc-day.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/green-satoshi-token-ohlc-month.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/green-satoshi-token-ohlc-month.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/terra-luna-ohlc-day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/terra-luna-ohlc-day.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/terra-luna-ohlc-month.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/terra-luna-ohlc-month.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/terrausd-ohlc-day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/terrausd-ohlc-day.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/terrausd-ohlc-month.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/terrausd-ohlc-month.png -------------------------------------------------------------------------------- /samples/trending-crypto-report/trending-coins-report.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botradingblog1/python-algorithmic-trading/e6031db8edfde45c541b8016e0f25ad96c973937/samples/trending-crypto-report/trending-coins-report.html -------------------------------------------------------------------------------- /screeners/Stock Value Screener 1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 96, 6 | "id": "fd0b1a92", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import os\n", 11 | "import numpy as np\n", 12 | "import pandas as pd\n", 13 | "from datetime import datetime, timedelta\n", 14 | "import simfin as sf\n", 15 | "from simfin.names import *" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 97, 21 | "id": "aa959ae6", 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "# Set the SimFin data-directory\n", 26 | "sf.set_data_dir(\"C:\\\\dev\\\\trading\\\\tradesystem1\\\\data\\\\simfin\")" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 98, 32 | "id": "00f124d8", 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "# Set your API Key\n", 37 | "sf_api_key = \"\"\n", 38 | "sf.set_api_key(sf_api_key)" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 99, 44 | "id": "da364502", 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "# Configure SimFin hub with cache refresh params\n", 49 | "variant = 'latest' # latest or ttm\n", 50 | "hub = sf.StockHub(market='us',\n", 51 | " refresh_days=30,\n", 52 | " refresh_days_shareprices=1)\n" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 100, 58 | "id": "1bf297b0", 59 | "metadata": {}, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "Dataset \"us-income-quarterly\" on disk (0 days old).\n", 66 | "- Loading from disk ... Done!\n", 67 | "Ticker\n", 68 | "Report Date\n", 69 | "SimFinId\n", 70 | "Currency\n", 71 | "Fiscal Year\n", 72 | "Fiscal Period\n", 73 | "Publish Date\n", 74 | "Restated Date\n", 75 | "Shares (Basic)\n", 76 | "Shares (Diluted)\n", 77 | "Revenue\n", 78 | "Cost of Revenue\n", 79 | "Gross Profit\n", 80 | "Operating Expenses\n", 81 | "Selling, General & Administrative\n", 82 | "Research & Development\n", 83 | "Depreciation & Amortization\n", 84 | "Operating Income (Loss)\n", 85 | "Non-Operating Income (Loss)\n", 86 | "Interest Expense, Net\n", 87 | "Pretax Income (Loss), Adj.\n", 88 | "Abnormal Gains (Losses)\n", 89 | "Pretax Income (Loss)\n", 90 | "Income Tax (Expense) Benefit, Net\n", 91 | "Income (Loss) from Continuing Operations\n", 92 | "Net Extraordinary Gains (Losses)\n", 93 | "Net Income\n", 94 | "Net Income (Common)\n", 95 | " Ticker INCOME_GROWTH_MA4\n", 96 | "0 ADI 0.202279\n", 97 | "1 AI 0.298943\n", 98 | "2 AMBA 1.925286\n", 99 | "3 AMSWA 0.422999\n", 100 | "4 ASPU 0.305638\n", 101 | ".. ... ...\n", 102 | "59 VALU 0.332183\n", 103 | "60 VLGEA 0.737297\n", 104 | "61 VMW 1.364544\n", 105 | "62 VSCO 6.001084\n", 106 | "63 WEWA 0.264045\n", 107 | "\n", 108 | "[64 rows x 2 columns]\n" 109 | ] 110 | } 111 | ], 112 | "source": [ 113 | "# Load quartely income in line line!!!\n", 114 | "income_df = hub.load_income(variant='quarterly') # annual or quarterly\n", 115 | "income_df = income_df.reset_index()\n", 116 | "for col in income_df.columns:\n", 117 | " print(col)\n", 118 | "income_df['INCOME_GROWTH'] = income_df[OPERATING_INCOME].pct_change(periods=1)\n", 119 | "# Average income growth in the last 4 quarters\n", 120 | "income_df['INCOME_GROWTH_MA4'] = income_df['INCOME_GROWTH'].rolling(4).mean()\n", 121 | "# Gross income growth last 4 quarters\n", 122 | "income_mask = income_df['INCOME_GROWTH_MA4'] > 0.20\n", 123 | "\n", 124 | "# Calculate past 3 months\n", 125 | "today = datetime.today()\n", 126 | "today_date_str = today.strftime(\"%Y-%m-%d\")\n", 127 | "past_date = today - timedelta(days=90)\n", 128 | "past_date_str = past_date.strftime(\"%Y-%m-%d\")\n", 129 | "\n", 130 | "# Get last 3 months of reporting\n", 131 | "income_mask &= ((income_df[REPORT_DATE] >= past_date_str) & (income_df[REPORT_DATE] <= today_date_str))\n", 132 | "\n", 133 | "# Format results\n", 134 | "income_results = income_df[income_mask]\n", 135 | "income_results = income_results.groupby(['Ticker']).mean()\n", 136 | "income_results.reset_index(inplace=True)\n", 137 | "income_results = income_results[['Ticker', 'INCOME_GROWTH_MA4']]\n", 138 | "print(income_results)" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 101, 144 | "id": "680f0a50", 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "name": "stdout", 149 | "output_type": "stream", 150 | "text": [ 151 | "Dataset \"us-derived-quarterly\" on disk (0 days old).\n", 152 | "- Loading from disk ... Done!\n", 153 | "Ticker\n", 154 | "Report Date\n", 155 | "SimFinId\n", 156 | "Currency\n", 157 | "Fiscal Year\n", 158 | "Fiscal Period\n", 159 | "Publish Date\n", 160 | "Restated Date\n", 161 | "EBITDA\n", 162 | "Total Debt\n", 163 | "Free Cash Flow\n", 164 | "Gross Profit Margin\n", 165 | "Operating Margin\n", 166 | "Net Profit Margin\n", 167 | "Return on Equity\n", 168 | "Return on Assets\n", 169 | "Free Cash Flow to Net Income\n", 170 | "Current Ratio\n", 171 | "Liabilities to Equity Ratio\n", 172 | "Debt Ratio\n", 173 | "Earnings Per Share, Basic\n", 174 | "Earnings Per Share, Diluted\n", 175 | "Sales Per Share\n", 176 | "Equity Per Share\n", 177 | "Free Cash Flow Per Share\n", 178 | "Dividends Per Share\n", 179 | "Piotroski F-Score\n", 180 | "Return On Invested Capital\n", 181 | "Cash Return On Invested Capital\n", 182 | "Dividend Payout Ratio\n", 183 | "Net Debt / EBITDA\n", 184 | "Net Debt / EBIT\n", 185 | " Ticker\n", 186 | "10527 BKE\n", 187 | "17860 CODA\n", 188 | "18806 CPRT\n", 189 | "28445 FAST\n", 190 | "34697 HEI\n", 191 | "44827 LOVE\n", 192 | "49643 MOV\n", 193 | "50851 MU\n", 194 | "68159 SLP\n", 195 | "68624 SMTC\n", 196 | "71434 SWBI\n", 197 | "78023 VALU\n", 198 | "78305 VEEV\n", 199 | "84041 ZDGE\n", 200 | "84222 ZM\n" 201 | ] 202 | } 203 | ], 204 | "source": [ 205 | "# Get financial ratios\n", 206 | "financial_ratios_df = hub.load_derived(variant='quarterly') # annual or quarterly\n", 207 | "financial_ratios_df = financial_ratios_df.reset_index()\n", 208 | "for col in financial_ratios_df.columns:\n", 209 | " print(col)\n", 210 | "\n", 211 | "\n", 212 | "# Build the mask\n", 213 | "# Company’s current assets to its current liabilities.\n", 214 | "financial_mask = (financial_ratios_df[CURRENT_RATIO] > 1.5)\n", 215 | "# The debt ratio is defined as the ratio of total debt to total assets\n", 216 | "financial_mask &= (financial_ratios_df[DEBT_RATIO] < 0.2)\n", 217 | "financial_mask &= (financial_ratios_df[NET_PROFIT_MARGIN] > 0.15)\n", 218 | "# Get last 3 months of reporting\n", 219 | "financial_mask &= ((financial_ratios_df[REPORT_DATE] >= past_date_str) & (financial_ratios_df[REPORT_DATE] <= today_date_str))\n", 220 | "\n", 221 | "financial_selections_df = financial_ratios_df[financial_mask]\n", 222 | "financial_results = financial_selections_df[['Ticker']]\n", 223 | "print(financial_results)" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": 104, 229 | "id": "1ed37897", 230 | "metadata": {}, 231 | "outputs": [ 232 | { 233 | "name": "stdout", 234 | "output_type": "stream", 235 | "text": [ 236 | "Ticker\n", 237 | "Date\n", 238 | "SimFinId\n", 239 | "Market-Cap\n", 240 | "Price to Earnings Ratio (quarterly)\n", 241 | "Price to Earnings Ratio (ttm)\n", 242 | "Price to Sales Ratio (quarterly)\n", 243 | "Price to Sales Ratio (ttm)\n", 244 | "Price to Book Value\n", 245 | "Price to Free Cash Flow (quarterly)\n", 246 | "Price to Free Cash Flow (ttm)\n", 247 | "Enterprise Value\n", 248 | "EV/EBITDA\n", 249 | "EV/Sales\n", 250 | "EV/FCF\n", 251 | "Book to Market Value\n", 252 | "Operating Income/EV\n", 253 | "Altman Z Score\n", 254 | " Ticker\n", 255 | "10527 BKE\n", 256 | "17860 CODA\n", 257 | "18806 CPRT\n", 258 | "28445 FAST\n", 259 | "34697 HEI\n", 260 | "44827 LOVE\n", 261 | "49643 MOV\n", 262 | "50851 MU\n", 263 | "68159 SLP\n", 264 | "68624 SMTC\n", 265 | "71434 SWBI\n", 266 | "78023 VALU\n", 267 | "78305 VEEV\n", 268 | "84041 ZDGE\n", 269 | "84222 ZM\n" 270 | ] 271 | } 272 | ], 273 | "source": [ 274 | "# Price Ratio Screening\n", 275 | "price_ratio_df = hub.load_derived_shareprices(variant='daily') # daily or latest\n", 276 | "price_ratio_df = price_ratio_df.reset_index()\n", 277 | "for col in price_ratio_df.columns:\n", 278 | " print(col)\n", 279 | "\n", 280 | "# Build the mask\n", 281 | "# The price-to-earnings ratio (P/E ratio) is the current share price relative to its earnings per share (EPS)\n", 282 | "price_ratio_mask = (price_ratio_df[PE_QUARTERLY] < 25)\n", 283 | "# The price-to-cash flow (P/CF) ratio compares a company's market value to its operating cash flow or\n", 284 | "# its stock price per share to operating cash flow per share\n", 285 | "price_ratio_mask &= (price_ratio_df[PRICE_FCF_QUARTERLY] < 20)\n", 286 | "# Get last 3 months of reporting\n", 287 | "price_ratio_mask &= ((price_ratio_df['Date'] >= past_date_str) & (price_ratio_df['Date'] <= today_date_str))\n", 288 | "\n", 289 | "price_selections_df = price_ratio_df[price_ratio_mask]\n", 290 | "price_results = price_selections_df.groupby(['Ticker']).mean()\n", 291 | "price_results.reset_index(inplace=True)\n", 292 | "price_results = financial_selections_df[['Ticker']]\n", 293 | "print(price_results)" 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "execution_count": null, 299 | "id": "ec75100d", 300 | "metadata": {}, 301 | "outputs": [], 302 | "source": [] 303 | } 304 | ], 305 | "metadata": { 306 | "kernelspec": { 307 | "display_name": "Python [conda env:tradesystem1]", 308 | "language": "python", 309 | "name": "conda-env-tradesystem1-py" 310 | }, 311 | "language_info": { 312 | "codemirror_mode": { 313 | "name": "ipython", 314 | "version": 3 315 | }, 316 | "file_extension": ".py", 317 | "mimetype": "text/x-python", 318 | "name": "python", 319 | "nbconvert_exporter": "python", 320 | "pygments_lexer": "ipython3", 321 | "version": "3.9.5" 322 | } 323 | }, 324 | "nbformat": 4, 325 | "nbformat_minor": 5 326 | } 327 | -------------------------------------------------------------------------------- /screeners/performance_screener.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import pandas_ta as ta 4 | import pandas as pd 5 | import datetime 6 | from pandas.tseries.holiday import USFederalHolidayCalendar 7 | from pandas.tseries.offsets import CustomBusinessDay 8 | US_BUSINESS_DAY = CustomBusinessDay(calendar=USFederalHolidayCalendar()) 9 | from yahoo_fin import stock_info as si 10 | import time 11 | from random import randint 12 | 13 | 14 | """ 15 | Strategy Rules: 16 | - Current stock price is above the 150 and 200 days moving average (MA). 17 | - The 150 days moving average is above the 200 days moving average. 18 | - The 200 days moving average is trending up for at least a month. 19 | - The 50 day MA is above the 150 and 200 MAs 20 | - Stock price is above the 50 day MA 21 | - Current share price is at least 30% above its 52 week low 22 | - Current stock price is at least within 25% of the 52 week high 23 | """ 24 | 25 | 26 | def get_past_business_days_delta_str(current_date_str, business_day_delta): 27 | target_date = datetime.datetime.strptime(current_date_str, "%Y-%m-%d") 28 | delta_date = target_date + (business_day_delta * US_BUSINESS_DAY) 29 | delta_date_str = datetime.datetime.strftime(delta_date, "%Y-%m-%d") 30 | return delta_date_str 31 | 32 | 33 | def load_nasdaq_symbols(): 34 | nasdaq_df = pd.read_csv( 35 | 'https://raw.githubusercontent.com/justmobiledev/python-algorithmic-trading/main/data/nasdaq.csv') 36 | symbols = nasdaq_df['Symbol'].to_numpy() 37 | return symbols 38 | 39 | 40 | def load_historic_data(symbol): 41 | today = datetime.date.today() 42 | today_str = today.strftime("%Y-%m-%d") 43 | # Get last 2 years of data 44 | start_date = today - (522 * US_BUSINESS_DAY) 45 | start_date_str = datetime.datetime.strftime(start_date, "%Y-%m-%d") 46 | try: 47 | # Download data from Yahoo Finance 48 | df = si.get_data(symbol, start_date=start_date_str, end_date=today_str, index_as_date=False) 49 | return df 50 | except: 51 | print('Error loading stock data for ' + symbol) 52 | return None 53 | 54 | 55 | def calculate_technical_indicators(df): 56 | df['200_MA'] = df['adjclose'].rolling(window=200).mean() 57 | df['150_MA'] = df['adjclose'].rolling(window=150).mean() 58 | df['50_MA'] = df['adjclose'].rolling(window=50).mean() 59 | df['RSI'] = ta.rsi(df["adjclose"], length=14) 60 | 61 | return df 62 | 63 | 64 | def calculate_metrics(df): 65 | # Get 1 month ago values -> 20 business days 66 | today = datetime.date.today() 67 | end_date = today 68 | end_date_str = datetime.datetime.strftime(end_date, "%Y-%m-%d") 69 | one_month_ago_str = get_past_business_days_delta_str(end_date_str, -20) 70 | 71 | mask = (df['date'] >= one_month_ago_str) 72 | df['200_MA_1m_ago'] = df[mask].iloc[0]['200_MA'] 73 | df['150_MA_1m_ago'] = df[mask].iloc[0]['150_MA'] 74 | df['RSI_1m_ago'] = df[mask].iloc[0]['RSI'] 75 | 76 | # Get 2 month ago values 77 | two_months_ago_str = get_past_business_days_delta_str(end_date_str, -40) 78 | mask = (df['date'] >= two_months_ago_str) 79 | df['200_MA_2m_ago'] = df[mask]['200_MA'] 80 | df['150_MA_2m_ago'] = df[mask]['150_MA'] 81 | 82 | # Get 52w values 83 | one_year_ago_str = get_past_business_days_delta_str(end_date_str, -261) 84 | mask = (df['date'] >= one_year_ago_str) & (df['date'] <= end_date_str) 85 | df['52w_low'] = df[mask]['adjclose'].min() 86 | df['52w_high'] = df[mask]['adjclose'].max() 87 | 88 | # Condition 6: Current Price is at least 30% above 52-week low 89 | df['above_52w_low'] = df['52w_low'] * 1.30 90 | # Condition 7: Current Price is within 90% of 52-week high 91 | df['within_52w_high'] = df['52w_high'] * 0.90 92 | 93 | return df 94 | 95 | 96 | def evaluate_conditions(df): 97 | df['condition1'] = (df['adjclose'] > df['200_MA']) & (df['adjclose'] > df['150_MA']) 98 | df['condition2'] = df['150_MA'] > df['200_MA'] 99 | df['condition3'] = df['200_MA'] > df['200_MA_1m_ago'] 100 | df['condition4'] = (df['50_MA'] > df['200_MA']) & (df['50_MA'] > df['150_MA']) 101 | df['condition5'] = df['adjclose'] > df['50_MA'] 102 | df['condition6'] = df['adjclose'] > df['above_52w_low'] 103 | df['condition7'] = df['adjclose'] > df['within_52w_high'] 104 | df['condition8'] = df['RSI_1m_ago'] >= 80 105 | 106 | # Select stocks where all conditions are met 107 | query = "condition1 == True & condition2 == True & condition3 == True & condition4 == True & \ 108 | condition5 == True & condition6 == True & condition7 == True & condition8 == True" 109 | 110 | selection_df = df.query(query) 111 | 112 | return selection_df 113 | 114 | 115 | # MAIN 116 | def main(): 117 | results_df = pd.DataFrame({"symbol": []}) 118 | symbols = load_nasdaq_symbols() 119 | 120 | # Iterate through symbols 121 | for symbol in symbols: 122 | # Skip indices 123 | if '^' in symbol: 124 | continue 125 | 126 | print(f"Processing: {symbol}") 127 | # Load daily historic prices 128 | price_df = load_historic_data(symbol) 129 | if price_df is None: 130 | continue 131 | 132 | # Only need the last two years of data 133 | price_df = price_df.tail(522) 134 | if len(price_df) < 522: 135 | continue 136 | 137 | # Calculate indicators for all rows 138 | price_df = calculate_technical_indicators(price_df) 139 | 140 | # Calculate metrics 141 | price_df = calculate_metrics(price_df) 142 | 143 | # Evaluate conditions 144 | selections_df = evaluate_conditions(price_df) 145 | if not selections_df.empty: 146 | print(f"Candidate stock: {symbol}") 147 | result_df = pd.DataFrame({"symbol": [symbol]}) 148 | results_df = pd.concat([results_df, result_df], axis=0, ignore_index=True) 149 | 150 | # Avoid DOS issues 151 | time.sleep(randint(0,1)) 152 | 153 | print(f"Selections: {results_df['symbol'].values[0]}") 154 | 155 | 156 | if __name__ == "__main__": 157 | main() 158 | -------------------------------------------------------------------------------- /strategies/BB-Strategy-With-Stop-Loss.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "5fefabd2", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import os\n", 11 | "import math\n", 12 | "import numpy as np\n", 13 | "import pandas as pd\n", 14 | "import datetime\n", 15 | "import time\n", 16 | "import random\n", 17 | "from datetime import date\n", 18 | "import pandas_ta as ta\n", 19 | "from ta.volatility import BollingerBands\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "import plotly.graph_objects as go\n", 22 | "from plotly.subplots import make_subplots\n", 23 | "from yahoo_fin import stock_info as si\n", 24 | "import datetime\n", 25 | "from pandas.tseries.holiday import USFederalHolidayCalendar\n", 26 | "from pandas.tseries.offsets import CustomBusinessDay\n", 27 | "US_BUSINESS_DAY = CustomBusinessDay(calendar=USFederalHolidayCalendar())" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": null, 33 | "id": "c1ea6afe", 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "def load_historic_data(symbol):\n", 38 | " today = datetime.date.today()\n", 39 | " today_str = today.strftime(\"%Y-%m-%d\")\n", 40 | " # Get last year's data\n", 41 | " start_date = today - (251 * US_BUSINESS_DAY)\n", 42 | " start_date_str = datetime.datetime.strftime(start_date, \"%Y-%m-%d\")\n", 43 | " # Download data from Yahoo Finance\n", 44 | " try:\n", 45 | " df = si.get_data(symbol, start_date=start_date_str, end_date=today_str, index_as_date=False)\n", 46 | " return df\n", 47 | " except:\n", 48 | " print('Error loading stock data for ' + symbol)\n", 49 | " return None" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "id": "c6d17621", 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "def calculate_bollinger_bands(df):\n", 60 | " # Initialize Bollinger Bands Indicator\n", 61 | " indicator_bb = BollingerBands(close=df[\"close\"], window=20, window_dev=2)\n", 62 | "\n", 63 | " # Add Bollinger Bands features\n", 64 | " df['BB_mid'] = indicator_bb.bollinger_mavg()\n", 65 | " df['BB_high'] = indicator_bb.bollinger_hband()\n", 66 | " df['BB_low'] = indicator_bb.bollinger_lband()\n", 67 | "\n", 68 | " return df" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": null, 74 | "id": "1341e115", 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [ 78 | "def apply_strategy_rules(df):\n", 79 | " # Entry Rule 1: Close price below Low Bollinger Band\n", 80 | " df['BB_entry_signal'] = np.where((df[\"close\"] < df[\"BB_low\"]) & (df[\"close\"].shift() >= df[\"BB_low\"]), 1, 0)\n", 81 | " \n", 82 | " # Exit rule\n", 83 | " df['BB_exit_signal'] = np.where((df[\"close\"] > df[\"BB_high\"]) & (df[\"close\"].shift() <= df[\"BB_high\"]), 1, 0)\n", 84 | "\n", 85 | " return df" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "id": "d60cc7d9", 92 | "metadata": {}, 93 | "outputs": [], 94 | "source": [ 95 | "def execute_strategy(df):\n", 96 | " close_prices = df['close']\n", 97 | " BB_entry_signals = df['BB_entry_signal']\n", 98 | " BB_exit_signals = df['BB_exit_signal']\n", 99 | " entry_prices = []\n", 100 | " exit_prices = []\n", 101 | " entry_signal = 0\n", 102 | " exit_signal = 0\n", 103 | " buy_price = -1\n", 104 | " hold = 0\n", 105 | " \n", 106 | " for i in range(len(close_prices)):\n", 107 | " # Check entry and exit signals\n", 108 | " if BB_entry_signals[i] == 1:\n", 109 | " entry_signal = 1\n", 110 | " else:\n", 111 | " entry_signal = 0\n", 112 | " if BB_exit_signals[i] == 1:\n", 113 | " exit_signal = 1\n", 114 | " else:\n", 115 | " exit_signal = 0\n", 116 | " \n", 117 | " # Add entry prices\n", 118 | " if hold == 0 and entry_signal == 1:\n", 119 | " buy_price = close_prices[i]\n", 120 | " entry_prices.append(close_prices[i])\n", 121 | " exit_prices.append(np.nan) \n", 122 | " entry_signal = 0\n", 123 | " hold = 1\n", 124 | " # Evaluate exit strategy\n", 125 | " elif (hold == 1 and exit_signal == 1 or (hold == 1 and close_prices[i] <= buy_price * 0.95)):\n", 126 | " entry_prices.append(np.nan)\n", 127 | " exit_prices.append(close_prices[i]) \n", 128 | " exit_signal = 0\n", 129 | " buy_price = -1\n", 130 | " hold = 0\n", 131 | " else:\n", 132 | " # Neither entry nor exit\n", 133 | " entry_prices.append(np.nan) \n", 134 | " exit_prices.append(np.nan) \n", 135 | " \n", 136 | " return entry_prices, exit_prices" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": null, 142 | "id": "97160be4", 143 | "metadata": {}, 144 | "outputs": [], 145 | "source": [ 146 | "def plot_graph(df, entry_prices, exit_prices):\n", 147 | " bb_high = df['BB_high']\n", 148 | " bb_mid = df['BB_mid']\n", 149 | " bb_low = df['BB_low']\n", 150 | " fig = make_subplots(rows=1, cols=1)\n", 151 | "\n", 152 | " # Plot close price\n", 153 | " fig.add_trace(go.Line(x = df.index, y = df['close'], line=dict(color=\"blue\", width=1), name=\"Close\"), row = 1, col = 1)\n", 154 | " \n", 155 | " # Plot bollinger bands\n", 156 | " fig.add_trace(go.Line(x = df.index, y = bb_high, line=dict(color=\"#ffdf80\", width=1), name=\"BB High\"), row = 1, col = 1)\n", 157 | " fig.add_trace(go.Line(x = df.index, y = bb_mid, line=dict(color=\"#ffd866\", width=1), name=\"BB Mid\"), row = 1, col = 1)\n", 158 | " fig.add_trace(go.Line(x = df.index, y = bb_low, line=dict(color=\"#ffd24d\", width=1), name=\"BB Low\"), row = 1, col = 1)\n", 159 | " \n", 160 | " # Add buy and sell indicators\n", 161 | " fig.add_trace(go.Scatter(x=df.index, y=entry_prices, marker_symbol=\"arrow-up\", marker=dict(\n", 162 | " color='green',\n", 163 | " ),mode='markers',name='Buy'))\n", 164 | " fig.add_trace(go.Scatter(x=df.index, y=exit_prices, marker_symbol=\"arrow-down\", marker=dict(\n", 165 | " color='red'\n", 166 | " ),mode='markers',name='Sell'))\n", 167 | " \n", 168 | " fig.update_layout(\n", 169 | " title={'text':'BB + Stop Loss', 'x':0.5},\n", 170 | " autosize=False,\n", 171 | " width=800,height=400)\n", 172 | " fig.update_yaxes(range=[0,1000000000],secondary_y=True)\n", 173 | " fig.update_yaxes(visible=False, secondary_y=True) #hide range slider\n", 174 | " \n", 175 | " fig.show()\n", 176 | " " 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": null, 182 | "id": "0a501873", 183 | "metadata": {}, 184 | "outputs": [], 185 | "source": [ 186 | "def calculate_buy_hold_profit(investment, df):\n", 187 | " close_prices = df['close']\n", 188 | " buy_quantity = investment / close_prices[0]\n", 189 | " sell_amount = buy_quantity * close_prices[len(close_prices)-1]\n", 190 | " profit = sell_amount - investment\n", 191 | " return profit\n", 192 | " " 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": null, 198 | "id": "84b8285c", 199 | "metadata": {}, 200 | "outputs": [], 201 | "source": [ 202 | "def calculate_strategy_profit(investment, entry_prices, exit_prices):\n", 203 | " entry_price = 0\n", 204 | " hold = 0\n", 205 | " total_profit = 0\n", 206 | " quantity = 0\n", 207 | " available_funds = investment\n", 208 | " purchase_amount = 0\n", 209 | " \n", 210 | " for i in range(len(entry_prices)):\n", 211 | " current_entry_price = entry_prices[i]\n", 212 | " current_exit_price = exit_prices[i]\n", 213 | " \n", 214 | " if not math.isnan(current_entry_price) and hold == 0:\n", 215 | " entry_price = current_entry_price\n", 216 | " quantity = available_funds / entry_price\n", 217 | " purchase_amount = quantity * entry_price\n", 218 | " hold = 1\n", 219 | " elif hold == 1 and not math.isnan(current_exit_price):\n", 220 | " hold = 0\n", 221 | " sales_amount = quantity * current_exit_price\n", 222 | " profit_or_loss = sales_amount - purchase_amount\n", 223 | " available_funds = available_funds + profit_or_loss\n", 224 | " total_profit += profit_or_loss\n", 225 | " \n", 226 | " return total_profit " 227 | ] 228 | }, 229 | { 230 | "cell_type": "code", 231 | "execution_count": null, 232 | "id": "cc8bdd7a", 233 | "metadata": {}, 234 | "outputs": [], 235 | "source": [ 236 | "# Perform analysis\n", 237 | "investment = 1000\n", 238 | "df = load_historic_data('BKNG')\n", 239 | "df.reset_index(inplace=True)\n", 240 | "df = calculate_bollinger_bands(df)\n", 241 | "df = apply_strategy_rules(df)\n", 242 | "entry_prices, exit_prices = execute_strategy(df)\n", 243 | "profit_or_loss = calculate_strategy_profit(investment, entry_prices, exit_prices)\n", 244 | "buy_hold_profit = calculate_buy_hold_profit(investment, df)\n", 245 | "plot_graph(df, entry_prices, exit_prices)" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": null, 251 | "id": "88ecd586", 252 | "metadata": {}, 253 | "outputs": [], 254 | "source": [ 255 | "def perform_analysis(symbol, df, investment):\n", 256 | " df = df.reset_index()\n", 257 | " df = calculate_bollinger_bands(df)\n", 258 | " df = apply_strategy_rules(df)\n", 259 | " \n", 260 | " entry_prices, exit_prices = execute_strategy(df)\n", 261 | " profit_or_loss = calculate_strategy_profit(investment, entry_prices, exit_prices)\n", 262 | " buy_hold_profit = calculate_buy_hold_profit(investment, df)\n", 263 | " return profit_or_loss, buy_hold_profit" 264 | ] 265 | }, 266 | { 267 | "cell_type": "code", 268 | "execution_count": null, 269 | "id": "8bc1b36f", 270 | "metadata": {}, 271 | "outputs": [], 272 | "source": [ 273 | "# Backtesting using NASDAQ 100\n", 274 | "nasdaq_100_df = pd.read_csv('https://raw.githubusercontent.com/justmobiledev/python-algorithmic-trading/main/data/nasdaq_100.csv')\n", 275 | "nasdaq_100 = nasdaq_100_df['Symbol'].to_numpy()" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "execution_count": null, 281 | "id": "6600aba0", 282 | "metadata": {}, 283 | "outputs": [], 284 | "source": [ 285 | "# Backtesting\n", 286 | "total_strategy_profit = 0\n", 287 | "total_buy_hold_profit = 0\n", 288 | "for symbol in nasdaq_100:\n", 289 | " df = load_historic_data(symbol)\n", 290 | " if df is None or df.empty:\n", 291 | " continue\n", 292 | " df.reset_index(inplace=True)\n", 293 | " \n", 294 | " # Random interval between remote fetch to avoid spam issues\n", 295 | " random_secs = random.uniform(0, 1)\n", 296 | " time.sleep(random_secs)\n", 297 | " \n", 298 | " # Run backtest\n", 299 | " profit, buy_hold_profit = perform_analysis(symbol, df, investment=investment) \n", 300 | " print(f\"Backtest profit for symbol {symbol}: ${math.trunc(profit)}, buy & hold: ${math.trunc(buy_hold_profit)}\")\n", 301 | " total_strategy_profit += profit\n", 302 | " total_buy_hold_profit += buy_hold_profit\n", 303 | " \n", 304 | "print(f\"\\nAvg strategy profit per stock: ${math.trunc(total_strategy_profit / len(nasdaq_100))}\")\n", 305 | "print(f\"\\nAvg buy & hold profit per stock: ${math.trunc(total_buy_hold_profit / len(nasdaq_100))}\")" 306 | ] 307 | } 308 | ], 309 | "metadata": { 310 | "kernelspec": { 311 | "display_name": "Python [conda env:tradesystem1]", 312 | "language": "python", 313 | "name": "conda-env-tradesystem1-py" 314 | }, 315 | "language_info": { 316 | "codemirror_mode": { 317 | "name": "ipython", 318 | "version": 3 319 | }, 320 | "file_extension": ".py", 321 | "mimetype": "text/x-python", 322 | "name": "python", 323 | "nbconvert_exporter": "python", 324 | "pygments_lexer": "ipython3", 325 | "version": "3.9.5" 326 | } 327 | }, 328 | "nbformat": 4, 329 | "nbformat_minor": 5 330 | } 331 | -------------------------------------------------------------------------------- /trends/aaii_survey_results_1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 61, 6 | "id": "0bfa7464", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "# Python imports\n", 11 | "from bs4 import BeautifulSoup\n", 12 | "import requests\n", 13 | "import pandas as pd\n", 14 | "from plotly.subplots import make_subplots\n", 15 | "import plotly.graph_objects as go\n", 16 | "from random import randint\n", 17 | "from time import sleep\n", 18 | "import os" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 62, 24 | "id": "f90ce480", 25 | "metadata": {}, 26 | "outputs": [], 27 | "source": [ 28 | "def load_results_from_file():\n", 29 | " # Check if output file exists\n", 30 | " file_name = 'sentiment_results_survey.csv'\n", 31 | " if os.path.exists(file_name):\n", 32 | " df = pd.read_csv(file_name, parse_dates=False)\n", 33 | " return df\n", 34 | " else:\n", 35 | " return None" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 63, 41 | "id": "68ce3af5", 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "def retrieve_survey_results(url):\n", 46 | " try:\n", 47 | " # Create session\n", 48 | " session = requests.Session()\n", 49 | " response = session.get(url)\n", 50 | " session_cookies = session.cookies\n", 51 | " cookies_dictionary = session_cookies.get_dict()\n", 52 | " \n", 53 | " # Get cookie params\n", 54 | " list_from_dict = []\n", 55 | " for key in cookies_dictionary:\n", 56 | " list_from_dict.append(key)\n", 57 | " list_from_dict.append(cookies_dictionary[key])\n", 58 | "\n", 59 | " # Build cookie\n", 60 | " cookie='{}={}; {}={}'.format(list_from_dict[2], list_from_dict[3], list_from_dict[0], list_from_dict[1])\n", 61 | " headers = {\n", 62 | " 'Host': 'www.aaii.com',\n", 63 | " 'Connection': 'keep-alive',\n", 64 | " 'Cache-Control': 'max-age=0',\n", 65 | " 'Upgrade-Insecure-Requests': '1',\n", 66 | " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0',\n", 67 | " 'DNT': '1',\n", 68 | " 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',\n", 69 | " 'Accept-Encoding': 'gzip, deflate, br',\n", 70 | " 'Accept-Language': 'ru,en-US;q=0.9,en;q=0.8,tr;q=0.7',\n", 71 | " 'Cookie': '{}'.format(cookie),\n", 72 | " }\n", 73 | " html_text = requests.get(url, headers=headers,timeout=20).text\n", 74 | " return html_text\n", 75 | " except:\n", 76 | " print('Fetch request failed')\n", 77 | " return None" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 64, 83 | "id": "3414e898", 84 | "metadata": {}, 85 | "outputs": [], 86 | "source": [ 87 | "def process_results(html_text):\n", 88 | " soup = BeautifulSoup(html_text, \"html.parser\")\n", 89 | " results = soup.find_all('tr',{'align': 'center'})\n", 90 | " results_df = pd.DataFrame()\n", 91 | " for i in range(1, len(results) - 1):\n", 92 | " elements = results[i].find_all('td')\n", 93 | " reported_date =elements[0].getText().strip().replace(':','')\n", 94 | "\n", 95 | " bullish=elements[1].getText().strip().replace('%','')\n", 96 | " neutral=elements[2].getText().strip().replace('%','')\n", 97 | " bearish=elements[3].getText().strip().replace('%','')\n", 98 | " result_row = pd.DataFrame({\"reported_date\":[reported_date],\"bullish\":[bullish],\"bearish\":[bearish],\"neutral\":[neutral]})\n", 99 | " results_df = pd.concat([results_df, result_row], axis=0, ignore_index = True)\n", 100 | " \n", 101 | " return results_df " 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 65, 107 | "id": "a7dabc8c", 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "def plot_results(df):\n", 112 | " fig = make_subplots(rows=1, cols=1)\n", 113 | "\n", 114 | " # Plot sentiments\n", 115 | " fig.add_trace(go.Line(x = df.index, y = df['neutral'], line=dict(color=\"blue\", width=1), name=\"Neutral\"), row = 1, col = 1)\n", 116 | " fig.add_trace(go.Line(x = df.index, y = df['bullish'], line=dict(color=\"green\", width=1), name=\"Bullish\"), row = 1, col = 1) \n", 117 | " fig.add_trace(go.Line(x = df.index, y = df['bearish'], line=dict(color=\"red\", width=1), name=\"Bearish\"), row = 1, col = 1) \n", 118 | " \n", 119 | " fig.update_layout(\n", 120 | " title={'text':'AAII Sentiment Results', 'x':0.5},\n", 121 | " autosize=False,\n", 122 | " width=800,height=400)\n", 123 | " fig.update_yaxes(range=[0,1000000000],secondary_y=True)\n", 124 | " fig.update_yaxes(visible=False, secondary_y=True) #hide range slider\n", 125 | " \n", 126 | " fig.show()" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 66, 132 | "id": "dfd77081", 133 | "metadata": {}, 134 | "outputs": [ 135 | { 136 | "name": "stdout", 137 | "output_type": "stream", 138 | "text": [ 139 | " Unnamed: 0 reported_date bullish bearish neutral\n", 140 | "0 20 December 8 29.7 30.5 39.8\n", 141 | "1 19 December 15 25.2 39.3 35.4\n", 142 | "2 18 December 22 29.6 33.9 36.6\n", 143 | "3 17 December 29 37.7 30.5 31.8\n", 144 | "4 16 January 5 32.8 33.3 33.9\n", 145 | "5 15 January 12 24.9 38.3 36.8\n", 146 | "6 14 January 19 21.0 46.7 32.3\n", 147 | "7 13 January 26 23.1 52.9 23.9\n", 148 | "8 12 February 2 26.5 43.7 29.9\n", 149 | "9 11 February 9 24.4 35.5 40.2\n", 150 | "10 10 February 16 19.2 43.2 37.6\n", 151 | "11 9 February 23 23.4 53.7 22.9\n", 152 | "12 8 March 2 30.4 41.4 28.2\n", 153 | "13 7 March 9 24.0 45.8 30.2\n", 154 | "14 6 March 16 22.5 49.8 27.8\n", 155 | "15 5 March 23 32.8 35.4 31.7\n", 156 | "16 4 March 30 31.9 27.5 40.6\n", 157 | "17 3 April 6 24.7 41.4 33.9\n", 158 | "18 2 April 13 15.8 48.4 35.7\n", 159 | "19 1 April 20 18.9 43.9 37.3\n", 160 | "20 0 April 27 16.4 59.4 24.2\n" 161 | ] 162 | }, 163 | { 164 | "name": "stderr", 165 | "output_type": "stream", 166 | "text": [ 167 | "C:\\Users\\dutch\\anaconda3\\envs\\tradesystem1\\lib\\site-packages\\plotly\\graph_objs\\_deprecations.py:378: DeprecationWarning:\n", 168 | "\n", 169 | "plotly.graph_objs.Line is deprecated.\n", 170 | "Please replace it with one of the following more specific types\n", 171 | " - plotly.graph_objs.scatter.Line\n", 172 | " - plotly.graph_objs.layout.shape.Line\n", 173 | " - etc.\n", 174 | "\n", 175 | "\n" 176 | ] 177 | }, 178 | { 179 | "data": { 180 | "application/vnd.plotly.v1+json": { 181 | "config": { 182 | "plotlyServerURL": "https://plot.ly" 183 | }, 184 | "data": [ 185 | { 186 | "line": { 187 | "color": "blue", 188 | "width": 1 189 | }, 190 | "name": "Neutral", 191 | "type": "scatter", 192 | "x": [ 193 | 0, 194 | 1, 195 | 2, 196 | 3, 197 | 4, 198 | 5, 199 | 6, 200 | 7, 201 | 8, 202 | 9, 203 | 10, 204 | 11, 205 | 12, 206 | 13, 207 | 14, 208 | 15, 209 | 16, 210 | 17, 211 | 18, 212 | 19, 213 | 20 214 | ], 215 | "xaxis": "x", 216 | "y": [ 217 | 39.8, 218 | 35.4, 219 | 36.6, 220 | 31.8, 221 | 33.9, 222 | 36.8, 223 | 32.3, 224 | 23.9, 225 | 29.9, 226 | 40.2, 227 | 37.6, 228 | 22.9, 229 | 28.2, 230 | 30.2, 231 | 27.8, 232 | 31.7, 233 | 40.6, 234 | 33.9, 235 | 35.7, 236 | 37.3, 237 | 24.2 238 | ], 239 | "yaxis": "y" 240 | }, 241 | { 242 | "line": { 243 | "color": "green", 244 | "width": 1 245 | }, 246 | "name": "Bullish", 247 | "type": "scatter", 248 | "x": [ 249 | 0, 250 | 1, 251 | 2, 252 | 3, 253 | 4, 254 | 5, 255 | 6, 256 | 7, 257 | 8, 258 | 9, 259 | 10, 260 | 11, 261 | 12, 262 | 13, 263 | 14, 264 | 15, 265 | 16, 266 | 17, 267 | 18, 268 | 19, 269 | 20 270 | ], 271 | "xaxis": "x", 272 | "y": [ 273 | 29.7, 274 | 25.2, 275 | 29.6, 276 | 37.7, 277 | 32.8, 278 | 24.9, 279 | 21, 280 | 23.1, 281 | 26.5, 282 | 24.4, 283 | 19.2, 284 | 23.4, 285 | 30.4, 286 | 24, 287 | 22.5, 288 | 32.8, 289 | 31.9, 290 | 24.7, 291 | 15.8, 292 | 18.9, 293 | 16.4 294 | ], 295 | "yaxis": "y" 296 | }, 297 | { 298 | "line": { 299 | "color": "red", 300 | "width": 1 301 | }, 302 | "name": "Bearish", 303 | "type": "scatter", 304 | "x": [ 305 | 0, 306 | 1, 307 | 2, 308 | 3, 309 | 4, 310 | 5, 311 | 6, 312 | 7, 313 | 8, 314 | 9, 315 | 10, 316 | 11, 317 | 12, 318 | 13, 319 | 14, 320 | 15, 321 | 16, 322 | 17, 323 | 18, 324 | 19, 325 | 20 326 | ], 327 | "xaxis": "x", 328 | "y": [ 329 | 30.5, 330 | 39.3, 331 | 33.9, 332 | 30.5, 333 | 33.3, 334 | 38.3, 335 | 46.7, 336 | 52.9, 337 | 43.7, 338 | 35.5, 339 | 43.2, 340 | 53.7, 341 | 41.4, 342 | 45.8, 343 | 49.8, 344 | 35.4, 345 | 27.5, 346 | 41.4, 347 | 48.4, 348 | 43.9, 349 | 59.4 350 | ], 351 | "yaxis": "y" 352 | } 353 | ], 354 | "layout": { 355 | "autosize": false, 356 | "height": 400, 357 | "template": { 358 | "data": { 359 | "bar": [ 360 | { 361 | "error_x": { 362 | "color": "#2a3f5f" 363 | }, 364 | "error_y": { 365 | "color": "#2a3f5f" 366 | }, 367 | "marker": { 368 | "line": { 369 | "color": "#E5ECF6", 370 | "width": 0.5 371 | }, 372 | "pattern": { 373 | "fillmode": "overlay", 374 | "size": 10, 375 | "solidity": 0.2 376 | } 377 | }, 378 | "type": "bar" 379 | } 380 | ], 381 | "barpolar": [ 382 | { 383 | "marker": { 384 | "line": { 385 | "color": "#E5ECF6", 386 | "width": 0.5 387 | }, 388 | "pattern": { 389 | "fillmode": "overlay", 390 | "size": 10, 391 | "solidity": 0.2 392 | } 393 | }, 394 | "type": "barpolar" 395 | } 396 | ], 397 | "carpet": [ 398 | { 399 | "aaxis": { 400 | "endlinecolor": "#2a3f5f", 401 | "gridcolor": "white", 402 | "linecolor": "white", 403 | "minorgridcolor": "white", 404 | "startlinecolor": "#2a3f5f" 405 | }, 406 | "baxis": { 407 | "endlinecolor": "#2a3f5f", 408 | "gridcolor": "white", 409 | "linecolor": "white", 410 | "minorgridcolor": "white", 411 | "startlinecolor": "#2a3f5f" 412 | }, 413 | "type": "carpet" 414 | } 415 | ], 416 | "choropleth": [ 417 | { 418 | "colorbar": { 419 | "outlinewidth": 0, 420 | "ticks": "" 421 | }, 422 | "type": "choropleth" 423 | } 424 | ], 425 | "contour": [ 426 | { 427 | "colorbar": { 428 | "outlinewidth": 0, 429 | "ticks": "" 430 | }, 431 | "colorscale": [ 432 | [ 433 | 0, 434 | "#0d0887" 435 | ], 436 | [ 437 | 0.1111111111111111, 438 | "#46039f" 439 | ], 440 | [ 441 | 0.2222222222222222, 442 | "#7201a8" 443 | ], 444 | [ 445 | 0.3333333333333333, 446 | "#9c179e" 447 | ], 448 | [ 449 | 0.4444444444444444, 450 | "#bd3786" 451 | ], 452 | [ 453 | 0.5555555555555556, 454 | "#d8576b" 455 | ], 456 | [ 457 | 0.6666666666666666, 458 | "#ed7953" 459 | ], 460 | [ 461 | 0.7777777777777778, 462 | "#fb9f3a" 463 | ], 464 | [ 465 | 0.8888888888888888, 466 | "#fdca26" 467 | ], 468 | [ 469 | 1, 470 | "#f0f921" 471 | ] 472 | ], 473 | "type": "contour" 474 | } 475 | ], 476 | "contourcarpet": [ 477 | { 478 | "colorbar": { 479 | "outlinewidth": 0, 480 | "ticks": "" 481 | }, 482 | "type": "contourcarpet" 483 | } 484 | ], 485 | "heatmap": [ 486 | { 487 | "colorbar": { 488 | "outlinewidth": 0, 489 | "ticks": "" 490 | }, 491 | "colorscale": [ 492 | [ 493 | 0, 494 | "#0d0887" 495 | ], 496 | [ 497 | 0.1111111111111111, 498 | "#46039f" 499 | ], 500 | [ 501 | 0.2222222222222222, 502 | "#7201a8" 503 | ], 504 | [ 505 | 0.3333333333333333, 506 | "#9c179e" 507 | ], 508 | [ 509 | 0.4444444444444444, 510 | "#bd3786" 511 | ], 512 | [ 513 | 0.5555555555555556, 514 | "#d8576b" 515 | ], 516 | [ 517 | 0.6666666666666666, 518 | "#ed7953" 519 | ], 520 | [ 521 | 0.7777777777777778, 522 | "#fb9f3a" 523 | ], 524 | [ 525 | 0.8888888888888888, 526 | "#fdca26" 527 | ], 528 | [ 529 | 1, 530 | "#f0f921" 531 | ] 532 | ], 533 | "type": "heatmap" 534 | } 535 | ], 536 | "heatmapgl": [ 537 | { 538 | "colorbar": { 539 | "outlinewidth": 0, 540 | "ticks": "" 541 | }, 542 | "colorscale": [ 543 | [ 544 | 0, 545 | "#0d0887" 546 | ], 547 | [ 548 | 0.1111111111111111, 549 | "#46039f" 550 | ], 551 | [ 552 | 0.2222222222222222, 553 | "#7201a8" 554 | ], 555 | [ 556 | 0.3333333333333333, 557 | "#9c179e" 558 | ], 559 | [ 560 | 0.4444444444444444, 561 | "#bd3786" 562 | ], 563 | [ 564 | 0.5555555555555556, 565 | "#d8576b" 566 | ], 567 | [ 568 | 0.6666666666666666, 569 | "#ed7953" 570 | ], 571 | [ 572 | 0.7777777777777778, 573 | "#fb9f3a" 574 | ], 575 | [ 576 | 0.8888888888888888, 577 | "#fdca26" 578 | ], 579 | [ 580 | 1, 581 | "#f0f921" 582 | ] 583 | ], 584 | "type": "heatmapgl" 585 | } 586 | ], 587 | "histogram": [ 588 | { 589 | "marker": { 590 | "pattern": { 591 | "fillmode": "overlay", 592 | "size": 10, 593 | "solidity": 0.2 594 | } 595 | }, 596 | "type": "histogram" 597 | } 598 | ], 599 | "histogram2d": [ 600 | { 601 | "colorbar": { 602 | "outlinewidth": 0, 603 | "ticks": "" 604 | }, 605 | "colorscale": [ 606 | [ 607 | 0, 608 | "#0d0887" 609 | ], 610 | [ 611 | 0.1111111111111111, 612 | "#46039f" 613 | ], 614 | [ 615 | 0.2222222222222222, 616 | "#7201a8" 617 | ], 618 | [ 619 | 0.3333333333333333, 620 | "#9c179e" 621 | ], 622 | [ 623 | 0.4444444444444444, 624 | "#bd3786" 625 | ], 626 | [ 627 | 0.5555555555555556, 628 | "#d8576b" 629 | ], 630 | [ 631 | 0.6666666666666666, 632 | "#ed7953" 633 | ], 634 | [ 635 | 0.7777777777777778, 636 | "#fb9f3a" 637 | ], 638 | [ 639 | 0.8888888888888888, 640 | "#fdca26" 641 | ], 642 | [ 643 | 1, 644 | "#f0f921" 645 | ] 646 | ], 647 | "type": "histogram2d" 648 | } 649 | ], 650 | "histogram2dcontour": [ 651 | { 652 | "colorbar": { 653 | "outlinewidth": 0, 654 | "ticks": "" 655 | }, 656 | "colorscale": [ 657 | [ 658 | 0, 659 | "#0d0887" 660 | ], 661 | [ 662 | 0.1111111111111111, 663 | "#46039f" 664 | ], 665 | [ 666 | 0.2222222222222222, 667 | "#7201a8" 668 | ], 669 | [ 670 | 0.3333333333333333, 671 | "#9c179e" 672 | ], 673 | [ 674 | 0.4444444444444444, 675 | "#bd3786" 676 | ], 677 | [ 678 | 0.5555555555555556, 679 | "#d8576b" 680 | ], 681 | [ 682 | 0.6666666666666666, 683 | "#ed7953" 684 | ], 685 | [ 686 | 0.7777777777777778, 687 | "#fb9f3a" 688 | ], 689 | [ 690 | 0.8888888888888888, 691 | "#fdca26" 692 | ], 693 | [ 694 | 1, 695 | "#f0f921" 696 | ] 697 | ], 698 | "type": "histogram2dcontour" 699 | } 700 | ], 701 | "mesh3d": [ 702 | { 703 | "colorbar": { 704 | "outlinewidth": 0, 705 | "ticks": "" 706 | }, 707 | "type": "mesh3d" 708 | } 709 | ], 710 | "parcoords": [ 711 | { 712 | "line": { 713 | "colorbar": { 714 | "outlinewidth": 0, 715 | "ticks": "" 716 | } 717 | }, 718 | "type": "parcoords" 719 | } 720 | ], 721 | "pie": [ 722 | { 723 | "automargin": true, 724 | "type": "pie" 725 | } 726 | ], 727 | "scatter": [ 728 | { 729 | "marker": { 730 | "colorbar": { 731 | "outlinewidth": 0, 732 | "ticks": "" 733 | } 734 | }, 735 | "type": "scatter" 736 | } 737 | ], 738 | "scatter3d": [ 739 | { 740 | "line": { 741 | "colorbar": { 742 | "outlinewidth": 0, 743 | "ticks": "" 744 | } 745 | }, 746 | "marker": { 747 | "colorbar": { 748 | "outlinewidth": 0, 749 | "ticks": "" 750 | } 751 | }, 752 | "type": "scatter3d" 753 | } 754 | ], 755 | "scattercarpet": [ 756 | { 757 | "marker": { 758 | "colorbar": { 759 | "outlinewidth": 0, 760 | "ticks": "" 761 | } 762 | }, 763 | "type": "scattercarpet" 764 | } 765 | ], 766 | "scattergeo": [ 767 | { 768 | "marker": { 769 | "colorbar": { 770 | "outlinewidth": 0, 771 | "ticks": "" 772 | } 773 | }, 774 | "type": "scattergeo" 775 | } 776 | ], 777 | "scattergl": [ 778 | { 779 | "marker": { 780 | "colorbar": { 781 | "outlinewidth": 0, 782 | "ticks": "" 783 | } 784 | }, 785 | "type": "scattergl" 786 | } 787 | ], 788 | "scattermapbox": [ 789 | { 790 | "marker": { 791 | "colorbar": { 792 | "outlinewidth": 0, 793 | "ticks": "" 794 | } 795 | }, 796 | "type": "scattermapbox" 797 | } 798 | ], 799 | "scatterpolar": [ 800 | { 801 | "marker": { 802 | "colorbar": { 803 | "outlinewidth": 0, 804 | "ticks": "" 805 | } 806 | }, 807 | "type": "scatterpolar" 808 | } 809 | ], 810 | "scatterpolargl": [ 811 | { 812 | "marker": { 813 | "colorbar": { 814 | "outlinewidth": 0, 815 | "ticks": "" 816 | } 817 | }, 818 | "type": "scatterpolargl" 819 | } 820 | ], 821 | "scatterternary": [ 822 | { 823 | "marker": { 824 | "colorbar": { 825 | "outlinewidth": 0, 826 | "ticks": "" 827 | } 828 | }, 829 | "type": "scatterternary" 830 | } 831 | ], 832 | "surface": [ 833 | { 834 | "colorbar": { 835 | "outlinewidth": 0, 836 | "ticks": "" 837 | }, 838 | "colorscale": [ 839 | [ 840 | 0, 841 | "#0d0887" 842 | ], 843 | [ 844 | 0.1111111111111111, 845 | "#46039f" 846 | ], 847 | [ 848 | 0.2222222222222222, 849 | "#7201a8" 850 | ], 851 | [ 852 | 0.3333333333333333, 853 | "#9c179e" 854 | ], 855 | [ 856 | 0.4444444444444444, 857 | "#bd3786" 858 | ], 859 | [ 860 | 0.5555555555555556, 861 | "#d8576b" 862 | ], 863 | [ 864 | 0.6666666666666666, 865 | "#ed7953" 866 | ], 867 | [ 868 | 0.7777777777777778, 869 | "#fb9f3a" 870 | ], 871 | [ 872 | 0.8888888888888888, 873 | "#fdca26" 874 | ], 875 | [ 876 | 1, 877 | "#f0f921" 878 | ] 879 | ], 880 | "type": "surface" 881 | } 882 | ], 883 | "table": [ 884 | { 885 | "cells": { 886 | "fill": { 887 | "color": "#EBF0F8" 888 | }, 889 | "line": { 890 | "color": "white" 891 | } 892 | }, 893 | "header": { 894 | "fill": { 895 | "color": "#C8D4E3" 896 | }, 897 | "line": { 898 | "color": "white" 899 | } 900 | }, 901 | "type": "table" 902 | } 903 | ] 904 | }, 905 | "layout": { 906 | "annotationdefaults": { 907 | "arrowcolor": "#2a3f5f", 908 | "arrowhead": 0, 909 | "arrowwidth": 1 910 | }, 911 | "autotypenumbers": "strict", 912 | "coloraxis": { 913 | "colorbar": { 914 | "outlinewidth": 0, 915 | "ticks": "" 916 | } 917 | }, 918 | "colorscale": { 919 | "diverging": [ 920 | [ 921 | 0, 922 | "#8e0152" 923 | ], 924 | [ 925 | 0.1, 926 | "#c51b7d" 927 | ], 928 | [ 929 | 0.2, 930 | "#de77ae" 931 | ], 932 | [ 933 | 0.3, 934 | "#f1b6da" 935 | ], 936 | [ 937 | 0.4, 938 | "#fde0ef" 939 | ], 940 | [ 941 | 0.5, 942 | "#f7f7f7" 943 | ], 944 | [ 945 | 0.6, 946 | "#e6f5d0" 947 | ], 948 | [ 949 | 0.7, 950 | "#b8e186" 951 | ], 952 | [ 953 | 0.8, 954 | "#7fbc41" 955 | ], 956 | [ 957 | 0.9, 958 | "#4d9221" 959 | ], 960 | [ 961 | 1, 962 | "#276419" 963 | ] 964 | ], 965 | "sequential": [ 966 | [ 967 | 0, 968 | "#0d0887" 969 | ], 970 | [ 971 | 0.1111111111111111, 972 | "#46039f" 973 | ], 974 | [ 975 | 0.2222222222222222, 976 | "#7201a8" 977 | ], 978 | [ 979 | 0.3333333333333333, 980 | "#9c179e" 981 | ], 982 | [ 983 | 0.4444444444444444, 984 | "#bd3786" 985 | ], 986 | [ 987 | 0.5555555555555556, 988 | "#d8576b" 989 | ], 990 | [ 991 | 0.6666666666666666, 992 | "#ed7953" 993 | ], 994 | [ 995 | 0.7777777777777778, 996 | "#fb9f3a" 997 | ], 998 | [ 999 | 0.8888888888888888, 1000 | "#fdca26" 1001 | ], 1002 | [ 1003 | 1, 1004 | "#f0f921" 1005 | ] 1006 | ], 1007 | "sequentialminus": [ 1008 | [ 1009 | 0, 1010 | "#0d0887" 1011 | ], 1012 | [ 1013 | 0.1111111111111111, 1014 | "#46039f" 1015 | ], 1016 | [ 1017 | 0.2222222222222222, 1018 | "#7201a8" 1019 | ], 1020 | [ 1021 | 0.3333333333333333, 1022 | "#9c179e" 1023 | ], 1024 | [ 1025 | 0.4444444444444444, 1026 | "#bd3786" 1027 | ], 1028 | [ 1029 | 0.5555555555555556, 1030 | "#d8576b" 1031 | ], 1032 | [ 1033 | 0.6666666666666666, 1034 | "#ed7953" 1035 | ], 1036 | [ 1037 | 0.7777777777777778, 1038 | "#fb9f3a" 1039 | ], 1040 | [ 1041 | 0.8888888888888888, 1042 | "#fdca26" 1043 | ], 1044 | [ 1045 | 1, 1046 | "#f0f921" 1047 | ] 1048 | ] 1049 | }, 1050 | "colorway": [ 1051 | "#636efa", 1052 | "#EF553B", 1053 | "#00cc96", 1054 | "#ab63fa", 1055 | "#FFA15A", 1056 | "#19d3f3", 1057 | "#FF6692", 1058 | "#B6E880", 1059 | "#FF97FF", 1060 | "#FECB52" 1061 | ], 1062 | "font": { 1063 | "color": "#2a3f5f" 1064 | }, 1065 | "geo": { 1066 | "bgcolor": "white", 1067 | "lakecolor": "white", 1068 | "landcolor": "#E5ECF6", 1069 | "showlakes": true, 1070 | "showland": true, 1071 | "subunitcolor": "white" 1072 | }, 1073 | "hoverlabel": { 1074 | "align": "left" 1075 | }, 1076 | "hovermode": "closest", 1077 | "mapbox": { 1078 | "style": "light" 1079 | }, 1080 | "paper_bgcolor": "white", 1081 | "plot_bgcolor": "#E5ECF6", 1082 | "polar": { 1083 | "angularaxis": { 1084 | "gridcolor": "white", 1085 | "linecolor": "white", 1086 | "ticks": "" 1087 | }, 1088 | "bgcolor": "#E5ECF6", 1089 | "radialaxis": { 1090 | "gridcolor": "white", 1091 | "linecolor": "white", 1092 | "ticks": "" 1093 | } 1094 | }, 1095 | "scene": { 1096 | "xaxis": { 1097 | "backgroundcolor": "#E5ECF6", 1098 | "gridcolor": "white", 1099 | "gridwidth": 2, 1100 | "linecolor": "white", 1101 | "showbackground": true, 1102 | "ticks": "", 1103 | "zerolinecolor": "white" 1104 | }, 1105 | "yaxis": { 1106 | "backgroundcolor": "#E5ECF6", 1107 | "gridcolor": "white", 1108 | "gridwidth": 2, 1109 | "linecolor": "white", 1110 | "showbackground": true, 1111 | "ticks": "", 1112 | "zerolinecolor": "white" 1113 | }, 1114 | "zaxis": { 1115 | "backgroundcolor": "#E5ECF6", 1116 | "gridcolor": "white", 1117 | "gridwidth": 2, 1118 | "linecolor": "white", 1119 | "showbackground": true, 1120 | "ticks": "", 1121 | "zerolinecolor": "white" 1122 | } 1123 | }, 1124 | "shapedefaults": { 1125 | "line": { 1126 | "color": "#2a3f5f" 1127 | } 1128 | }, 1129 | "ternary": { 1130 | "aaxis": { 1131 | "gridcolor": "white", 1132 | "linecolor": "white", 1133 | "ticks": "" 1134 | }, 1135 | "baxis": { 1136 | "gridcolor": "white", 1137 | "linecolor": "white", 1138 | "ticks": "" 1139 | }, 1140 | "bgcolor": "#E5ECF6", 1141 | "caxis": { 1142 | "gridcolor": "white", 1143 | "linecolor": "white", 1144 | "ticks": "" 1145 | } 1146 | }, 1147 | "title": { 1148 | "x": 0.05 1149 | }, 1150 | "xaxis": { 1151 | "automargin": true, 1152 | "gridcolor": "white", 1153 | "linecolor": "white", 1154 | "ticks": "", 1155 | "title": { 1156 | "standoff": 15 1157 | }, 1158 | "zerolinecolor": "white", 1159 | "zerolinewidth": 2 1160 | }, 1161 | "yaxis": { 1162 | "automargin": true, 1163 | "gridcolor": "white", 1164 | "linecolor": "white", 1165 | "ticks": "", 1166 | "title": { 1167 | "standoff": 15 1168 | }, 1169 | "zerolinecolor": "white", 1170 | "zerolinewidth": 2 1171 | } 1172 | } 1173 | }, 1174 | "title": { 1175 | "text": "AAII Sentiment Results", 1176 | "x": 0.5 1177 | }, 1178 | "width": 800, 1179 | "xaxis": { 1180 | "anchor": "y", 1181 | "domain": [ 1182 | 0, 1183 | 1 1184 | ] 1185 | }, 1186 | "yaxis": { 1187 | "anchor": "x", 1188 | "domain": [ 1189 | 0, 1190 | 1 1191 | ] 1192 | } 1193 | } 1194 | }, 1195 | "text/html": [ 1196 | "
" 1221 | ] 1222 | }, 1223 | "metadata": {}, 1224 | "output_type": "display_data" 1225 | } 1226 | ], 1227 | "source": [ 1228 | "# Try to load from file\n", 1229 | "results_df = load_results_from_file()\n", 1230 | "# Reverse rows\n", 1231 | "results_df[::-1]\n", 1232 | "print(results_df)\n", 1233 | "\n", 1234 | "if results_df is None:\n", 1235 | " print('Results file not found - retrieving info remotely')\n", 1236 | " # Load remotely\n", 1237 | " url = 'https://www.aaii.com/sentimentsurvey/sent_results'\n", 1238 | " html_text = retrieve_survey_results(url)\n", 1239 | " print(html_text)\n", 1240 | " # Pass robots prevention\n", 1241 | " if \"Incapsula incident ID\" in html_text:\n", 1242 | " print('Blocked by robots prevention - trying again later')\n", 1243 | " else:\n", 1244 | " # Process results\n", 1245 | " results_df = process_results(html_text)\n", 1246 | " print(results_df)\n", 1247 | " # Store file for next time\n", 1248 | " results_df.to_csv('sentiment_results_survey.csv')\n", 1249 | "\n", 1250 | "# Plot results\n", 1251 | "if results_df is not None:\n", 1252 | " plot_results(results_df)\n" 1253 | ] 1254 | }, 1255 | { 1256 | "cell_type": "code", 1257 | "execution_count": null, 1258 | "id": "2d3ee026", 1259 | "metadata": {}, 1260 | "outputs": [], 1261 | "source": [] 1262 | } 1263 | ], 1264 | "metadata": { 1265 | "kernelspec": { 1266 | "display_name": "Python [conda env:tradesystem1]", 1267 | "language": "python", 1268 | "name": "conda-env-tradesystem1-py" 1269 | }, 1270 | "language_info": { 1271 | "codemirror_mode": { 1272 | "name": "ipython", 1273 | "version": 3 1274 | }, 1275 | "file_extension": ".py", 1276 | "mimetype": "text/x-python", 1277 | "name": "python", 1278 | "nbconvert_exporter": "python", 1279 | "pygments_lexer": "ipython3", 1280 | "version": "3.9.5" 1281 | } 1282 | }, 1283 | "nbformat": 4, 1284 | "nbformat_minor": 5 1285 | } 1286 | -------------------------------------------------------------------------------- /trends/market_index_sentiment.py: -------------------------------------------------------------------------------- 1 | import os 2 | import math 3 | import numpy as np 4 | import pandas as pd 5 | import datetime 6 | from datetime import date 7 | import pandas_ta as ta 8 | import matplotlib.pyplot as plt 9 | import plotly.graph_objects as go 10 | from plotly.subplots import make_subplots 11 | import datetime 12 | from yahoo_fin import stock_info as si 13 | from pandas.tseries.holiday import USFederalHolidayCalendar 14 | from pandas.tseries.offsets import CustomBusinessDay 15 | US_BUSINESS_DAY = CustomBusinessDay(calendar=USFederalHolidayCalendar()) 16 | 17 | 18 | def calculate_smas(df): 19 | df['SMA20'] = ta.sma(df["close"], length=20) 20 | df['SMA5'] = ta.sma(df["close"], length=5) 21 | df['SMA5_SMA20'] = df['SMA5'] / df['SMA20'] 22 | df['SMA5_SMA20_NORM'] = (df['SMA5_SMA20'] - df['SMA5_SMA20'].min()) / (df['SMA5_SMA20'].max() - df['SMA5_SMA20'].min()) 23 | 24 | return df 25 | 26 | 27 | def determine_market_trend(df): 28 | short_term_sentiment = round(df['SMA5_SMA20_NORM'].tail(20).mean(),2) 29 | 30 | return short_term_sentiment 31 | 32 | 33 | def load_daily_data(symbol): 34 | today = datetime.date.today() 35 | today_str = today.strftime("%Y-%m-%d") 36 | start_date = today - (220 * US_BUSINESS_DAY) 37 | start_date_str = datetime.datetime.strftime(start_date, "%Y-%m-%d") 38 | try: 39 | # Download data from Yahoo Finance 40 | df = si.get_data(symbol, start_date=start_date_str, end_date=today_str, index_as_date=False) 41 | return df 42 | except: 43 | print('Error loading stock data for ' + symbol) 44 | return None 45 | 46 | 47 | def plot_trend_indicator(df, name): 48 | fig = make_subplots(rows=2, cols=1) 49 | 50 | # Plot close price 51 | fig.add_trace(go.Line(x=df.index, y=df['close'], line=dict(color="blue", width=1), name=name), 52 | row=1, col=1) 53 | 54 | # SMAs 55 | fig.add_trace(go.Line(x=df.index, y=df['SMA20'], line=dict(color="#f95738", width=1), name="SMA 20"), 56 | row=1, col=1) 57 | fig.add_trace(go.Line(x=df.index, y=df['SMA5'], line=dict(color="#ee964b", width=1), name="SMA 5"), 58 | row=1, col=1) 59 | 60 | 61 | # Plot Indicator 62 | fig.add_trace(go.Line(x=df.index, y=df['SMA5_SMA20_NORM'], line=dict(color="#f95738", width=1), name="Short Term Trend Indicator"), 63 | row=2, col=1) 64 | 65 | 66 | fig.add_hline(y=0.5, row=2, col=1) 67 | 68 | fig.update_layout( 69 | title={'text': f"{name} Trend Indicator", 'x': 0.5}, 70 | autosize=True, 71 | width=800, height=800) 72 | fig.update_yaxes(autorange=True, fixedrange=False, secondary_y=True, row=1, col=1) 73 | fig.update_yaxes(range=[0,1], row=2, col=1) 74 | 75 | fig.write_image(f"{name}_trend_indictor.png") 76 | 77 | 78 | 79 | def get_market_sentiment(): 80 | # Retrieve prices for DOW 81 | dji_df = load_daily_data('^DJI') 82 | dji_df = calculate_smas(dji_df) 83 | dow_short_term_trend = determine_market_trend(dji_df) 84 | 85 | # NASDAQ 86 | nasdaq_df = load_daily_data('^IXIC') 87 | nasdaq_df = calculate_smas(nasdaq_df) 88 | nasdaq_short_term_trend = determine_market_trend(nasdaq_df) 89 | 90 | # S&P 500 91 | snp_df = load_daily_data('^GSPC') 92 | snp_df = calculate_smas(snp_df) 93 | snp_short_term_trend = determine_market_trend(snp_df) 94 | 95 | # Crypto index 96 | crypto_df = load_daily_data('BITW') 97 | crypto_df = calculate_smas(crypto_df) 98 | crypto_short_term_trend = determine_market_trend(crypto_df) 99 | 100 | # Visualize results 101 | plot_trend_indicator(dji_df.tail(200), 'DJI') 102 | plot_trend_indicator(nasdaq_df.tail(200), 'NASDAQ') 103 | plot_trend_indicator(snp_df.tail(200), 'S&P') 104 | plot_trend_indicator(crypto_df.tail(200), 'BITW') 105 | 106 | combined_trend = (dow_short_term_trend + nasdaq_short_term_trend + snp_short_term_trend + crypto_short_term_trend) / 4 107 | combined_trend = str(round(combined_trend,2)) 108 | print(combined_trend) 109 | 110 | get_market_sentiment() --------------------------------------------------------------------------------