├── .gitignore ├── LICENSE.txt ├── README.md ├── binance-spot ├── __init__.py ├── base │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-38.pyc │ │ ├── printobject.cpython-38.pyc │ │ └── printtime.cpython-38.pyc │ └── printobject.py ├── constant │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-38.pyc │ │ └── system.cpython-38.pyc │ └── system.py ├── examples.py ├── exception │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-38.pyc │ │ └── binanceapiexception.cpython-38.pyc │ └── binanceapiexception.py ├── impl │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-38.pyc │ │ ├── restapiinvoker.cpython-38.pyc │ │ ├── restapirequest.cpython-38.pyc │ │ ├── restapirequestimpl.cpython-38.pyc │ │ ├── websocketconnection.cpython-38.pyc │ │ ├── websocketrequest.cpython-38.pyc │ │ ├── websocketrequestimpl.cpython-38.pyc │ │ └── websocketwatchdog.cpython-38.pyc │ ├── restapiinvoker.py │ ├── restapirequest.py │ ├── restapirequestimpl.py │ ├── utils │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-38.pyc │ │ │ ├── apisignature.cpython-38.pyc │ │ │ ├── channelparser.cpython-38.pyc │ │ │ ├── channels.cpython-38.pyc │ │ │ ├── inputchecker.cpython-38.pyc │ │ │ ├── jsonwrapper.cpython-38.pyc │ │ │ ├── timeservice.cpython-38.pyc │ │ │ └── urlparamsbuilder.cpython-38.pyc │ │ ├── apisignature.py │ │ ├── channels.py │ │ ├── inputchecker.py │ │ ├── jsonwrapper.py │ │ ├── timeservice.py │ │ └── urlparamsbuilder.py │ ├── websocketconnection.py │ ├── websocketrequest.py │ ├── websocketrequestimpl.py │ └── websocketwatchdog.py ├── model.json │ ├── order.json │ └── orderoco.json ├── model │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-38.pyc │ │ ├── accountinformation.cpython-38.pyc │ │ ├── accountupdate.cpython-38.pyc │ │ ├── aggregatetrade.cpython-38.pyc │ │ ├── aggregatetradeevent.cpython-38.pyc │ │ ├── averagePrice.cpython-38.pyc │ │ ├── candlestick.cpython-38.pyc │ │ ├── candlestickevent.cpython-38.pyc │ │ ├── codeandmsg.cpython-38.pyc │ │ ├── constant.cpython-38.pyc │ │ ├── diffdepthevent.cpython-38.pyc │ │ ├── exchangeinformation.cpython-38.pyc │ │ ├── fundingrate.cpython-38.pyc │ │ ├── liquidationorder.cpython-38.pyc │ │ ├── liquidationorderevent.cpython-38.pyc │ │ ├── listenkeyexpired.cpython-38.pyc │ │ ├── markprice.cpython-38.pyc │ │ ├── markpriceevent.cpython-38.pyc │ │ ├── message.cpython-38.pyc │ │ ├── mytrade.cpython-38.pyc │ │ ├── openinterest.cpython-38.pyc │ │ ├── order.cpython-38.pyc │ │ ├── orderOCO.cpython-38.pyc │ │ ├── orderbook.cpython-38.pyc │ │ ├── orderbookevent.cpython-38.pyc │ │ ├── orderupdate.cpython-38.pyc │ │ ├── positionmode.cpython-38.pyc │ │ ├── symbolbooktickerevent.cpython-38.pyc │ │ ├── symbolminitickerevent.cpython-38.pyc │ │ ├── symbolorderbook.cpython-38.pyc │ │ ├── symbolprice.cpython-38.pyc │ │ ├── symboltickerevent.cpython-38.pyc │ │ ├── tickerpricechangestatistics.cpython-38.pyc │ │ └── trade.cpython-38.pyc │ ├── accountinformation.py │ ├── accountupdate.py │ ├── aggregatetrade.py │ ├── aggregatetradeevent.py │ ├── averagePrice.py │ ├── candlestick.py │ ├── candlestickevent.py │ ├── constant.py │ ├── diffdepthevent.py │ ├── exchangeinformation.py │ ├── listenkeyexpired.py │ ├── mytrade.py │ ├── order.py │ ├── orderOCO.py │ ├── orderbook.py │ ├── orderbookevent.py │ ├── orderupdate.py │ ├── symbolbooktickerevent.py │ ├── symbolminitickerevent.py │ ├── symbolorderbook.py │ ├── symbolprice.py │ ├── symboltickerevent.py │ ├── tickerpricechangestatistics.py │ ├── trade.py │ └── tradeevent.py ├── requestclient.py └── subscriptionclient.py └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # VSCode 10 | .vscode/ 11 | 12 | service-account.json 13 | 14 | # Distribution / packaging 15 | .Python 16 | build/ 17 | develop-eggs/ 18 | dist/ 19 | downloads/ 20 | eggs/ 21 | .eggs/ 22 | lib/ 23 | lib64/ 24 | parts/ 25 | sdist/ 26 | var/ 27 | wheels/ 28 | share/python-wheels/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | MANIFEST 33 | 34 | # PyInstaller 35 | # Usually these files are written by a python script from a template 36 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 37 | *.manifest 38 | *.spec 39 | 40 | # Installer logs 41 | pip-log.txt 42 | pip-delete-this-directory.txt 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .nox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | *.py,cover 55 | .hypothesis/ 56 | .pytest_cache/ 57 | cover/ 58 | 59 | # Translations 60 | *.mo 61 | *.pot 62 | 63 | # Django stuff: 64 | *.log 65 | local_settings.py 66 | db.sqlite3 67 | db.sqlite3-journal 68 | 69 | # Flask stuff: 70 | instance/ 71 | .webassets-cache 72 | 73 | # Scrapy stuff: 74 | .scrapy 75 | 76 | # Sphinx documentation 77 | docs/_build/ 78 | 79 | # PyBuilder 80 | .pybuilder/ 81 | target/ 82 | 83 | # Jupyter Notebook 84 | .ipynb_checkpoints 85 | 86 | # IPython 87 | profile_default/ 88 | ipython_config.py 89 | 90 | # pyenv 91 | # For a library or package, you might want to ignore these files since the code is 92 | # intended to run in multiple environments; otherwise, check them in: 93 | # .python-version 94 | 95 | # pipenv 96 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 97 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 98 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 99 | # install all needed dependencies. 100 | #Pipfile.lock 101 | 102 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 103 | __pypackages__/ 104 | 105 | # Celery stuff 106 | celerybeat-schedule 107 | celerybeat.pid 108 | 109 | # SageMath parsed files 110 | *.sage.py 111 | 112 | # Environments 113 | .env 114 | .venv 115 | env/ 116 | venv/ 117 | ENV/ 118 | env.bak/ 119 | venv.bak/ 120 | 121 | # Spyder project settings 122 | .spyderproject 123 | .spyproject 124 | 125 | # Rope project settings 126 | .ropeproject 127 | 128 | # mkdocs documentation 129 | /site 130 | 131 | # mypy 132 | .mypy_cache/ 133 | .dmypy.json 134 | dmypy.json 135 | 136 | # Pyre type checker 137 | .pyre/ 138 | 139 | # pytype static type analyzer 140 | .pytype/ 141 | 142 | # Cython debug symbols 143 | cython_debug/ 144 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Abdeen and Tarun 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Binance API Library 2 | 3 | [![Status](https://img.shields.io/badge/build-passing-green.svg?branch=main)](https://github.com/AbdeenM/binance-api) 4 | [![Python](https://img.shields.io/badge/Python-v3.8.5-blue.svg?logo=python)](https://www.python.org/) 5 | 6 | A python library that implements the Binance Exchange REST API and Web socket communication. 7 | 8 | ## Installation 9 | 10 | ```Bash 11 | $ pip install solo-binance-api 12 | ``` 13 | 14 | You can uninstall the library anytime by running: 15 | 16 | ```Bash 17 | $ pip uninstall -y solo-binance-api 18 | ``` 19 | 20 | ## Getting Started 21 | 22 | Various implemenation for methods has been developed, a Docs is in progress to better illustrate the functions made, below is is an initial setup you can add to monitor logs and initialize your connection. 23 | 24 | ```Python 25 | import os 26 | import logging 27 | 28 | # Configuring logger 29 | logger = logging.getLogger('algo-trading') 30 | logger.setLevel(level=logging.INFO) 31 | 32 | # Setting logger handler 33 | handler = logging.StreamHandler() 34 | handler.setFormatter(logging.Formatter( 35 | '%(asctime)s - %(name)s - %(levelname)s - %(message)s')) 36 | logger.addHandler(handler) 37 | 38 | # Declaring binance account credentials 39 | API_KEY = os.getenv('binance_api_key') 40 | SECRET_KEY = os.getenv('binance_secret_key') 41 | 42 | # Initializing REST and Socket clients 43 | api_client = RequestClient(api_key=API_KEY, secret_key=SECRET_KEY, debug=False) 44 | subscription_client = SubscriptionClient( 45 | api_key=API_KEY, secret_key=SECRET_KEY) 46 | 47 | # Defining callback function and error function for socket subscriptions 48 | def callback(data_type: 'SubscribeMessageType', event: 'any'): 49 | if data_type == SubscribeMessageType.RESPONSE: 50 | print('Event ID: ', event) 51 | elif data_type == SubscribeMessageType.PAYLOAD: 52 | print('=========== Subscription Payload Data ===========') 53 | PrintBasic.print_obj(event) 54 | 55 | # Uncomment below to stop subscribtion 56 | # subscription_client.unsubscribe_all() 57 | else: 58 | print('Unknown Data: ', event) 59 | 60 | 61 | def error(e: 'BinanceApiException'): 62 | print(e.error_code + e.error_message) 63 | ``` 64 | 65 | ## Usage 66 | 67 | ```Python 68 | # Example 1: Getting old trade lookup (REST) 69 | old_trade = api_client.get_old_trade_lookup(symbol='BTCUSDT', 70 | limit=10) 71 | 72 | print('======= Example 1: Old Trade Look up Data =======') 73 | PrintMix.print_data(old_trade) 74 | print('=================================================') 75 | 76 | 77 | # Example 2: Getting CandlStick Data (REST) 78 | candle_data = api_client.get_candlestick_data(symbol='BTCUSDT', 79 | interval=CandlestickInterval.MIN1, 80 | startTime=None, 81 | endTime=None, 82 | limit=10) 83 | 84 | print('======= Example 2: Kline/Candlestick Data =======') 85 | PrintMix.print_data(candle_data) 86 | print('=================================================') 87 | 88 | 89 | # Example 3: Getting Symbol Price Ticker Data (REST) 90 | symbol_price = api_client.get_symbol_price_ticker(symbol='BTCUSDT') 91 | 92 | print('====== Example 3: Symbol Price Ticker Data ======') 93 | PrintMix.print_data(symbol_price) 94 | print('=================================================') 95 | 96 | 97 | # Example 4: Getting Order Data (REST) 98 | get_order = api_client.get_order(symbol='BTCUSDT', 99 | orderId='some-order-id') 100 | 101 | print('=========== Example 4: Get Order Data ===========') 102 | # PrintMix.print_data(get_order) 103 | print('=================================================') 104 | 105 | # Example 5: Posting an Order to binance (REST) 106 | post_order = api_client.post_test_order(symbol='BTCUSDT', 107 | side=OrderSide.BUY, 108 | ordertype=OrderType.MARKET, 109 | timeInForce=None, 110 | quantity=9, 111 | quoteOrderQty=None, 112 | price=None, 113 | newClientOrderId=None, 114 | stopPrice=None, 115 | icebergQty=None, 116 | newOrderRespType=OrderRespType.FULL) 117 | 118 | print('=========== Example 5: Post Order Data ==========') 119 | PrintMix.print_data(post_order) 120 | print('=================================================') 121 | 122 | # Example 6: Subscribe to Trade Stream 123 | subscription_client.subscribe_trade_event(symbol='btcusdt', 124 | callback=callback, 125 | error_handler=error) 126 | 127 | # Example 7: Subscribe to Symbol Book Ticker 128 | subscription_client.subscribe_symbol_bookticker_event(symbol='btcusdt', 129 | callback=callback, 130 | error_handler=error) 131 | 132 | # Example 8: Subscribe to Candle Stick 133 | subscription_client.subscribe_candlestick_event(symbol='btcusdt', 134 | interval=CandlestickInterval.MIN1, 135 | callback=callback, 136 | error_handler=error) 137 | ``` 138 | 139 | ## Project Status 140 | 141 | This project has great potential for improvements for the moment only the Binance Spot API is implemented based on their documentation, currently i wont be updating or modifying it due to time shortage but feel free to contribute! 142 | 143 | ## Contributing 144 | 145 | Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. Please make sure to update tests as appropriate. 146 | 147 | ## License 148 | 149 | Released under the **[MIT License](http://mit-license.org/)** 150 | 151 | Authored and Maintained by **[Abdeen Mohamed](https://github.com/AbdeenM)** -------------------------------------------------------------------------------- /binance-spot/__init__.py: -------------------------------------------------------------------------------- 1 | from common.scripts.binance_spot.requestclient import RequestClient 2 | from common.scripts.binance_spot.subscriptionclient import SubscriptionClient 3 | -------------------------------------------------------------------------------- /binance-spot/base/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/base/__init__.py -------------------------------------------------------------------------------- /binance-spot/base/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/base/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/base/__pycache__/printobject.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/base/__pycache__/printobject.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/base/__pycache__/printtime.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/base/__pycache__/printtime.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/base/printobject.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | BASIC_DATA_TYPE = (int, str, float) 4 | BASIC_DATA_TYPE_BOOL = (bool) 5 | 6 | TYPE_BASIC = "type_basic" 7 | TYPE_BOOL = "type_bool" 8 | TYPE_OBJECT = "type_object" 9 | TYPE_LIST = "type_list" 10 | TYPE_DICT = "type_dict" 11 | TYPE_UNDEFINED = "type_undefined" 12 | 13 | 14 | class TypeCheck: 15 | @staticmethod 16 | def is_list(obj): 17 | return type(obj) == list and isinstance(obj, list) 18 | 19 | @staticmethod 20 | def is_dict(obj): 21 | return type(obj) == dict and isinstance(obj, dict) 22 | 23 | @staticmethod 24 | def is_object(obj): 25 | return isinstance(obj, object) 26 | 27 | @staticmethod 28 | def is_basic(obj): 29 | return isinstance(obj, BASIC_DATA_TYPE) 30 | 31 | @staticmethod 32 | def is_bool(obj): 33 | return isinstance(obj, bool) 34 | 35 | @staticmethod 36 | def get_obj_type(obj): 37 | if TypeCheck.is_basic(obj): 38 | return TYPE_BASIC 39 | elif TypeCheck.is_bool(obj): 40 | return TYPE_BOOL 41 | elif TypeCheck.is_list(obj): 42 | return TYPE_LIST 43 | elif TypeCheck.is_dict(obj): 44 | return TYPE_DICT 45 | elif TypeCheck.is_object(obj): 46 | return TYPE_OBJECT 47 | else: 48 | return TYPE_UNDEFINED 49 | 50 | 51 | class PrintBasic: 52 | @staticmethod 53 | def print_basic(data, name=None): 54 | if name and len(name): 55 | print(str(name) + " : " + str(data)) 56 | else: 57 | print(str(data)) 58 | 59 | @staticmethod 60 | def print_basic_bool(data, name=None): 61 | bool_desc = "True" 62 | if not data: 63 | bool_desc = "False" 64 | 65 | if name and len(name): 66 | print(str(name) + " : " + str(bool_desc)) 67 | else: 68 | print(str(bool_desc)) 69 | 70 | @staticmethod 71 | def print_obj(obj): 72 | if not obj: 73 | return -1 74 | 75 | members = [attr for attr in dir(obj) if not callable( 76 | attr) and not attr.startswith("__")] 77 | for member_def in members: 78 | val_str = str(getattr(obj, member_def)) 79 | print(member_def + ":" + val_str) 80 | return 0 81 | 82 | 83 | class PrintList: 84 | @staticmethod 85 | def print_list_data(obj): 86 | if not obj: 87 | print("object is None") 88 | return -1 89 | 90 | if TypeCheck.get_obj_type(obj) == TYPE_LIST: 91 | for idx, row in enumerate(obj): 92 | PrintBasic.print_basic(row) 93 | else: 94 | return -2 95 | 96 | return 0 97 | 98 | @staticmethod 99 | def print_origin_object(obj): 100 | if not obj: 101 | print("object is None") 102 | return -1 103 | obj_type = TypeCheck.get_obj_type(obj) 104 | 105 | if obj_type == TYPE_BASIC: 106 | PrintBasic.print_basic(obj) 107 | elif obj_type == TYPE_BOOL: 108 | PrintBasic.print_basic_bool(obj) 109 | elif obj_type == TYPE_OBJECT: 110 | PrintBasic.print_obj(obj) 111 | else: 112 | return 1 113 | 114 | return 0 115 | 116 | @staticmethod 117 | def print_object_list(obj_list): 118 | if not obj_list: 119 | return -1 120 | 121 | obj_type = TypeCheck.get_obj_type(obj_list) 122 | if obj_type != TYPE_LIST: 123 | return -2 124 | 125 | print("data count : ", (len(obj_list))) 126 | print("\n") 127 | for idx, row in enumerate(obj_list): 128 | print("data number " + (str(idx)) + " :") 129 | PrintList.print_origin_object(row) 130 | print("\n") 131 | print("\n\n") 132 | 133 | return 0 134 | 135 | @staticmethod 136 | def print_object_dict(obj_dict): 137 | if not obj_dict: 138 | return -1 139 | 140 | obj_type = TypeCheck.get_obj_type(obj_dict) 141 | if obj_type != TYPE_DICT: 142 | return -2 143 | 144 | print("data count : ", (len(obj_dict))) 145 | print("\n") 146 | for key, row in obj_dict.items(): 147 | PrintBasic.print_basic(str(key) + " :") 148 | PrintList.print_origin_object(row) 149 | print("\n") 150 | print("\n\n") 151 | 152 | return 0 153 | 154 | 155 | class PrintMix: 156 | @staticmethod 157 | def print_data(data): 158 | if not data: 159 | print(sys._getframe().f_code.co_name + " none data") 160 | return -1 161 | 162 | obj_type = TypeCheck.get_obj_type(data) 163 | 164 | if obj_type == TYPE_BASIC: 165 | PrintBasic.print_basic(data) 166 | elif obj_type == TYPE_BOOL: 167 | PrintBasic.print_basic_bool(data) 168 | elif obj_type == TYPE_LIST: 169 | PrintList.print_object_list(data) 170 | elif obj_type == TYPE_DICT: 171 | PrintList.print_object_dict(data) 172 | elif obj_type == TYPE_OBJECT: 173 | PrintList.print_origin_object(data) 174 | else: 175 | print(sys._getframe().f_code.co_name + " enter unknown") 176 | return -2 177 | 178 | return 0 179 | 180 | 181 | if __name__ == "__main__": 182 | """ 183 | from common.scripts.binance_spot.model.symbol import Symbol 184 | 185 | symbol_1 = Symbol() 186 | symbol_1.amount_precision = 10009 187 | symbol_1.symbol = "btcusdt" 188 | 189 | symbol_2 = Symbol() 190 | symbol_2.amount_precision = 28 191 | symbol_2.symbol = "htusdt" 192 | 193 | symbol_3 = Symbol() 194 | symbol_3.amount_precision = 26 195 | symbol_3.symbol = "eosusdt" 196 | 197 | symbol_list = [symbol_1, symbol_2, symbol_3] 198 | symbol_dict = {"one": symbol_1, "two": symbol_2, "three": symbol_3} 199 | PrintMix.print_data(symbol_list) 200 | PrintMix.print_data(symbol_dict) 201 | 202 | print(type(symbol_list) == list) 203 | print(type(symbol_dict) == dict) 204 | print(type(symbol_list) == object) 205 | print(isinstance(symbol_list, list)) 206 | print(isinstance(symbol_list, object)) 207 | print(isinstance(symbol_dict, dict)) 208 | print(isinstance(symbol_dict, object)) 209 | """ 210 | 211 | a = ['s', 'h', 'i'] 212 | PrintList.print_list_data(a) 213 | -------------------------------------------------------------------------------- /binance-spot/constant/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/constant/__init__.py -------------------------------------------------------------------------------- /binance-spot/constant/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/constant/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/constant/__pycache__/system.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/constant/__pycache__/system.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/constant/system.py: -------------------------------------------------------------------------------- 1 | 2 | class WebSocketDefine: 3 | Uri = 'wss://stream.binance.com:9443/ws' 4 | 5 | 6 | class RestApiDefine: 7 | Url = 'https://api.binance.com' 8 | -------------------------------------------------------------------------------- /binance-spot/examples.py: -------------------------------------------------------------------------------- 1 | from common.scripts.binance_spot import * 2 | from common.scripts.binance_spot.model.constant import * 3 | from common.scripts.binance_spot.base.printobject import * 4 | from common.scripts.binance_spot.exception.binanceapiexception import BinanceApiException 5 | import os 6 | import sys 7 | import logging 8 | sys.path.insert(0, '/home/mephisto/Work/Project Algo/algo-trading/') 9 | 10 | 11 | # Configuring logger 12 | logger = logging.getLogger('algo-trading') 13 | logger.setLevel(level=logging.INFO) 14 | 15 | # Setting logger handler 16 | handler = logging.StreamHandler() 17 | handler.setFormatter(logging.Formatter( 18 | '%(asctime)s - %(name)s - %(levelname)s - %(message)s')) 19 | logger.addHandler(handler) 20 | 21 | # Declaring binance account credentials 22 | API_KEY = os.getenv('binance_api_key') 23 | SECRET_KEY = os.getenv('binance_secret_key') 24 | 25 | # Initializing REST and Socket clients 26 | api_client = RequestClient(api_key=API_KEY, secret_key=SECRET_KEY, debug=False) 27 | subscription_client = SubscriptionClient( 28 | api_key=API_KEY, secret_key=SECRET_KEY) 29 | 30 | # Defining callback function and error function for socket subscriptions 31 | def callback(data_type: 'SubscribeMessageType', event: 'any'): 32 | if data_type == SubscribeMessageType.RESPONSE: 33 | print('Event ID: ', event) 34 | elif data_type == SubscribeMessageType.PAYLOAD: 35 | print('=========== Subscription Payload Data ===========') 36 | PrintBasic.print_obj(event) 37 | 38 | # Uncomment below to stop subscribtion 39 | # subscription_client.unsubscribe_all() 40 | else: 41 | print('Unknown Data: ', event) 42 | 43 | 44 | def error(e: 'BinanceApiException'): 45 | print(e.error_code + e.error_message) 46 | 47 | 48 | # Example 1: Getting old trade lookup (REST) 49 | old_trade = api_client.get_old_trade_lookup(symbol='BTCUSDT', 50 | limit=10) 51 | 52 | print('======= Example 1: Old Trade Look up Data =======') 53 | PrintMix.print_data(old_trade) 54 | print('=================================================') 55 | 56 | 57 | # Example 2: Getting CandlStick Data (REST) 58 | candle_data = api_client.get_candlestick_data(symbol='BTCUSDT', 59 | interval=CandlestickInterval.MIN1, 60 | startTime=None, 61 | endTime=None, 62 | limit=10) 63 | 64 | print('======= Example 2: Kline/Candlestick Data =======') 65 | PrintMix.print_data(candle_data) 66 | print('=================================================') 67 | 68 | 69 | # Example 3: Getting Symbol Price Ticker Data (REST) 70 | symbol_price = api_client.get_symbol_price_ticker(symbol='BTCUSDT') 71 | 72 | print('====== Example 3: Symbol Price Ticker Data ======') 73 | PrintMix.print_data(symbol_price) 74 | print('=================================================') 75 | 76 | 77 | # Example 4: Getting Order Data (REST) 78 | get_order = api_client.get_order(symbol='BTCUSDT', 79 | orderId='some-order-id') 80 | 81 | print('=========== Example 4: Get Order Data ===========') 82 | # PrintMix.print_data(get_order) 83 | print('=================================================') 84 | 85 | # Example 5: Posting an Order to binance (REST) 86 | post_order = api_client.post_test_order(symbol='BTCUSDT', 87 | side=OrderSide.BUY, 88 | ordertype=OrderType.MARKET, 89 | timeInForce=None, 90 | quantity=9, 91 | quoteOrderQty=None, 92 | price=None, 93 | newClientOrderId=None, 94 | stopPrice=None, 95 | icebergQty=None, 96 | newOrderRespType=OrderRespType.FULL) 97 | 98 | print('=========== Example 5: Post Order Data ==========') 99 | PrintMix.print_data(post_order) 100 | print('=================================================') 101 | 102 | # Example 6: Subscribe to Trade Stream 103 | subscription_client.subscribe_trade_event(symbol='btcusdt', 104 | callback=callback, 105 | error_handler=error) 106 | 107 | # Example 7: Subscribe to Symbol Book Ticker 108 | subscription_client.subscribe_symbol_bookticker_event(symbol='btcusdt', 109 | callback=callback, 110 | error_handler=error) 111 | 112 | # Example 8: Subscribe to Candle Stick 113 | subscription_client.subscribe_candlestick_event(symbol='btcusdt', 114 | interval=CandlestickInterval.MIN1, 115 | callback=callback, 116 | error_handler=error) 117 | -------------------------------------------------------------------------------- /binance-spot/exception/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/exception/__init__.py -------------------------------------------------------------------------------- /binance-spot/exception/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/exception/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/exception/__pycache__/binanceapiexception.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/exception/__pycache__/binanceapiexception.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/exception/binanceapiexception.py: -------------------------------------------------------------------------------- 1 | 2 | class BinanceApiException(Exception): 3 | 4 | RUNTIME_ERROR = 'RuntimeError' 5 | INPUT_ERROR = 'InputError' 6 | KEY_MISSING = 'KeyMissing' 7 | SYS_ERROR = 'SysError' 8 | SUBSCRIPTION_ERROR = 'SubscriptionError' 9 | ENV_ERROR = 'EnvironmentError' 10 | EXEC_ERROR = 'ExecuteError' 11 | 12 | def __init__(self, error_code, error_message): 13 | self.error_code = error_code 14 | self.error_message = error_message 15 | -------------------------------------------------------------------------------- /binance-spot/impl/__init__.py: -------------------------------------------------------------------------------- 1 | from common.scripts.binance_spot.impl.restapirequest import RestApiRequest 2 | -------------------------------------------------------------------------------- /binance-spot/impl/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/__pycache__/restapiinvoker.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/__pycache__/restapiinvoker.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/__pycache__/restapirequest.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/__pycache__/restapirequest.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/__pycache__/restapirequestimpl.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/__pycache__/restapirequestimpl.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/__pycache__/websocketconnection.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/__pycache__/websocketconnection.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/__pycache__/websocketrequest.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/__pycache__/websocketrequest.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/__pycache__/websocketrequestimpl.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/__pycache__/websocketrequestimpl.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/__pycache__/websocketwatchdog.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/__pycache__/websocketwatchdog.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/restapiinvoker.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from common.scripts.binance_spot.exception.binanceapiexception import BinanceApiException 3 | from common.scripts.binance_spot.impl.utils import * 4 | # from common.scripts.binance_spot.base.printobject import * 5 | 6 | 7 | def check_response(json_wrapper): 8 | if json_wrapper.contain_key('success'): 9 | success = json_wrapper.get_boolean('success') 10 | if success is False: 11 | err_code = json_wrapper.get_int_or_default('code', '') 12 | err_msg = json_wrapper.get_string_or_default('msg', '') 13 | if err_code == '': 14 | raise BinanceApiException( 15 | BinanceApiException.EXEC_ERROR, '[Executing] ' + err_msg) 16 | else: 17 | raise BinanceApiException( 18 | BinanceApiException.EXEC_ERROR, '[Executing] ' + str(err_code) + ': ' + err_msg) 19 | elif json_wrapper.contain_key('code'): 20 | code = json_wrapper.get_int('code') 21 | msg = json_wrapper.get_string_or_default('msg', '') 22 | if code != 200: 23 | raise BinanceApiException( 24 | BinanceApiException.EXEC_ERROR, '[Executing] ' + str(code) + ': ' + msg) 25 | 26 | 27 | def get_limits_usage(response): 28 | limits = {} 29 | limits_headers = ['X-MBX-USED-WEIGHT-', 30 | 'X-MBX-ORDER-COUNT-'] # Limit headers to catch 31 | for key, value in response.headers.items(): 32 | if any([key.startswith(h) for h in limits_headers]): 33 | limits[key] = value 34 | return limits 35 | 36 | 37 | def call_sync(request, debug=False): 38 | if request.method == 'GET': 39 | response = requests.get( 40 | request.host + request.url, headers=request.header) 41 | limits = get_limits_usage(response) 42 | json_wrapper = parse_json_from_string(response.text) 43 | if debug: 44 | print(response.text) 45 | check_response(json_wrapper) 46 | return (request.json_parser(json_wrapper), limits) 47 | elif request.method == 'POST': 48 | response = requests.post( 49 | request.host + request.url, headers=request.header) 50 | limits = get_limits_usage(response) 51 | json_wrapper = parse_json_from_string(response.text) 52 | if debug: 53 | print(response.text) 54 | check_response(json_wrapper) 55 | return (request.json_parser(json_wrapper), limits) 56 | elif request.method == 'DELETE': 57 | response = requests.delete( 58 | request.host + request.url, headers=request.header) 59 | limits = get_limits_usage(response) 60 | json_wrapper = parse_json_from_string(response.text) 61 | if debug: 62 | print(response.text) 63 | check_response(json_wrapper) 64 | return (request.json_parser(json_wrapper), limits) 65 | elif request.method == 'PUT': 66 | response = requests.put( 67 | request.host + request.url, headers=request.header) 68 | limits = get_limits_usage(response) 69 | json_wrapper = parse_json_from_string(response.text) 70 | if debug: 71 | print(response.text) 72 | check_response(json_wrapper) 73 | return (request.json_parser(json_wrapper), limits) 74 | -------------------------------------------------------------------------------- /binance-spot/impl/restapirequest.py: -------------------------------------------------------------------------------- 1 | 2 | class RestApiRequest(object): 3 | 4 | def __init__(self): 5 | self.method = '' 6 | self.url = '' 7 | self.host = '' 8 | self.post_body = '' 9 | self.header = dict() 10 | self.json_parser = None 11 | # self.header.update( 12 | # {'client_SDK_Version': 'binanceutures-1.0.1-py3.7'}) 13 | -------------------------------------------------------------------------------- /binance-spot/impl/restapirequestimpl.py: -------------------------------------------------------------------------------- 1 | from common.scripts.binance_spot.impl import RestApiRequest 2 | from common.scripts.binance_spot.impl.utils.urlparamsbuilder import UrlParamsBuilder 3 | from common.scripts.binance_spot.impl.utils.apisignature import create_signature 4 | from common.scripts.binance_spot.impl.utils.inputchecker import * 5 | from common.scripts.binance_spot.impl.utils.timeservice import * 6 | from common.scripts.binance_spot.model import * 7 | # For develop 8 | from common.scripts.binance_spot.base.printobject import * 9 | 10 | 11 | class RestApiRequestImpl(object): 12 | 13 | def __init__(self, api_key, secret_key, server_url='https://api.binance.com', debug=False): 14 | self.__api_key = api_key 15 | self.__secret_key = secret_key 16 | self.__server_url = server_url 17 | self.__debug = debug 18 | 19 | def __create_request_by_get(self, url, builder): 20 | request = RestApiRequest() 21 | request.method = 'GET' 22 | request.host = self.__server_url 23 | request.header.update({'Content-Type': 'application/json'}) 24 | request.url = url + '?' + builder.build_url() 25 | 26 | if self.__debug == True: 27 | print('====== Request ======') 28 | print(request) 29 | PrintMix.print_data(request) 30 | print('=====================') 31 | return request 32 | 33 | def __create_request_by_get_with_apikey(self, url, builder): 34 | request = RestApiRequest() 35 | request.method = 'GET' 36 | request.host = self.__server_url 37 | request.header.update({'Content-Type': 'application/json'}) 38 | request.header.update({'X-MBX-APIKEY': self.__api_key}) 39 | request.url = url + '?' + builder.build_url() 40 | 41 | if self.__debug == True: 42 | print('====== Request ======') 43 | print(request) 44 | PrintMix.print_data(request) 45 | print('=====================') 46 | return request 47 | 48 | def __create_request_by_post_with_signature(self, url, builder): 49 | request = RestApiRequest() 50 | request.method = 'POST' 51 | request.host = self.__server_url 52 | builder.put_url('recvWindow', 60000) 53 | builder.put_url('timestamp', str(get_current_timestamp() - 1000)) 54 | create_signature(self.__secret_key, builder) 55 | request.header.update({'Content-Type': 'application/json'}) 56 | request.header.update({'X-MBX-APIKEY': self.__api_key}) 57 | request.post_body = builder.post_map 58 | request.url = url + '?' + builder.build_url() 59 | 60 | if self.__debug == True: 61 | print('====== Request ======') 62 | print(request) 63 | PrintMix.print_data(request) 64 | print('=====================') 65 | return request 66 | 67 | def __create_request_by_delete_with_signature(self, url, builder): 68 | request = RestApiRequest() 69 | request.method = 'DELETE' 70 | request.host = self.__server_url 71 | builder.put_url('recvWindow', 60000) 72 | builder.put_url('timestamp', str(get_current_timestamp() - 1000)) 73 | create_signature(self.__secret_key, builder) 74 | request.header.update({'Content-Type': 'application/json'}) 75 | request.header.update({'X-MBX-APIKEY': self.__api_key}) 76 | request.url = url + '?' + builder.build_url() 77 | 78 | if self.__debug == True: 79 | print('====== Request ======') 80 | print(request) 81 | PrintMix.print_data(request) 82 | print('=====================') 83 | return request 84 | 85 | def __create_request_by_get_with_signature(self, url, builder): 86 | request = RestApiRequest() 87 | request.method = 'GET' 88 | request.host = self.__server_url 89 | builder.put_url('recvWindow', 60000) 90 | builder.put_url('timestamp', str(get_current_timestamp() - 1000)) 91 | create_signature(self.__secret_key, builder) 92 | request.header.update( 93 | {'Content-Type': 'application/x-www-form-urlencoded'}) 94 | request.header.update({'X-MBX-APIKEY': self.__api_key}) 95 | request.url = url + '?' + builder.build_url() 96 | 97 | if self.__debug == True: 98 | print('====== Request ======') 99 | print(request) 100 | PrintMix.print_data(request) 101 | print('=====================') 102 | return request 103 | 104 | def __create_request_by_put_with_signature(self, url, builder): 105 | request = RestApiRequest() 106 | request.method = 'PUT' 107 | request.host = self.__server_url 108 | builder.put_url('recvWindow', 60000) 109 | builder.put_url('timestamp', str(get_current_timestamp() - 1000)) 110 | create_signature(self.__secret_key, builder) 111 | request.header.update({'Content-Type': 'application/json'}) 112 | request.header.update({'X-MBX-APIKEY': self.__api_key}) 113 | request.url = url + '?' + builder.build_url() 114 | 115 | if self.__debug == True: 116 | print('====== Request ======') 117 | print(request) 118 | PrintMix.print_data(request) 119 | print('=====================') 120 | return request 121 | 122 | def test_connectivity(self): 123 | builder = UrlParamsBuilder() 124 | request = self.__create_request_by_get('/api/v3/ping', builder) 125 | 126 | def parse(json_wrapper): 127 | result = 'OK' 128 | return result 129 | 130 | request.json_parser = parse 131 | return request 132 | 133 | def get_servertime(self): 134 | builder = UrlParamsBuilder() 135 | request = self.__create_request_by_get('/api/v3/time', builder) 136 | 137 | def parse(json_wrapper): 138 | result = json_wrapper.get_int('serverTime') 139 | return result 140 | 141 | request.json_parser = parse 142 | return request 143 | 144 | def get_exchange_information(self): 145 | builder = UrlParamsBuilder() 146 | request = self.__create_request_by_get( 147 | '/api/v3/exchangeInfo', builder) 148 | 149 | def parse(json_wrapper): 150 | result = ExchangeInformation.json_parse(json_wrapper) 151 | return result 152 | 153 | request.json_parser = parse 154 | return request 155 | 156 | def get_order_book(self, symbol, limit): 157 | check_should_not_none(symbol, 'symbol') 158 | builder = UrlParamsBuilder() 159 | builder.put_url('symbol', symbol) 160 | builder.put_url('limit', limit) 161 | 162 | request = self.__create_request_by_get('/api/v3/depth', builder) 163 | 164 | def parse(json_wrapper): 165 | result = OrderBook.json_parse(json_wrapper) 166 | return result 167 | 168 | request.json_parser = parse 169 | return request 170 | 171 | def get_recent_trades_list(self, symbol, limit): 172 | check_should_not_none(symbol, 'symbol') 173 | builder = UrlParamsBuilder() 174 | builder.put_url('symbol', symbol) 175 | builder.put_url('limit', limit) 176 | 177 | request = self.__create_request_by_get('/api/v3/trades', builder) 178 | 179 | def parse(json_wrapper): 180 | result = list() 181 | data_list = json_wrapper.convert_2_array() 182 | for item in data_list.get_items(): 183 | element = Trade.json_parse(item) 184 | result.append(element) 185 | return result 186 | 187 | request.json_parser = parse 188 | return request 189 | 190 | def get_old_trade_lookup(self, symbol, limit, fromId): 191 | check_should_not_none(symbol, 'symbol') 192 | builder = UrlParamsBuilder() 193 | builder.put_url('symbol', symbol) 194 | builder.put_url('limit', limit) 195 | builder.put_url('fromId', fromId) 196 | 197 | request = self.__create_request_by_get_with_apikey( 198 | '/api/v3/historicalTrades', builder) 199 | 200 | def parse(json_wrapper): 201 | result = list() 202 | data_list = json_wrapper.convert_2_array() 203 | for item in data_list.get_items(): 204 | element = Trade.json_parse(item) 205 | result.append(element) 206 | return result 207 | 208 | request.json_parser = parse 209 | return request 210 | 211 | def get_aggregate_trades_list(self, symbol, fromId, startTime, endTime, limit): 212 | check_should_not_none(symbol, 'symbol') 213 | builder = UrlParamsBuilder() 214 | builder.put_url('symbol', symbol) 215 | builder.put_url('fromId', fromId) 216 | builder.put_url('startTime', startTime) 217 | builder.put_url('endTime', endTime) 218 | builder.put_url('limit', limit) 219 | 220 | request = self.__create_request_by_get('/api/v3/aggTrades', builder) 221 | 222 | def parse(json_wrapper): 223 | aggregate_trades_list = list() 224 | data_list = json_wrapper.convert_2_array() 225 | for item in data_list.get_items(): 226 | trade = AggregateTrade.json_parse(item) 227 | aggregate_trades_list.append(trade) 228 | return aggregate_trades_list 229 | 230 | request.json_parser = parse 231 | return request 232 | 233 | def get_candlestick_data(self, symbol, interval, startTime, endTime, limit): 234 | check_should_not_none(symbol, 'symbol') 235 | check_should_not_none(symbol, 'interval') 236 | builder = UrlParamsBuilder() 237 | builder.put_url('symbol', symbol) 238 | builder.put_url('interval', interval) 239 | builder.put_url('startTime', startTime) 240 | builder.put_url('endTime', endTime) 241 | builder.put_url('limit', limit) 242 | 243 | request = self.__create_request_by_get('/api/v3/klines', builder) 244 | 245 | def parse(json_wrapper): 246 | result = list() 247 | data_list = json_wrapper.convert_2_array() 248 | for item in data_list.get_items(): 249 | element = Candlestick.json_parse(item) 250 | result.append(element) 251 | return result 252 | 253 | request.json_parser = parse 254 | return request 255 | 256 | def get_current_average_price(self, symbol): 257 | check_should_not_none(symbol, 'symbol') 258 | builder = UrlParamsBuilder() 259 | builder.put_url('symbol', symbol) 260 | 261 | request = self.__create_request_by_get( 262 | '/api/v3/avgPrice', builder) 263 | 264 | def parse(json_wrapper): 265 | result = AveragePrice.json_parse(json_wrapper) 266 | return result 267 | 268 | request.json_parser = parse 269 | return request 270 | 271 | def get_ticker_price_change_statistics(self, symbol): 272 | builder = UrlParamsBuilder() 273 | builder.put_url('symbol', symbol) 274 | 275 | request = self.__create_request_by_get('/api/v3/ticker/24hr', builder) 276 | 277 | def parse(json_wrapper): 278 | result = list() 279 | 280 | if symbol: 281 | element = TickerPriceChangeStatistics.json_parse(json_wrapper) 282 | result.append(element) 283 | else: 284 | data_list = json_wrapper.convert_2_array() 285 | for item in data_list.get_items(): 286 | element = TickerPriceChangeStatistics.json_parse(item) 287 | result.append(element) 288 | 289 | return result 290 | 291 | request.json_parser = parse 292 | return request 293 | 294 | def get_symbol_price_ticker(self, symbol): 295 | builder = UrlParamsBuilder() 296 | builder.put_url('symbol', symbol) 297 | 298 | request = self.__create_request_by_get( 299 | '/api/v3/ticker/price', builder) 300 | 301 | def parse(json_wrapper): 302 | result = list() 303 | 304 | if symbol: 305 | element = SymbolPrice.json_parse(json_wrapper) 306 | result.append(element) 307 | else: 308 | data_list = json_wrapper.convert_2_array() 309 | for item in data_list.get_items(): 310 | element = SymbolPrice.json_parse(item) 311 | result.append(element) 312 | return result 313 | 314 | request.json_parser = parse 315 | return request 316 | 317 | def get_symbol_orderbook_ticker(self, symbol): 318 | builder = UrlParamsBuilder() 319 | builder.put_url('symbol', symbol) 320 | 321 | request = self.__create_request_by_get( 322 | '/api/v3/ticker/bookTicker', builder) 323 | 324 | def parse(json_wrapper): 325 | result = list() 326 | 327 | if symbol: 328 | element = SymbolOrderBook.json_parse(json_wrapper) 329 | result.append(element) 330 | else: 331 | data_list = json_wrapper.convert_2_array() 332 | for item in data_list.get_items(): 333 | element = SymbolOrderBook.json_parse(item) 334 | result.append(element) 335 | return result 336 | 337 | request.json_parser = parse 338 | return request 339 | 340 | def post_test_order(self, symbol, side, ordertype, 341 | timeInForce, quantity, quoteOrderQty, price, 342 | newClientOrderId, stopPrice, icebergQty, newOrderRespType): 343 | check_should_not_none(symbol, 'symbol') 344 | check_should_not_none(side, 'side') 345 | check_should_not_none(ordertype, 'ordertype') 346 | builder = UrlParamsBuilder() 347 | builder.put_url('symbol', symbol) 348 | builder.put_url('side', side) 349 | builder.put_url('type', ordertype) 350 | builder.put_url('timeInForce', timeInForce) 351 | builder.put_url('quantity', quantity) 352 | builder.put_url('quoteOrderQty', quoteOrderQty) 353 | builder.put_url('price', price) 354 | builder.put_url('newClientOrderId', newClientOrderId) 355 | builder.put_url('stopPrice', stopPrice) 356 | builder.put_url('icebergQty', icebergQty) 357 | builder.put_url('newOrderRespType', newOrderRespType) 358 | 359 | request = self.__create_request_by_post_with_signature( 360 | '/api/v3/order/test', builder) 361 | 362 | def parse(json_wrapper): 363 | result = 'OK' 364 | return result 365 | 366 | request.json_parser = parse 367 | return request 368 | 369 | def post_order(self, symbol, side, ordertype, 370 | timeInForce, quantity, quoteOrderQty, price, 371 | newClientOrderId, stopPrice, icebergQty, newOrderRespType): 372 | check_should_not_none(symbol, 'symbol') 373 | check_should_not_none(side, 'side') 374 | check_should_not_none(ordertype, 'ordertype') 375 | builder = UrlParamsBuilder() 376 | builder.put_url('symbol', symbol) 377 | builder.put_url('side', side) 378 | builder.put_url('type', ordertype) 379 | builder.put_url('timeInForce', timeInForce) 380 | builder.put_url('quantity', quantity) 381 | builder.put_url('quoteOrderQty', quoteOrderQty) 382 | builder.put_url('price', price) 383 | builder.put_url('newClientOrderId', newClientOrderId) 384 | builder.put_url('stopPrice', stopPrice) 385 | builder.put_url('icebergQty', icebergQty) 386 | builder.put_url('newOrderRespType', newOrderRespType) 387 | 388 | request = self.__create_request_by_post_with_signature( 389 | '/api/v3/order', builder) 390 | 391 | def parse(json_wrapper): 392 | result = Order.json_parse(json_wrapper) 393 | return result 394 | 395 | request.json_parser = parse 396 | return request 397 | 398 | def cancel_order(self, symbol, orderId, newClientOrderId): 399 | check_should_not_none(symbol, 'symbol') 400 | builder = UrlParamsBuilder() 401 | builder.put_url('symbol', symbol) 402 | builder.put_url('orderId', orderId) 403 | builder.put_url('newClientOrderId', newClientOrderId) 404 | 405 | request = self.__create_request_by_delete_with_signature( 406 | '/api/v3/order', builder) 407 | 408 | def parse(json_wrapper): 409 | result = Order.json_parse(json_wrapper) 410 | return result 411 | 412 | request.json_parser = parse 413 | return request 414 | 415 | def cancel_all_orders(self, symbol): 416 | check_should_not_none(symbol, 'symbol') 417 | builder = UrlParamsBuilder() 418 | builder.put_url('symbol', symbol) 419 | 420 | request = self.__create_request_by_delete_with_signature( 421 | 'api/v3/openOrders', builder) 422 | 423 | def parse(json_wrapper): 424 | result = list() 425 | data_list = json_wrapper.convert_2_array() 426 | for item in data_list.get_items(): 427 | element = Order.json_parse(item) 428 | result.append(element) 429 | 430 | return result 431 | 432 | request.json_parser = parse 433 | return request 434 | 435 | def get_order(self, symbol, orderId): 436 | check_should_not_none(symbol, 'symbol') 437 | builder = UrlParamsBuilder() 438 | builder.put_url('symbol', symbol) 439 | builder.put_url('orderId', orderId) 440 | 441 | request = self.__create_request_by_get_with_signature( 442 | '/api/v3/order', builder) 443 | 444 | def parse(json_wrapper): 445 | result = Order.json_parse(json_wrapper) 446 | return result 447 | 448 | request.json_parser = parse 449 | return request 450 | 451 | def get_open_orders(self, symbol): 452 | builder = UrlParamsBuilder() 453 | builder.put_url('symbol', symbol) 454 | 455 | request = self.__create_request_by_get_with_signature( 456 | '/api/v3/openOrders', builder) 457 | 458 | def parse(json_wrapper): 459 | result = list() 460 | 461 | if symbol: 462 | element = Order.json_parse(json_wrapper) 463 | result.append(element) 464 | else: 465 | data_list = json_wrapper.convert_2_array() 466 | for item in data_list.get_items(): 467 | element = Order.json_parse(item) 468 | result.append(element) 469 | return result 470 | 471 | request.json_parser = parse 472 | return request 473 | 474 | def get_all_orders(self, symbol, orderId, startTime, endTime, limit): 475 | check_should_not_none(symbol, 'symbol') 476 | builder = UrlParamsBuilder() 477 | builder.put_url('symbol', symbol) 478 | builder.put_url('orderId', orderId) 479 | builder.put_url('startTime', startTime) 480 | builder.put_url('endTime', endTime) 481 | builder.put_url('limit', limit) 482 | 483 | request = self.__create_request_by_get_with_signature( 484 | '/api/v3/allOrders', builder) 485 | 486 | def parse(json_wrapper): 487 | result = list() 488 | data_list = json_wrapper.convert_2_array() 489 | for item in data_list.get_items(): 490 | element = Order.json_parse(item) 491 | result.append(element) 492 | return result 493 | 494 | request.json_parser = parse 495 | return request 496 | 497 | def post_oco_order(self, symbol, listClientOrderId, side, 498 | quantity, limitClientOrderId, price, 499 | limitIcebergQty, stopClientOrderId, 500 | stopPrice, stopLimitPrice, stopIcebergQty, 501 | stopLimitTimeInForce, newOrderRespType): 502 | check_should_not_none(symbol, 'symbol') 503 | check_should_not_none(side, 'side') 504 | check_should_not_none(quantity, 'quantity') 505 | check_should_not_none(price, 'price') 506 | check_should_not_none(stopPrice, 'stopPrice') 507 | builder = UrlParamsBuilder() 508 | builder.put_url('symbol', symbol) 509 | builder.put_url('listClientOrderId', listClientOrderId) 510 | builder.put_url('side', side) 511 | builder.put_url('quantity', quantity) 512 | builder.put_url('limitClientOrderId', limitClientOrderId) 513 | builder.put_url('price', price) 514 | builder.put_url('limitIcebergQty', limitIcebergQty) 515 | builder.put_url('stopClientOrderId', stopClientOrderId) 516 | builder.put_url('stopPrice', stopPrice) 517 | builder.put_url('stopLimitPrice', stopLimitPrice) 518 | builder.put_url('stopIcebergQty', stopIcebergQty) 519 | builder.put_url('stopLimitTimeInForce', stopLimitTimeInForce) 520 | builder.put_url('newOrderRespType', newOrderRespType) 521 | 522 | request = self.__create_request_by_post_with_signature( 523 | '/api/v3/order/oco', builder) 524 | 525 | def parse(json_wrapper): 526 | result = OrderOCO.json_parse(json_wrapper) 527 | return result 528 | 529 | request.json_parser = parse 530 | return request 531 | 532 | def cancel_oco_order(self, symbol, orderListId, listClientOrderId, newClientOrderId): 533 | check_should_not_none(symbol, 'symbol') 534 | builder = UrlParamsBuilder() 535 | builder.put_url('symbol', symbol) 536 | builder.put_url('orderListId', orderListId) 537 | builder.put_url('listClientOrderId', listClientOrderId) 538 | builder.put_url('newClientOrderId', newClientOrderId) 539 | 540 | request = self.__create_request_by_delete_with_signature( 541 | '/api/v3/order', builder) 542 | 543 | def parse(json_wrapper): 544 | result = OrderOCO.json_parse(json_wrapper) 545 | return result 546 | 547 | request.json_parser = parse 548 | return request 549 | 550 | def get_oco_order(self, orderListId, origClientOrderId): 551 | builder = UrlParamsBuilder() 552 | builder.put_url('orderListId', symbol) 553 | builder.put_url('origClientOrderId', orderId) 554 | 555 | request = self.__create_request_by_get_with_signature( 556 | '/api/v3/orderList', builder) 557 | 558 | def parse(json_wrapper): 559 | result = OrderOCO.json_parse(json_wrapper) 560 | return result 561 | 562 | request.json_parser = parse 563 | return request 564 | 565 | def get_all_oco_orders(self, fromId, startTime, endTime, limit): 566 | builder = UrlParamsBuilder() 567 | builder.put_url('fromId', fromId) 568 | builder.put_url('startTime', startTime) 569 | builder.put_url('endTime', endTime) 570 | builder.put_url('limit', limit) 571 | 572 | request = self.__create_request_by_get_with_signature( 573 | '/api/v3/allOrderList', builder) 574 | 575 | def parse(json_wrapper): 576 | result = list() 577 | data_list = json_wrapper.convert_2_array() 578 | for item in data_list.get_items(): 579 | element = OrderOCO.json_parse(item) 580 | result.append(element) 581 | return result 582 | 583 | request.json_parser = parse 584 | return request 585 | 586 | def get_open_oco_orders(self): 587 | builder = UrlParamsBuilder() 588 | 589 | request = self.__create_request_by_get_with_signature( 590 | '/api/v3/openOrderList', builder) 591 | 592 | def parse(json_wrapper): 593 | result = list() 594 | data_list = json_wrapper.convert_2_array() 595 | for item in data_list.get_items(): 596 | element = OrderOCO.json_parse(item) 597 | result.append(element) 598 | return result 599 | 600 | request.json_parser = parse 601 | return request 602 | 603 | def get_account_information(self): 604 | builder = UrlParamsBuilder() 605 | 606 | request = self.__create_request_by_get_with_signature( 607 | '/api/v3/account', builder) 608 | 609 | def parse(json_wrapper): 610 | result = AccountInformation.json_parse(json_wrapper) 611 | return result 612 | 613 | request.json_parser = parse 614 | return request 615 | 616 | def get_account_trades(self, symbol, startTime, endTime, fromId, limit): 617 | check_should_not_none(symbol, 'symbol') 618 | builder = UrlParamsBuilder() 619 | builder.put_url('symbol', symbol) 620 | builder.put_url('startTime', startTime) 621 | builder.put_url('endTime', endTime) 622 | builder.put_url('fromId', fromId) 623 | builder.put_url('limit', limit) 624 | 625 | request = self.__create_request_by_get_with_signature( 626 | '/api/v3/myTrades', builder) 627 | 628 | def parse(json_wrapper): 629 | result = list() 630 | data_list = json_wrapper.convert_2_array() 631 | for item in data_list.get_items(): 632 | element = MyTrade.json_parse(item) 633 | result.append(element) 634 | return result 635 | 636 | request.json_parser = parse 637 | return request 638 | 639 | def start_user_data_stream(self): 640 | builder = UrlParamsBuilder() 641 | 642 | request = self.__create_request_by_post_with_signature( 643 | '/api/v3/userDataStream', builder) 644 | 645 | def parse(json_wrapper): 646 | result = json_wrapper.get_string('listenKey') 647 | return result 648 | 649 | request.json_parser = parse 650 | return request 651 | 652 | def keep_user_data_stream(self, listenKey): 653 | check_should_not_none(listenKey, 'listenKey') 654 | builder = UrlParamsBuilder() 655 | builder.put_url('listenKey', listenKey) 656 | 657 | request = self.__create_request_by_put_with_signature( 658 | '/api/v3/userDataStream', builder) 659 | 660 | def parse(json_wrapper): 661 | result = 'OK' 662 | return result 663 | 664 | request.json_parser = parse 665 | return request 666 | 667 | def close_user_data_stream(self, listenKey): 668 | check_should_not_none(listenKey, 'listenKey') 669 | builder = UrlParamsBuilder() 670 | builder.put_url('listenKey', listenKey) 671 | 672 | request = self.__create_request_by_delete_with_signature( 673 | '/api/v3/userDataStream', builder) 674 | 675 | def parse(json_wrapper): 676 | result = 'OK' 677 | return result 678 | 679 | request.json_parser = parse 680 | return request 681 | -------------------------------------------------------------------------------- /binance-spot/impl/utils/__init__.py: -------------------------------------------------------------------------------- 1 | import json 2 | from common.scripts.binance_spot.impl.utils.jsonwrapper import JsonWrapper 3 | 4 | 5 | def parse_json_from_string(value): 6 | value = value.replace('False', 'false') 7 | value = value.replace('True', 'true') 8 | return JsonWrapper(json.loads(value)) 9 | -------------------------------------------------------------------------------- /binance-spot/impl/utils/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/utils/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/utils/__pycache__/apisignature.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/utils/__pycache__/apisignature.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/utils/__pycache__/channelparser.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/utils/__pycache__/channelparser.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/utils/__pycache__/channels.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/utils/__pycache__/channels.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/utils/__pycache__/inputchecker.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/utils/__pycache__/inputchecker.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/utils/__pycache__/jsonwrapper.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/utils/__pycache__/jsonwrapper.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/utils/__pycache__/timeservice.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/utils/__pycache__/timeservice.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/utils/__pycache__/urlparamsbuilder.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/impl/utils/__pycache__/urlparamsbuilder.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/impl/utils/apisignature.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import hashlib 3 | import hmac 4 | import datetime 5 | from urllib import parse 6 | import urllib.parse 7 | from common.scripts.binance_spot.exception.binanceapiexception import BinanceApiException 8 | 9 | 10 | def create_signature(secret_key, builder): 11 | if secret_key is None or secret_key == '': 12 | raise BinanceApiException( 13 | BinanceApiException.KEY_MISSING, 'Secret key are required') 14 | 15 | # keys = builder.param_map.keys() 16 | # query_string = '&'.join(['%s=%s' % (key, parse.quote(builder.param_map[key], safe='')) for key in keys]) 17 | query_string = builder.build_url() 18 | signature = hmac.new(secret_key.encode(), msg=query_string.encode( 19 | ), digestmod=hashlib.sha256).hexdigest() 20 | builder.put_url('signature', signature) 21 | 22 | 23 | def create_signature_with_query(secret_key, query): 24 | if secret_key is None or secret_key == '': 25 | raise BinanceApiException( 26 | BinanceApiException.KEY_MISSING, 'Secret key are required') 27 | 28 | signature = hmac.new(secret_key.encode(), msg=query.encode(), 29 | digestmod=hashlib.sha256).hexdigest() 30 | 31 | return signature 32 | 33 | 34 | def utc_now(): 35 | return datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S') 36 | -------------------------------------------------------------------------------- /binance-spot/impl/utils/channels.py: -------------------------------------------------------------------------------- 1 | import json 2 | from common.scripts.binance_spot.impl.utils.timeservice import get_current_timestamp 3 | 4 | 5 | def aggregate_trade_channel(symbol): 6 | channel = dict() 7 | channel['params'] = list() 8 | channel['params'].append(symbol + '@aggTrade') 9 | channel['id'] = get_current_timestamp() 10 | channel['method'] = 'SUBSCRIBE' 11 | return json.dumps(channel) 12 | 13 | 14 | def mark_price_channel(symbol): 15 | channel = dict() 16 | channel['params'] = list() 17 | channel['params'].append(symbol + '@markPrice') 18 | channel['id'] = get_current_timestamp() 19 | channel['method'] = 'SUBSCRIBE' 20 | return json.dumps(channel) 21 | 22 | 23 | def kline_channel(symbol, interval): 24 | channel = dict() 25 | channel['params'] = list() 26 | channel['params'].append(symbol + '@kline_' + interval) 27 | channel['id'] = get_current_timestamp() 28 | channel['method'] = 'SUBSCRIBE' 29 | return json.dumps(channel) 30 | 31 | 32 | def trade_channel(symbol): 33 | channel = dict() 34 | channel['params'] = list() 35 | channel['params'].append(symbol + '@trade') 36 | channel['id'] = get_current_timestamp() 37 | channel['method'] = 'SUBSCRIBE' 38 | return json.dumps(channel) 39 | 40 | 41 | def symbol_miniticker_channel(symbol): 42 | channel = dict() 43 | channel['params'] = list() 44 | channel['params'].append(symbol + '@miniTicker') 45 | channel['id'] = get_current_timestamp() 46 | channel['method'] = 'SUBSCRIBE' 47 | return json.dumps(channel) 48 | 49 | 50 | def all_miniticker_channel(): 51 | channel = dict() 52 | channel['params'] = list() 53 | channel['params'].append('!miniTicker@arr') 54 | channel['id'] = get_current_timestamp() 55 | channel['method'] = 'SUBSCRIBE' 56 | return json.dumps(channel) 57 | 58 | 59 | def symbol_ticker_channel(symbol): 60 | channel = dict() 61 | channel['params'] = list() 62 | channel['params'].append(symbol + '@ticker') 63 | channel['id'] = get_current_timestamp() 64 | channel['method'] = 'SUBSCRIBE' 65 | return json.dumps(channel) 66 | 67 | 68 | def all_ticker_channel(): 69 | channel = dict() 70 | channel['params'] = list() 71 | channel['params'].append('!ticker@arr') 72 | channel['id'] = get_current_timestamp() 73 | channel['method'] = 'SUBSCRIBE' 74 | return json.dumps(channel) 75 | 76 | 77 | def symbol_bookticker_channel(symbol): 78 | channel = dict() 79 | channel['params'] = list() 80 | channel['params'].append(symbol + '@bookTicker') 81 | channel['id'] = get_current_timestamp() 82 | channel['method'] = 'SUBSCRIBE' 83 | return json.dumps(channel) 84 | 85 | 86 | def all_bookticker_channel(): 87 | channel = dict() 88 | channel['params'] = list() 89 | channel['params'].append('!bookTicker') 90 | channel['id'] = get_current_timestamp() 91 | channel['method'] = 'SUBSCRIBE' 92 | return json.dumps(channel) 93 | 94 | 95 | def symbol_liquidation_channel(symbol): 96 | channel = dict() 97 | channel['params'] = list() 98 | channel['params'].append(symbol + '@forceOrder') 99 | channel['id'] = get_current_timestamp() 100 | channel['method'] = 'SUBSCRIBE' 101 | return json.dumps(channel) 102 | 103 | 104 | def all_liquidation_channel(symbol): 105 | channel = dict() 106 | channel['params'] = list() 107 | channel['params'].append('!forceOrder@arr') 108 | channel['id'] = get_current_timestamp() 109 | channel['method'] = 'SUBSCRIBE' 110 | return json.dumps(channel) 111 | 112 | 113 | def book_depth_channel(symbol, limit, update_time): 114 | channel = dict() 115 | channel['params'] = list() 116 | channel['params'].append(symbol + '@depth' + str(limit) + str(update_time)) 117 | channel['id'] = get_current_timestamp() 118 | channel['method'] = 'SUBSCRIBE' 119 | return json.dumps(channel) 120 | 121 | 122 | def diff_depth_channel(symbol, update_time): 123 | channel = dict() 124 | channel['params'] = list() 125 | channel['params'].append(symbol + '@depth' + update_time) 126 | channel['id'] = get_current_timestamp() 127 | channel['method'] = 'SUBSCRIBE' 128 | return json.dumps(channel) 129 | 130 | 131 | def user_data_channel(listenKey): 132 | channel = dict() 133 | channel['params'] = list() 134 | channel['params'].append(listenKey) 135 | channel['id'] = get_current_timestamp() 136 | channel['method'] = 'SUBSCRIBE' 137 | return json.dumps(channel) 138 | -------------------------------------------------------------------------------- /binance-spot/impl/utils/inputchecker.py: -------------------------------------------------------------------------------- 1 | import re 2 | import time 3 | from common.scripts.binance_spot.exception.binanceapiexception import BinanceApiException 4 | 5 | reg_ex = "[ _`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]|\n|\t" 6 | 7 | 8 | def check_symbol(symbol): 9 | if not isinstance(symbol, str): 10 | raise BinanceApiException( 11 | BinanceApiException.INPUT_ERROR, '[Input] symbol must be string') 12 | if re.match(reg_ex, symbol): 13 | raise BinanceApiException( 14 | BinanceApiException.INPUT_ERROR, '[Input] ' + symbol + ' is invalid symbol') 15 | 16 | 17 | def check_symbol_list(symbols): 18 | if not isinstance(symbols, list): 19 | raise BinanceApiException( 20 | BinanceApiException.INPUT_ERROR, '[Input] symbols in subscription is not a list') 21 | for symbol in symbols: 22 | check_symbol(symbol) 23 | 24 | 25 | def check_currency(currency): 26 | if not isinstance(currency, str): 27 | raise BinanceApiException( 28 | BinanceApiException.INPUT_ERROR, '[Input] currency must be string') 29 | if re.match(reg_ex, currency) is not None: 30 | raise BinanceApiException( 31 | BinanceApiException.INPUT_ERROR, '[Input] ' + currency + ' is invalid currency') 32 | 33 | 34 | def check_range(value, min_value, max_value, name): 35 | if value is None: 36 | return 37 | if min_value > value or value > max_value: 38 | raise BinanceApiException(BinanceApiException.INPUT_ERROR, 39 | '[Input] ' + name + ' is out of bound. ' + str(value) + ' is not in [' + str( 40 | min_value) + ',' + str(max_value) + ']') 41 | 42 | 43 | def check_should_not_none(value, name): 44 | if value is None: 45 | raise BinanceApiException( 46 | BinanceApiException.INPUT_ERROR, '[Input] ' + name + ' should not be null') 47 | 48 | 49 | def check_should_none(value, name): 50 | if value is not None: 51 | raise BinanceApiException( 52 | BinanceApiException.INPUT_ERROR, '[Input] ' + name + ' should be null') 53 | 54 | 55 | def check_list(list_value, min_value, max_value, name): 56 | if list_value is None: 57 | return 58 | if len(list_value) > max_value: 59 | raise BinanceApiException(BinanceApiException.INPUT_ERROR, 60 | '[Input] ' + name + ' is out of bound, the max size is ' + str(max_value)) 61 | if len(list_value) < min_value: 62 | raise BinanceApiException(BinanceApiException.INPUT_ERROR, 63 | '[Input] ' + name + ' should contain ' + str(min_value) + ' item(s) at least') 64 | 65 | 66 | def greater_or_equal(value, base, name): 67 | if value is not None and value < base: 68 | raise BinanceApiException(BinanceApiException.INPUT_ERROR, 69 | '[Input] ' + name + ' should be greater than ' + base) 70 | 71 | 72 | def format_date(value, name): 73 | if value is None: 74 | return None 75 | if not isinstance(value, str): 76 | raise BinanceApiException( 77 | BinanceApiException.INPUT_ERROR, '[Input] ' + name + ' must be string') 78 | try: 79 | new_time = time.strptime(value, '%Y-%m-%d') 80 | return time.strftime('%Y-%m-%d', new_time) 81 | except: 82 | raise BinanceApiException( 83 | BinanceApiException.INPUT_ERROR, '[Input] ' + name + ' is not invalid date format') 84 | -------------------------------------------------------------------------------- /binance-spot/impl/utils/jsonwrapper.py: -------------------------------------------------------------------------------- 1 | import json 2 | from common.scripts.binance_spot.exception.binanceapiexception import BinanceApiException 3 | 4 | 5 | class JsonWrapper: 6 | 7 | def __init__(self, json_object): 8 | self.json_object = json_object 9 | 10 | def __check_mandatory_field(self, name): 11 | if name not in self.json_object: 12 | raise BinanceApiException(BinanceApiException.RUNTIME_ERROR, 13 | '[Json] Get json item field: ' + name + ' does not exist') 14 | 15 | def contain_key(self, name): 16 | if name in self.json_object: 17 | return True 18 | else: 19 | return False 20 | 21 | def get_boolean(self, name): 22 | self.__check_mandatory_field(name) 23 | return bool(self.json_object[name]) 24 | 25 | def get_boolean_or_default(self, name, default: bool): 26 | if self.contain_key(name): 27 | return bool(self.json_object[name]) 28 | return default 29 | 30 | def get_string(self, name): 31 | self.__check_mandatory_field(name) 32 | return str(self.json_object[name]) 33 | 34 | def get_int(self, name): 35 | self.__check_mandatory_field(name) 36 | return int(self.json_object[name]) 37 | 38 | def get_string_or_default(self, name, default): 39 | if self.contain_key(name): 40 | return str(self.json_object[name]) 41 | else: 42 | return default 43 | 44 | def get_int_or_default(self, name, default): 45 | if self.contain_key(name): 46 | return int(self.json_object[name]) 47 | else: 48 | return default 49 | 50 | def get_float(self, name): 51 | self.__check_mandatory_field(name) 52 | return float(self.json_object[name]) 53 | 54 | def get_float_or_default(self, name, default): 55 | if self.contain_key(name): 56 | return float(self.json_object[name]) 57 | else: 58 | return default 59 | 60 | def get_object(self, name): 61 | self.__check_mandatory_field(name) 62 | return JsonWrapper(self.json_object[name]) 63 | 64 | def get_object_or_default(self, name, default_value): 65 | if name not in self.json_object: 66 | return default_value 67 | else: 68 | return JsonWrapper(self.json_object[name]) 69 | 70 | def get_array(self, name): 71 | self.__check_mandatory_field(name) 72 | return JsonWrapperArray(self.json_object[name]) 73 | 74 | def get_array_or_default(self, name): 75 | if self.contain_key(name): 76 | return JsonWrapperArray(self.json_object[name]) 77 | return JsonWrapperArray(json.loads('[]')) 78 | 79 | def convert_2_array(self): 80 | return JsonWrapperArray(self.json_object) 81 | 82 | def convert_2_dict(self): 83 | items = dict() 84 | for item in self.json_object: 85 | name = item 86 | items[name] = self.json_object[name] 87 | return items 88 | 89 | def convert_2_list(self): 90 | items = list() 91 | for item in self.json_object: 92 | items.append(item) 93 | return items 94 | 95 | 96 | class JsonWrapperArray: 97 | def __init__(self, json_object): 98 | self.json_object = json_object 99 | 100 | def get_items(self): 101 | items = list() 102 | for item in self.json_object: 103 | items.append(JsonWrapper(item)) 104 | return items 105 | 106 | def get_items_as_array(self): 107 | items = list() 108 | for item in self.json_object: 109 | items.append(JsonWrapperArray(item)) 110 | return items 111 | 112 | def get_float_at(self, index): 113 | return float(self.json_object[index]) 114 | 115 | def get_items_as_string(self): 116 | items = list() 117 | for item in self.json_object: 118 | items.append(str(item)) 119 | return items 120 | 121 | def get_array_at(self, index): 122 | return JsonWrapperArray(self.json_object[index]) 123 | 124 | def get_object_at(self, index): 125 | return JsonWrapper(self.json_object[index]) 126 | -------------------------------------------------------------------------------- /binance-spot/impl/utils/timeservice.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | 4 | def get_current_timestamp(): 5 | return int(round(time.time() * 1000)) 6 | 7 | 8 | def convert_cst_in_second_to_utc(time_in_second): 9 | if time_in_second > 946656000: 10 | return (time_in_second - 8 * 60 * 60) * 1000 11 | else: 12 | return 0 13 | 14 | 15 | def convert_cst_in_millisecond_to_utc(time_in_ms): 16 | if time_in_ms > 946656000000: 17 | return time_in_ms - 8 * 60 * 60 * 1000 18 | else: 19 | return 0 20 | -------------------------------------------------------------------------------- /binance-spot/impl/utils/urlparamsbuilder.py: -------------------------------------------------------------------------------- 1 | import json 2 | import urllib.parse 3 | 4 | 5 | class UrlParamsBuilder(object): 6 | 7 | def __init__(self): 8 | self.param_map = dict() 9 | self.post_map = dict() 10 | 11 | def put_url(self, name, value): 12 | if value is not None: 13 | if isinstance(value, list): 14 | self.param_map[name] = json.dumps(value) 15 | elif isinstance(value, float): 16 | self.param_map[name] = ('%.20f' % (value))[ 17 | slice(0, 16)].rstrip('0').rstrip('.') 18 | else: 19 | self.param_map[name] = str(value) 20 | 21 | def put_post(self, name, value): 22 | if value is not None: 23 | if isinstance(value, list): 24 | self.post_map[name] = value 25 | else: 26 | self.post_map[name] = str(value) 27 | 28 | def build_url(self): 29 | if len(self.param_map) == 0: 30 | return '' 31 | encoded_param = urllib.parse.urlencode(self.param_map) 32 | return encoded_param 33 | 34 | def build_url_to_json(self): 35 | return json.dumps(self.param_map) 36 | -------------------------------------------------------------------------------- /binance-spot/impl/websocketconnection.py: -------------------------------------------------------------------------------- 1 | import threading 2 | import websocket 3 | import gzip 4 | import ssl 5 | import logging 6 | from urllib import parse 7 | import urllib.parse 8 | 9 | from common.scripts.binance_spot.impl.utils.timeservice import get_current_timestamp 10 | from common.scripts.binance_spot.impl.utils.urlparamsbuilder import UrlParamsBuilder 11 | from common.scripts.binance_spot.impl.utils.apisignature import create_signature 12 | from common.scripts.binance_spot.exception.binanceapiexception import BinanceApiException 13 | from common.scripts.binance_spot.impl.utils import * 14 | from common.scripts.binance_spot.base.printobject import * 15 | from common.scripts.binance_spot.model.constant import * 16 | # Key: ws, Value: connection 17 | websocket_connection_handler = dict() 18 | 19 | 20 | def on_message(ws, message): 21 | websocket_connection = websocket_connection_handler[ws] 22 | websocket_connection.on_message(message) 23 | return 24 | 25 | 26 | def on_error(ws, error): 27 | websocket_connection = websocket_connection_handler[ws] 28 | websocket_connection.on_failure(error) 29 | 30 | 31 | def on_close(ws): 32 | websocket_connection = websocket_connection_handler[ws] 33 | websocket_connection.on_close() 34 | 35 | 36 | def on_open(ws): 37 | websocket_connection = websocket_connection_handler[ws] 38 | websocket_connection.on_open(ws) 39 | 40 | 41 | connection_id = 0 42 | 43 | 44 | class ConnectionState: 45 | IDLE = 0 46 | CONNECTED = 1 47 | CLOSED_ON_ERROR = 2 48 | 49 | 50 | def websocket_func(*args): 51 | connection_instance = args[0] 52 | connection_instance.ws = websocket.WebSocketApp(connection_instance.url, 53 | on_message=on_message, 54 | on_error=on_error, 55 | on_close=on_close) 56 | global websocket_connection_handler 57 | websocket_connection_handler[connection_instance.ws] = connection_instance 58 | connection_instance.logger.info( 59 | '[Sub][' + str(connection_instance.id) + '] Connecting...') 60 | connection_instance.delay_in_second = -1 61 | connection_instance.ws.on_open = on_open 62 | connection_instance.ws.run_forever(sslopt={'cert_reqs': ssl.CERT_NONE}) 63 | connection_instance.logger.info( 64 | '[Sub][' + str(connection_instance.id) + '] Connection event loop down') 65 | if connection_instance.state == ConnectionState.CONNECTED: 66 | connection_instance.state = ConnectionState.IDLE 67 | 68 | 69 | class WebsocketConnection: 70 | 71 | def __init__(self, api_key, secret_key, uri, watch_dog, request): 72 | self.__thread = None 73 | self.url = uri 74 | self.__api_key = api_key 75 | self.__secret_key = secret_key 76 | self.request = request 77 | self.__watch_dog = watch_dog 78 | self.delay_in_second = -1 79 | self.ws = None 80 | self.last_receive_time = 0 81 | self.logger = logging.getLogger('algo-trading') 82 | self.state = ConnectionState.IDLE 83 | global connection_id 84 | connection_id += 1 85 | self.id = connection_id 86 | 87 | def in_delay_connection(self): 88 | return self.delay_in_second != -1 89 | 90 | def re_connect_in_delay(self, delay_in_second): 91 | if self.ws is not None: 92 | self.ws.close() 93 | self.ws = None 94 | self.delay_in_second = delay_in_second 95 | self.logger.warning('[Sub][' + str(self.id) + '] Reconnecting after ' 96 | + str(self.delay_in_second) + ' seconds later') 97 | 98 | def re_connect(self): 99 | if self.delay_in_second != 0: 100 | self.delay_in_second -= 1 101 | self.logger.warning('In delay connection: ' + 102 | str(self.delay_in_second)) 103 | else: 104 | self.connect() 105 | 106 | def connect(self): 107 | if self.state == ConnectionState.CONNECTED: 108 | self.logger.info('[Sub][' + str(self.id) + '] Already connected') 109 | else: 110 | self.__thread = threading.Thread( 111 | target=websocket_func, args=[self]) 112 | self.__thread.start() 113 | 114 | def send(self, data): 115 | self.ws.send(data) 116 | 117 | def close(self): 118 | self.ws.close() 119 | del websocket_connection_handler[self.ws] 120 | self.__watch_dog.on_connection_closed(self) 121 | self.logger.error('[Sub][' + str(self.id) + '] Closing normally') 122 | 123 | def on_open(self, ws): 124 | self.logger.info('[Sub][' + str(self.id) + '] Connected to server') 125 | self.ws = ws 126 | self.last_receive_time = get_current_timestamp() 127 | self.state = ConnectionState.CONNECTED 128 | self.__watch_dog.on_connection_created(self) 129 | if self.request.subscription_handler is not None: 130 | self.request.subscription_handler(self) 131 | return 132 | 133 | def on_error(self, error_message): 134 | if self.request.error_handler is not None: 135 | print('error') 136 | exception = BinanceApiException( 137 | BinanceApiException.SUBSCRIPTION_ERROR, error_message) 138 | self.request.error_handler(exception) 139 | self.logger.error('[Sub][' + str(self.id) + '] ' + str(error_message)) 140 | 141 | def on_failure(self, error): 142 | print('on_failure') 143 | self.on_error('Unexpected error: ' + str(error)) 144 | self.close_on_error() 145 | 146 | def on_message(self, message): 147 | self.last_receive_time = get_current_timestamp() 148 | json_wrapper = parse_json_from_string(message) 149 | 150 | if json_wrapper.contain_key('status') and json_wrapper.get_string('status') != 'ok': 151 | error_code = json_wrapper.get_string_or_default( 152 | 'err-code', 'Unknown error') 153 | error_msg = json_wrapper.get_string_or_default( 154 | 'err-msg', 'Unknown error') 155 | self.on_error(error_code + ': ' + error_msg) 156 | elif json_wrapper.contain_key('err-code') and json_wrapper.get_int('err-code') != 0: 157 | error_code = json_wrapper.get_string_or_default( 158 | 'err-code', 'Unknown error') 159 | error_msg = json_wrapper.get_string_or_default( 160 | 'err-msg', 'Unknown error') 161 | self.on_error(error_code + ': ' + error_msg) 162 | elif json_wrapper.contain_key('result') and json_wrapper.contain_key('id'): 163 | self.__on_receive_response(json_wrapper) 164 | else: 165 | self.__on_receive_payload(json_wrapper) 166 | 167 | def __on_receive_response(self, json_wrapper): 168 | res = None 169 | try: 170 | res = json_wrapper.get_int('id') 171 | except Exception as e: 172 | self.on_error('Failed to parse servers response: ' + str(e)) 173 | 174 | try: 175 | if self.request.update_callback is not None: 176 | self.request.update_callback( 177 | SubscribeMessageType.RESPONSE, res) 178 | except Exception as e: 179 | self.on_error('Process error: ' + str(e) 180 | + ' You should capture the exception in your error handler') 181 | 182 | def __on_receive_payload(self, json_wrapper): 183 | res = None 184 | try: 185 | if self.request.json_parser is not None: 186 | res = self.request.json_parser(json_wrapper) 187 | except Exception as e: 188 | self.on_error('Failed to parse servers response: ' + str(e)) 189 | 190 | try: 191 | if self.request.update_callback is not None: 192 | self.request.update_callback(SubscribeMessageType.PAYLOAD, res) 193 | except Exception as e: 194 | self.on_error('Process error: ' + str(e) 195 | + ' You should capture the exception in your error handler') 196 | 197 | if self.request.auto_close: 198 | self.close() 199 | 200 | def __process_ping_on_trading_line(self, ping_ts): 201 | self.send('{\'op\':\'pong\',\'ts\':' + str(ping_ts) + '}') 202 | return 203 | 204 | def __process_ping_on_market_line(self, ping_ts): 205 | self.send('{\'pong\':' + str(ping_ts) + '}') 206 | return 207 | 208 | def close_on_error(self): 209 | if self.ws is not None: 210 | self.ws.close() 211 | self.state = ConnectionState.CLOSED_ON_ERROR 212 | self.logger.error( 213 | '[Sub][' + str(self.id) + '] Connection is closing due to error') 214 | -------------------------------------------------------------------------------- /binance-spot/impl/websocketrequest.py: -------------------------------------------------------------------------------- 1 | class WebsocketRequest(object): 2 | 3 | def __init__(self): 4 | self.subscription_handler = None 5 | # close connection after receive data, for subscribe set False, for request set True 6 | self.auto_close = False 7 | self.is_trading = False 8 | self.error_handler = None 9 | self.json_parser = None 10 | self.update_callback = None 11 | -------------------------------------------------------------------------------- /binance-spot/impl/websocketrequestimpl.py: -------------------------------------------------------------------------------- 1 | import time 2 | from common.scripts.binance_spot.impl.websocketrequest import WebsocketRequest 3 | from common.scripts.binance_spot.impl.utils.channels import * 4 | from common.scripts.binance_spot.impl.utils.timeservice import * 5 | from common.scripts.binance_spot.impl.utils.inputchecker import * 6 | from common.scripts.binance_spot.model import * 7 | # For develop 8 | from common.scripts.binance_spot.base.printobject import * 9 | 10 | 11 | class WebsocketRequestImpl(object): 12 | 13 | def __init__(self, api_key): 14 | self.__api_key = api_key 15 | 16 | def subscribe_aggregate_trade_event(self, symbol, callback, error_handler=None): 17 | check_should_not_none(symbol, 'symbol') 18 | check_should_not_none(callback, 'callback') 19 | 20 | def subscription_handler(connection): 21 | connection.send(aggregate_trade_channel(symbol)) 22 | time.sleep(0.01) 23 | 24 | def json_parse(json_wrapper): 25 | result = AggregateTradeEvent.json_parse(json_wrapper) 26 | return result 27 | 28 | request = WebsocketRequest() 29 | request.subscription_handler = subscription_handler 30 | request.json_parser = json_parse 31 | request.update_callback = callback 32 | request.error_handler = error_handler 33 | 34 | return request 35 | 36 | def subscribe_trade_event(self, symbol, callback, error_handler=None): 37 | check_should_not_none(symbol, 'symbol') 38 | check_should_not_none(callback, 'callback') 39 | 40 | def subscription_handler(connection): 41 | connection.send(rade_channel(symbol)) 42 | time.sleep(0.01) 43 | 44 | def json_parse(json_wrapper): 45 | result = TradeEvent.json_parse(json_wrapper) 46 | return result 47 | 48 | request = WebsocketRequest() 49 | request.subscription_handler = subscription_handler 50 | request.json_parser = json_parse 51 | request.update_callback = callback 52 | request.error_handler = error_handler 53 | 54 | return request 55 | 56 | def subscribe_candlestick_event(self, symbol, interval, callback, error_handler=None): 57 | check_should_not_none(symbol, 'symbol') 58 | check_should_not_none(interval, 'interval') 59 | check_should_not_none(callback, 'callback') 60 | 61 | def subscription_handler(connection): 62 | connection.send(kline_channel(symbol, interval)) 63 | time.sleep(0.01) 64 | 65 | def json_parse(json_wrapper): 66 | result = CandlestickEvent.json_parse(json_wrapper) 67 | return result 68 | 69 | request = WebsocketRequest() 70 | request.subscription_handler = subscription_handler 71 | request.json_parser = json_parse 72 | request.update_callback = callback 73 | request.error_handler = error_handler 74 | 75 | return request 76 | 77 | def subscribe_symbol_miniticker_event(self, symbol, callback, error_handler=None): 78 | check_should_not_none(symbol, 'symbol') 79 | check_should_not_none(callback, 'callback') 80 | 81 | def subscription_handler(connection): 82 | connection.send(symbol_miniticker_channel(symbol)) 83 | time.sleep(0.01) 84 | 85 | def json_parse(json_wrapper): 86 | result = SymbolMiniTickerEvent.json_parse(json_wrapper) 87 | return result 88 | 89 | request = WebsocketRequest() 90 | request.subscription_handler = subscription_handler 91 | request.json_parser = json_parse 92 | request.update_callback = callback 93 | request.error_handler = error_handler 94 | 95 | return request 96 | 97 | def subscribe_all_miniticker_event(self, callback, error_handler=None): 98 | check_should_not_none(callback, 'callback') 99 | 100 | def subscription_handler(connection): 101 | connection.send(all_miniticker_channel()) 102 | time.sleep(0.01) 103 | 104 | def json_parse(json_wrapper): 105 | result = list() 106 | data_list = json_wrapper.convert_2_array() 107 | for item in data_list.get_items(): 108 | element = SymbolMiniTickerEvent.json_parse(item) 109 | result.append(element) 110 | return result 111 | 112 | request = WebsocketRequest() 113 | request.subscription_handler = subscription_handler 114 | request.json_parser = json_parse 115 | request.update_callback = callback 116 | request.error_handler = error_handler 117 | 118 | return request 119 | 120 | def subscribe_symbol_ticker_event(self, symbol, callback, error_handler=None): 121 | check_should_not_none(symbol, 'symbol') 122 | check_should_not_none(callback, 'callback') 123 | 124 | def subscription_handler(connection): 125 | connection.send(symbol_ticker_channel(symbol)) 126 | time.sleep(0.02) 127 | 128 | def json_parse(json_wrapper): 129 | result = SymbolTickerEvent.json_parse(json_wrapper) 130 | return result 131 | 132 | request = WebsocketRequest() 133 | request.subscription_handler = subscription_handler 134 | request.json_parser = json_parse 135 | request.update_callback = callback 136 | request.error_handler = error_handler 137 | 138 | return request 139 | 140 | def subscribe_all_ticker_event(self, callback, error_handler=None): 141 | check_should_not_none(callback, 'callback') 142 | 143 | def subscription_handler(connection): 144 | connection.send(all_ticker_channel()) 145 | time.sleep(0.01) 146 | 147 | def json_parse(json_wrapper): 148 | result = list() 149 | data_list = json_wrapper.convert_2_array() 150 | for item in data_list.get_items(): 151 | ticker_event_obj = SymbolTickerEvent.json_parse(item) 152 | result.append(ticker_event_obj) 153 | return result 154 | 155 | request = WebsocketRequest() 156 | request.subscription_handler = subscription_handler 157 | request.json_parser = json_parse 158 | request.update_callback = callback 159 | request.error_handler = error_handler 160 | 161 | return request 162 | 163 | def subscribe_symbol_bookticker_event(self, symbol, callback, error_handler=None): 164 | check_should_not_none(symbol, 'symbol') 165 | check_should_not_none(callback, 'callback') 166 | 167 | def subscription_handler(connection): 168 | connection.send(symbol_bookticker_channel(symbol)) 169 | time.sleep(0.01) 170 | 171 | def json_parse(json_wrapper): 172 | result = SymbolBookTickerEvent.json_parse(json_wrapper) 173 | return result 174 | 175 | request = WebsocketRequest() 176 | request.subscription_handler = subscription_handler 177 | request.json_parser = json_parse 178 | request.update_callback = callback 179 | request.error_handler = error_handler 180 | 181 | return request 182 | 183 | def subscribe_all_bookticker_event(self, callback, error_handler=None): 184 | check_should_not_none(callback, 'callback') 185 | 186 | def subscription_handler(connection): 187 | connection.send(all_bookticker_channel()) 188 | time.sleep(0.01) 189 | 190 | def json_parse(json_wrapper): 191 | result = SymbolBookTickerEvent.json_parse(json_wrapper) 192 | return result 193 | 194 | request = WebsocketRequest() 195 | request.subscription_handler = subscription_handler 196 | request.json_parser = json_parse 197 | request.update_callback = callback 198 | request.error_handler = error_handler 199 | 200 | return request 201 | 202 | def subscribe_book_depth_event(self, symbol, limit, update_time, callback, error_handler=None): 203 | check_should_not_none(symbol, 'symbol') 204 | check_should_not_none(limit, 'limit') 205 | check_should_not_none(callback, 'callback') 206 | # print(update_time) 207 | 208 | def subscription_handler(connection): 209 | connection.send(book_depth_channel(symbol, limit, update_time)) 210 | time.sleep(0.01) 211 | 212 | def json_parse(json_wrapper): 213 | result = OrderBookEvent.json_parse(json_wrapper) 214 | return result 215 | 216 | request = WebsocketRequest() 217 | request.subscription_handler = subscription_handler 218 | request.json_parser = json_parse 219 | request.update_callback = callback 220 | request.error_handler = error_handler 221 | 222 | return request 223 | 224 | def subscribe_diff_depth_event(self, symbol, update_time, callback, error_handler=None): 225 | check_should_not_none(symbol, 'symbol') 226 | check_should_not_none(callback, 'callback') 227 | 228 | def subscription_handler(connection): 229 | connection.send(diff_depth_channel(symbol, update_time)) 230 | time.sleep(0.01) 231 | 232 | def json_parse(json_wrapper): 233 | result = DiffDepthEvent.json_parse(json_wrapper) 234 | return result 235 | 236 | request = WebsocketRequest() 237 | request.subscription_handler = subscription_handler 238 | request.json_parser = json_parse 239 | request.update_callback = callback 240 | request.error_handler = error_handler 241 | 242 | return request 243 | 244 | def subscribe_user_data_event(self, listenKey, callback, error_handler=None): 245 | check_should_not_none(listenKey, 'listenKey') 246 | check_should_not_none(callback, 'callback') 247 | 248 | def subscription_handler(connection): 249 | connection.send(user_data_channel(listenKey)) 250 | time.sleep(0.01) 251 | 252 | def json_parse(json_wrapper): 253 | print('event type: ', json_wrapper.get_string('e')) 254 | print(json_wrapper) 255 | if(json_wrapper.get_string('e') == 'ACCOUNT_UPDATE'): 256 | result = AccountUpdate.json_parse(json_wrapper) 257 | elif(json_wrapper.get_string('e') == 'ORDER_TRADE_UPDATE'): 258 | result = OrderUpdate.json_parse(json_wrapper) 259 | elif(json_wrapper.get_string('e') == 'listenKeyExpired'): 260 | result = ListenKeyExpired.json_parse(json_wrapper) 261 | return result 262 | 263 | request = WebsocketRequest() 264 | request.subscription_handler = subscription_handler 265 | request.json_parser = json_parse 266 | request.update_callback = callback 267 | request.error_handler = error_handler 268 | 269 | return request 270 | -------------------------------------------------------------------------------- /binance-spot/impl/websocketwatchdog.py: -------------------------------------------------------------------------------- 1 | import threading 2 | import logging 3 | from apscheduler.schedulers.blocking import BlockingScheduler 4 | from common.scripts.binance_spot.impl.websocketconnection import ConnectionState 5 | from common.scripts.binance_spot.impl.utils.timeservice import get_current_timestamp 6 | 7 | 8 | def watch_dog_job(*args): 9 | watch_dog_instance = args[0] 10 | for connection in watch_dog_instance.connection_list: 11 | if connection.state == ConnectionState.CONNECTED: 12 | if watch_dog_instance.is_auto_connect: 13 | ts = get_current_timestamp() - connection.last_receive_time 14 | if ts > watch_dog_instance.receive_limit_ms: 15 | watch_dog_instance.logger.warning( 16 | '[Sub][' + str(connection.id) + '] No response from server') 17 | connection.re_connect_in_delay( 18 | watch_dog_instance.connection_delay_failure) 19 | elif connection.in_delay_connection(): 20 | watch_dog_instance.logger.warning('[Sub] call re_connect') 21 | connection.re_connect() 22 | pass 23 | elif connection.state == ConnectionState.CLOSED_ON_ERROR: 24 | if watch_dog_instance.is_auto_connect: 25 | connection.re_connect_in_delay( 26 | watch_dog_instance.connection_delay_failure) 27 | pass 28 | 29 | 30 | class WebSocketWatchDog(threading.Thread): 31 | mutex = threading.Lock() 32 | connection_list = list() 33 | 34 | def __init__(self, is_auto_connect=True, receive_limit_ms=60000, connection_delay_failure=15): 35 | threading.Thread.__init__(self) 36 | self.is_auto_connect = is_auto_connect 37 | self.receive_limit_ms = receive_limit_ms 38 | self.connection_delay_failure = connection_delay_failure 39 | self.logger = logging.getLogger('algo-trading') 40 | self.scheduler = BlockingScheduler() 41 | self.scheduler.add_job(watch_dog_job, 'interval', 42 | max_instances=10, seconds=1, args=[self]) 43 | self.start() 44 | 45 | def run(self): 46 | self.scheduler.start() 47 | 48 | def on_connection_created(self, connection): 49 | self.mutex.acquire() 50 | self.connection_list.append(connection) 51 | self.mutex.release() 52 | 53 | def on_connection_closed(self, connection): 54 | self.mutex.acquire() 55 | self.connection_list.remove(connection) 56 | self.mutex.release() 57 | -------------------------------------------------------------------------------- /binance-spot/model.json/order.json: -------------------------------------------------------------------------------- 1 | { 2 | "py/object": "common.scripts.binance_spot.model.order.Order", 3 | "symbol": "SXPUSDT", 4 | "origClientOrderId": "", 5 | "orderId": 17500957, 6 | "orderListId": -1, 7 | "contingencyType": "", 8 | "listStatusType": "", 9 | "listOrderStatus": "", 10 | "listClientOrderId": "", 11 | "transactionTime": 0, 12 | "clientOrderId": "9SvLONxzYd8Q19v6WMPtjI", 13 | "transactTime": 1597757086698, 14 | "price": 0.0, 15 | "origQty": 3.006, 16 | "executedQty": 3.006, 17 | "cummulativeQuoteQty": 9.997956, 18 | "status": "FILLED", 19 | "timeInForce": "GTC", 20 | "type": "MARKET", 21 | "side": "BUY", 22 | "stopPrice": 0.0, 23 | "icebergQty": 0.0, 24 | "time": 0, 25 | "updateTime": 0, 26 | "isWorking": false, 27 | "origQuoteOrderQty": 0.0, 28 | "fills": [ 29 | { 30 | "py/object": "common.scripts.binance_spot.model.exchangeinformation.Symbol", 31 | "symbol": "", 32 | "status": "", 33 | "baseAsset": "", 34 | "baseAssetPrecision": 0, 35 | "quoteAsset": "", 36 | "quotePrecision": 0, 37 | "quoteAssetPrecision": 0, 38 | "orderTypes": [], 39 | "icebergAllowed": false, 40 | "ocoAllowed": false, 41 | "isSpotTradingAllowed": false, 42 | "isMarginTradingAllowed": false, 43 | "filters": [], 44 | "permissions": [], 45 | "price": 3.326, 46 | "qty": 3.006, 47 | "commission": 0.00032332, 48 | "commissionAsset": "BNB" 49 | } 50 | ], 51 | "orders": [], 52 | "orderReports": [] 53 | } -------------------------------------------------------------------------------- /binance-spot/model.json/orderoco.json: -------------------------------------------------------------------------------- 1 | { 2 | "py/object": "common.scripts.binance_spot.model.order.Order", 3 | "symbol": "BNBUSDT", 4 | "origClientOrderId": "", 5 | "orderId": 0, 6 | "orderListId": 7272672, 7 | "contingencyType": "OCO", 8 | "listStatusType": "EXEC_STARTED", 9 | "listOrderStatus": "EXECUTING", 10 | "listClientOrderId": "LqwlGupeWacZfzsanOBWar", 11 | "transactionTime": 1597762604626, 12 | "clientOrderId": "", 13 | "transactTime": 0, 14 | "price": 0.0, 15 | "origQty": 0.0, 16 | "executedQty": 0.0, 17 | "cummulativeQuoteQty": 0.0, 18 | "status": "", 19 | "timeInForce": "", 20 | "type": "", 21 | "side": "", 22 | "stopPrice": 0.0, 23 | "icebergQty": 0.0, 24 | "time": 0, 25 | "updateTime": 0, 26 | "isWorking": false, 27 | "origQuoteOrderQty": 0.0, 28 | "fills": [], 29 | "orders": [ 30 | { 31 | "py/object": "common.scripts.binance_spot.model.orderOCO.Orders", 32 | "symbol": "BNBUSDT", 33 | "orderId": 706207176, 34 | "clientOrderId": "3hgJi5FIYAtotmx4qECLcc", 35 | "orderListId": 7272672, 36 | "transactionTime": 0, 37 | "price": 21.0, 38 | "origQty": 1.0, 39 | "executedQty": 0.0, 40 | "cummulativeQuoteQty": 0.0, 41 | "status": "NEW", 42 | "timeInForce": "GTC", 43 | "type": "STOP_LOSS_LIMIT", 44 | "side": "SELL", 45 | "stopPrice": "21.05000000", 46 | "icebergQty": 0.0 47 | }, 48 | { 49 | "py/object": "common.scripts.binance_spot.model.orderOCO.Orders", 50 | "symbol": "BNBUSDT", 51 | "orderId": 706207177, 52 | "clientOrderId": "oVemahbkFjMbe2CKeV1wES", 53 | "orderListId": 7272672, 54 | "transactionTime": 0, 55 | "price": 23.0, 56 | "origQty": 1.0, 57 | "executedQty": 0.0, 58 | "cummulativeQuoteQty": 0.0, 59 | "status": "NEW", 60 | "timeInForce": "GTC", 61 | "type": "LIMIT_MAKER", 62 | "side": "SELL", 63 | "stopPrice": "", 64 | "icebergQty": 0.0 65 | } 66 | ], 67 | "orderReports": [] 68 | } -------------------------------------------------------------------------------- /binance-spot/model/__init__.py: -------------------------------------------------------------------------------- 1 | from common.scripts.binance_spot.model.constant import * 2 | from common.scripts.binance_spot.model.exchangeinformation import ExchangeInformation 3 | from common.scripts.binance_spot.model.orderbook import OrderBook 4 | from common.scripts.binance_spot.model.trade import Trade 5 | from common.scripts.binance_spot.model.aggregatetrade import AggregateTrade 6 | from common.scripts.binance_spot.model.candlestick import Candlestick 7 | from common.scripts.binance_spot.model.tickerpricechangestatistics import TickerPriceChangeStatistics 8 | from common.scripts.binance_spot.model.symbolprice import SymbolPrice 9 | from common.scripts.binance_spot.model.symbolorderbook import SymbolOrderBook 10 | from common.scripts.binance_spot.model.aggregatetradeevent import AggregateTradeEvent 11 | from common.scripts.binance_spot.model.candlestickevent import CandlestickEvent 12 | from common.scripts.binance_spot.model.symbolminitickerevent import SymbolMiniTickerEvent 13 | from common.scripts.binance_spot.model.symboltickerevent import SymbolTickerEvent 14 | from common.scripts.binance_spot.model.symbolbooktickerevent import SymbolBookTickerEvent 15 | from common.scripts.binance_spot.model.orderbookevent import OrderBookEvent 16 | from common.scripts.binance_spot.model.diffdepthevent import DiffDepthEvent 17 | from common.scripts.binance_spot.model.order import Order 18 | from common.scripts.binance_spot.model.orderOCO import OrderOCO 19 | from common.scripts.binance_spot.model.accountinformation import AccountInformation 20 | from common.scripts.binance_spot.model.mytrade import MyTrade 21 | from common.scripts.binance_spot.model.accountupdate import AccountUpdate 22 | from common.scripts.binance_spot.model.orderupdate import OrderUpdate 23 | from common.scripts.binance_spot.model.listenkeyexpired import ListenKeyExpired 24 | from common.scripts.binance_spot.model.averagePrice import AveragePrice 25 | -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/accountinformation.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/accountinformation.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/accountupdate.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/accountupdate.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/aggregatetrade.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/aggregatetrade.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/aggregatetradeevent.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/aggregatetradeevent.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/averagePrice.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/averagePrice.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/candlestick.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/candlestick.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/candlestickevent.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/candlestickevent.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/codeandmsg.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/codeandmsg.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/constant.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/constant.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/diffdepthevent.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/diffdepthevent.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/exchangeinformation.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/exchangeinformation.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/fundingrate.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/fundingrate.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/liquidationorder.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/liquidationorder.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/liquidationorderevent.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/liquidationorderevent.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/listenkeyexpired.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/listenkeyexpired.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/markprice.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/markprice.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/markpriceevent.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/markpriceevent.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/message.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/message.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/mytrade.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/mytrade.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/openinterest.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/openinterest.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/order.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/order.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/orderOCO.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/orderOCO.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/orderbook.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/orderbook.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/orderbookevent.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/orderbookevent.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/orderupdate.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/orderupdate.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/positionmode.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/positionmode.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/symbolbooktickerevent.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/symbolbooktickerevent.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/symbolminitickerevent.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/symbolminitickerevent.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/symbolorderbook.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/symbolorderbook.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/symbolprice.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/symbolprice.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/symboltickerevent.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/symboltickerevent.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/tickerpricechangestatistics.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/tickerpricechangestatistics.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/__pycache__/trade.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdeenM/binance-api/f48ab28dd837dd66bb8373e5e4b1bf24379e46ad/binance-spot/model/__pycache__/trade.cpython-38.pyc -------------------------------------------------------------------------------- /binance-spot/model/accountinformation.py: -------------------------------------------------------------------------------- 1 | class Balances: 2 | 3 | def __init__(self): 4 | self.asset = '' 5 | self.free = 0.0 6 | self.locked = 0.0 7 | 8 | @staticmethod 9 | def json_parse(json_data): 10 | result = Balances() 11 | result.asset = json_data.get_string('asset') 12 | result.free = json_data.get_float('free') 13 | result.locked = json_data.get_float('locked') 14 | return result 15 | 16 | 17 | class AccountInformation: 18 | 19 | def __init__(self): 20 | self.makerCommission = 0 21 | self.takerCommission = 0 22 | self.buyerCommission = 0 23 | self.sellerCommission = 0 24 | self.canTrade = False 25 | self.canWithdraw = False 26 | self.canDeposit = False 27 | self.updateTime = 0 28 | self.accountType = '' 29 | self.balances = list() 30 | self.permissions = list() 31 | 32 | @staticmethod 33 | def json_parse(json_data): 34 | result = AccountInformation() 35 | result.makerCommission = json_data.get_int('makerCommission') 36 | result.takerCommission = json_data.get_int('takerCommission') 37 | result.buyerCommission = json_data.get_int('buyerCommission') 38 | result.sellerCommission = json_data.get_int('sellerCommission') 39 | result.canTrade = json_data.get_boolean('canTrade') 40 | result.canWithdraw = json_data.get_boolean('canWithdraw') 41 | result.canDeposit = json_data.get_boolean('canDeposit') 42 | result.updateTime = json_data.get_int('updateTime') 43 | result.accountType = json_data.get_string('accountType') 44 | 45 | element_list = list() 46 | data_list = json_data.get_array('balances') 47 | for item in data_list.get_items(): 48 | element = Balances.json_parse(item) 49 | element_list.append(element) 50 | result.balances = element_list 51 | 52 | result.permissions = json_data.get_object( 53 | 'permissions').convert_2_list() 54 | 55 | return result 56 | -------------------------------------------------------------------------------- /binance-spot/model/accountupdate.py: -------------------------------------------------------------------------------- 1 | class Balance: 2 | 3 | def __init__(self): 4 | self.asset = '' 5 | self.walletBalance = 0.0 6 | self.crossWallet = 0.0 7 | 8 | @staticmethod 9 | def json_parse(json_data): 10 | result = Balance() 11 | result.asset = json_data.get_string('a') 12 | result.walletBalance = json_data.get_float('wb') 13 | result.crossWallet = json_data.get_float('cw') 14 | return result 15 | 16 | 17 | class Position: 18 | 19 | def __init__(self): 20 | self.symbol = '' 21 | self.amount = 0.0 22 | self.entryPrice = 0.0 23 | self.preFee = 0.0 24 | self.unrealizedPnl = 0.0 25 | self.marginType = '' 26 | self.isolatedWallet = 0.0 27 | self.positionSide = '' 28 | 29 | @staticmethod 30 | def json_parse(json_data): 31 | result = Position() 32 | result.symbol = json_data.get_string('s') 33 | result.amount = json_data.get_float('pa') 34 | result.entryPrice = json_data.get_float('ep') 35 | result.preFee = json_data.get_float('cr') 36 | result.unrealizedPnl = json_data.get_float('up') 37 | result.marginType = json_data.get_string('mt') 38 | result.isolatedWallet = json_data.get_float('iw') 39 | result.positionSide = json_data.get_string('ps') 40 | return result 41 | 42 | 43 | class AccountUpdate: 44 | def __init__(self): 45 | self.eventType = '' 46 | self.eventTime = 0 47 | self.transactionTime = 0 48 | self.balances = list() 49 | self.positions = list() 50 | 51 | @staticmethod 52 | def json_parse(json_data): 53 | result = AccountUpdate() 54 | result.eventType = json_data.get_string('e') 55 | result.eventTime = json_data.get_int('E') 56 | result.transactionTime = json_data.get_int('T') 57 | 58 | data_group = json_data.get_object('a') 59 | 60 | element_list = list() 61 | data_list = data_group.get_array('B') 62 | for item in data_list.get_items(): 63 | element = Balance.json_parse(item) 64 | element_list.append(element) 65 | result.balances = element_list 66 | 67 | if data_group.contain_key('P'): 68 | element_list = list() 69 | data_list = data_group.get_array('P') 70 | for item in data_list.get_items(): 71 | element = Position.json_parse(item) 72 | element_list.append(element) 73 | result.positions = element_list 74 | return result 75 | -------------------------------------------------------------------------------- /binance-spot/model/aggregatetrade.py: -------------------------------------------------------------------------------- 1 | class AggregateTrade: 2 | 3 | def __init__(self): 4 | self.id = 0 5 | self.price = 0.0 6 | self.qty = 0.0 7 | self.firstId = 0 8 | self.lastId = 0 9 | self.time = 0 10 | self.isBuyerMaker = False 11 | self.isBestMatch = False 12 | 13 | @staticmethod 14 | def json_parse(json_data): 15 | trade = AggregateTrade() 16 | trade.id = json_data.get_int('a') 17 | trade.price = json_data.get_float('p') 18 | trade.qty = json_data.get_float('q') 19 | trade.firstId = json_data.get_int('f') 20 | trade.lastId = json_data.get_int('l') 21 | trade.time = json_data.get_int('T') 22 | trade.isBuyerMaker = json_data.get_boolean('m') 23 | trade.isBestMatch = json_data.get_boolean('M') 24 | 25 | return trade 26 | -------------------------------------------------------------------------------- /binance-spot/model/aggregatetradeevent.py: -------------------------------------------------------------------------------- 1 | class AggregateTradeEvent: 2 | 3 | def __init__(self): 4 | self.eventType = '' 5 | self.eventTime = 0 6 | self.symbol = '' 7 | self.id = 0 8 | self.price = 0.0 9 | self.qty = 0 10 | self.firstId = 0 11 | self.lastId = 0 12 | self.time = 0 13 | self.isBuyerMaker = False 14 | self.ignore = False 15 | 16 | @staticmethod 17 | def json_parse(json_wrapper): 18 | result = AggregateTradeEvent() 19 | result.eventType = json_wrapper.get_string('e') 20 | result.eventTime = json_wrapper.get_int('E') 21 | result.symbol = json_wrapper.get_string('s') 22 | result.id = json_wrapper.get_int('a') 23 | result.price = json_wrapper.get_float('p') 24 | result.qty = json_wrapper.get_float('q') 25 | result.firstId = json_wrapper.get_int('f') 26 | result.lastId = json_wrapper.get_int('l') 27 | result.time = json_wrapper.get_int('T') 28 | result.isBuyerMaker = json_wrapper.get_boolean('m') 29 | result.ignore = json_wrapper.get_boolean('M') 30 | return result 31 | -------------------------------------------------------------------------------- /binance-spot/model/averagePrice.py: -------------------------------------------------------------------------------- 1 | class AveragePrice: 2 | 3 | def __init__(self): 4 | self.mins = 0 5 | self.price = 0.0 6 | 7 | @staticmethod 8 | def json_parse(json_wrapper): 9 | result = AveragePrice() 10 | result.mins = json_wrapper.get_int('mins') 11 | result.price = json_wrapper.get_float('price') 12 | return result 13 | -------------------------------------------------------------------------------- /binance-spot/model/candlestick.py: -------------------------------------------------------------------------------- 1 | class Candlestick: 2 | 3 | def __init__(self): 4 | self.openTime = 0 5 | self.open = 0.0 6 | self.high = 0.0 7 | self.low = 0.0 8 | self.close = 0.0 9 | self.volume = 0.0 10 | self.closeTime = 0 11 | self.quoteAssetVolume = 0.0 12 | self.numTrades = 0 13 | self.takerBuyBaseAssetVolume = 0.0 14 | self.takerBuyQuoteAssetVolume = 0.0 15 | self.ignore = 0.0 16 | 17 | def to_list(self): 18 | return [ 19 | self.openTime, 20 | self.open, 21 | self.high, 22 | self.low, 23 | self.close, 24 | self.volume, 25 | self.closeTime, 26 | self.quoteAssetVolume, 27 | self.numTrades, 28 | self.takerBuyBaseAssetVolume, 29 | self.takerBuyQuoteAssetVolume, 30 | self.ignore, 31 | ] 32 | 33 | @staticmethod 34 | def json_parse_dict(val): 35 | result = Candlestick() 36 | result.openTime = val['t'] 37 | result.open = val['o'] 38 | result.high = val['h'] 39 | result.low = val['l'] 40 | result.close = val['c'] 41 | result.volume = val['v'] 42 | result.closeTime = val['T'] 43 | result.quoteAssetVolume = val['q'] 44 | result.numTrades = val['n'] 45 | result.takerBuyBaseAssetVolume = val['V'] 46 | result.takerBuyQuoteAssetVolume = val['Q'] 47 | result.ignore = val['B'] 48 | 49 | return result 50 | 51 | @staticmethod 52 | def json_parse(json_data): 53 | result = Candlestick() 54 | val = json_data.convert_2_list() 55 | result.openTime = val[0] 56 | result.open = val[1] 57 | result.high = val[2] 58 | result.low = val[3] 59 | result.close = val[4] 60 | result.volume = val[5] 61 | result.closeTime = val[6] 62 | result.quoteAssetVolume = val[7] 63 | result.numTrades = val[8] 64 | result.takerBuyBaseAssetVolume = val[9] 65 | result.takerBuyQuoteAssetVolume = val[10] 66 | result.ignore = val[11] 67 | 68 | return result 69 | -------------------------------------------------------------------------------- /binance-spot/model/candlestickevent.py: -------------------------------------------------------------------------------- 1 | class Candlestick: 2 | 3 | def __init__(self): 4 | self.startTime = 0 5 | self.closeTime = 0 6 | self.symbol = '' 7 | self.interval = '' 8 | self.firstTradeId = 0 9 | self.lastTradeId = 0 10 | self.open = 0.0 11 | self.close = 0.0 12 | self.high = 0.0 13 | self.low = 0.0 14 | self.volume = 0.0 15 | self.numTrades = 0 16 | self.isClosed = False 17 | self.quoteAssetVolume = 0.0 18 | self.takerBuyBaseAssetVolume = 0.0 19 | self.takerBuyQuoteAssetVolume = 0.0 20 | self.ignore = 0 21 | 22 | @staticmethod 23 | def json_parse(json_data): 24 | data_obj = Candlestick() 25 | data_obj.startTime = json_data.get_int('t') 26 | data_obj.closeTime = json_data.get_int('T') 27 | data_obj.symbol = json_data.get_string('s') 28 | data_obj.interval = json_data.get_string('i') 29 | data_obj.firstTradeId = json_data.get_int('f') 30 | data_obj.lastTradeId = json_data.get_int('L') 31 | data_obj.open = json_data.get_float('o') 32 | data_obj.close = json_data.get_float('c') 33 | data_obj.high = json_data.get_float('h') 34 | data_obj.low = json_data.get_float('l') 35 | data_obj.volume = json_data.get_float('v') 36 | data_obj.numTrades = json_data.get_int('n') 37 | data_obj.isClosed = json_data.get_boolean('x') 38 | data_obj.quoteAssetVolume = json_data.get_float('q') 39 | data_obj.takerBuyBaseAssetVolume = json_data.get_float('V') 40 | data_obj.takerBuyQuoteAssetVolume = json_data.get_float('Q') 41 | data_obj.ignore = json_data.get_int('B') 42 | 43 | return data_obj 44 | 45 | 46 | class CandlestickEvent: 47 | 48 | def __init__(self): 49 | self.eventType = '' 50 | self.eventTime = 0 51 | self.symbol = '' 52 | self.data = Candlestick() 53 | 54 | @staticmethod 55 | def json_parse(json_wrapper): 56 | candlestick_event = CandlestickEvent() 57 | candlestick_event.eventType = json_wrapper.get_string('e') 58 | candlestick_event.eventTime = json_wrapper.get_int('E') 59 | candlestick_event.symbol = json_wrapper.get_string('s') 60 | data = Candlestick.json_parse(json_wrapper.get_object('k')) 61 | candlestick_event.data = data 62 | return candlestick_event 63 | -------------------------------------------------------------------------------- /binance-spot/model/constant.py: -------------------------------------------------------------------------------- 1 | class CandlestickInterval: 2 | 3 | MIN1 = '1m' 4 | MIN3 = '3m' 5 | MIN5 = '5m' 6 | MIN15 = '15m' 7 | MIN30 = '30m' 8 | HOUR1 = '1h' 9 | HOUR2 = '2h' 10 | HOUR4 = '4h' 11 | HOUR6 = '6h' 12 | HOUR8 = '8h' 13 | HOUR12 = '12h' 14 | DAY1 = '1d' 15 | DAY3 = '3d' 16 | WEEK1 = '1w' 17 | MON1 = '1m' 18 | INVALID = None 19 | 20 | 21 | class OrderSide: 22 | 23 | BUY = 'BUY' 24 | SELL = 'SELL' 25 | INVALID = None 26 | 27 | 28 | class TimeInForce: 29 | 30 | GTC = 'GTC' 31 | IOC = 'IOC' 32 | FOK = 'FOK' 33 | GTX = 'GTX' 34 | INVALID = None 35 | 36 | 37 | class OrderType: 38 | 39 | LIMIT = 'LIMIT' 40 | MARKET = 'MARKET' 41 | STOP = 'STOP' 42 | STOP_MARKET = 'STOP_MARKET' 43 | TAKE_PROFIT = 'TAKE_PROFIT' 44 | TAKE_PROFIT_MARKET = 'TAKE_PROFIT_MARKET' 45 | TRAILING_STOP_MARKET = 'TRAILING_STOP_MARKET' 46 | INVALID = None 47 | 48 | 49 | class OrderRespType: 50 | 51 | ACK = 'ACK' 52 | RESULT = 'RESULT' 53 | FULL = 'FULL' 54 | INVALID = None 55 | 56 | 57 | class StopLimitTimeType: 58 | 59 | GTC = 'GTC' 60 | FOK = 'FOK' 61 | IOC = 'IOC' 62 | INVALID = None 63 | 64 | 65 | class SubscribeMessageType: 66 | 67 | RESPONSE = 'response' 68 | PAYLOAD = 'payload' 69 | 70 | 71 | class UpdateTime: 72 | 73 | NORMAL = '' 74 | FAST = '@100ms' 75 | REALTIME = '@0ms' 76 | INVALID = '' 77 | -------------------------------------------------------------------------------- /binance-spot/model/diffdepthevent.py: -------------------------------------------------------------------------------- 1 | class Order: 2 | 3 | def __init__(self): 4 | self.price = 0.0 5 | self.qty = 0 6 | 7 | 8 | class DiffDepthEvent: 9 | 10 | def __init__(self): 11 | self.eventType = '' 12 | self.eventTime = 0 13 | self.symbol = '' 14 | self.firstUpdateId = None 15 | self.finalUpdateId = None 16 | self.bids = list() 17 | self.asks = list() 18 | 19 | @staticmethod 20 | def json_parse(json_data): 21 | order_book = DiffDepthEvent() 22 | order_book.eventType = json_data.get_string('e') 23 | order_book.eventTime = json_data.get_int('E') 24 | order_book.symbol = json_data.get_string('s') 25 | order_book.firstUpdateId = json_data.get_int('U') 26 | order_book.finalUpdateId = json_data.get_int('u') 27 | 28 | list_array = json_data.get_array('b') 29 | bid_list = list() 30 | for item in list_array.get_items(): 31 | order = Order() 32 | val = item.convert_2_list() 33 | order.price = val[0] 34 | order.qty = val[1] 35 | bid_list.append(order) 36 | order_book.bids = bid_list 37 | 38 | list_array = json_data.get_array('a') 39 | ask_list = list() 40 | for item in list_array.get_items(): 41 | order = Order() 42 | val = item.convert_2_list() 43 | order.price = val[0] 44 | order.qty = val[1] 45 | ask_list.append(order) 46 | order_book.asks = ask_list 47 | 48 | return order_book 49 | -------------------------------------------------------------------------------- /binance-spot/model/exchangeinformation.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from common.scripts.binance_spot.impl.utils import JsonWrapper 4 | 5 | 6 | class RateLimit: 7 | 8 | def __init__(self): 9 | self.rateLimitType = '' 10 | self.interval = '' 11 | self.intervalNum = 0 12 | self.limit = 0 13 | 14 | 15 | class ExchangeFilter: 16 | 17 | def __init__(self): 18 | self.filterType = '' 19 | self.maxOrders = 0 20 | 21 | 22 | class Symbol: 23 | 24 | def __init__(self): 25 | self.symbol = '' 26 | self.status = '' 27 | self.baseAsset = '' 28 | self.baseAssetPrecision = 0 29 | self.quoteAsset = '' 30 | self.quotePrecision = 0 31 | self.quoteAssetPrecision = 0 32 | self.orderTypes = list() 33 | self.icebergAllowed = False 34 | self.ocoAllowed = False 35 | self.isSpotTradingAllowed = False 36 | self.isMarginTradingAllowed = False 37 | self.filters = list() 38 | self.permissions = list() 39 | 40 | 41 | class ExchangeInformation: 42 | 43 | def __init__(self): 44 | self.timezone = '' 45 | self.serverTime = 0 46 | self.rateLimits = list() 47 | self.exchangeFilters = list() 48 | self.symbols = list() 49 | 50 | @staticmethod 51 | def json_parse(json_data: JsonWrapper): 52 | result = ExchangeInformation() 53 | result.timezone = json_data.get_string('timezone') 54 | result.serverTime = json_data.get_int('serverTime') 55 | 56 | data_list = json_data.get_array('rateLimits') 57 | element_list = list() 58 | for item in data_list.get_items(): 59 | element = RateLimit() 60 | element.rateLimitType = item.get_string('rateLimitType') 61 | element.interval = item.get_string('interval') 62 | element.intervalNum = item.get_int('intervalNum') 63 | element.limit = item.get_int('limit') 64 | 65 | element_list.append(element) 66 | result.rateLimits = element_list 67 | 68 | data_list = json_data.get_array('exchangeFilters') 69 | element_list = list() 70 | for item in data_list.get_items(): 71 | element = ExchangeFilter() 72 | element.filterType = item.get_string('filterType') 73 | if element.filterType == 'EXCHANGE_MAX_NUM_ORDERS': 74 | element.maxNumOrders = item.get_int('maxNumOrders') 75 | elif element.filterType == 'EXCHANGE_MAX_ALGO_ORDERS': 76 | element.maxNumAlgoOrders = item.get_int('maxNumAlgoOrders') 77 | 78 | element_list.append(element) 79 | result.exchangeFilters = element_list 80 | 81 | data_list = json_data.get_array('symbols') 82 | element_list = list() 83 | for item in data_list.get_items(): 84 | element = Symbol() 85 | element.symbol = item.get_string('symbol') 86 | element.status = item.get_string('status') 87 | element.baseAsset = item.get_string('baseAsset') 88 | element.baseAssetPrecision = item.get_int('baseAssetPrecision') 89 | element.quoteAsset = item.get_string('quoteAsset') 90 | element.quotePrecision = item.get_int('quotePrecision') 91 | element.quoteAssetPrecision = item.get_int('quoteAssetPrecision') 92 | element.orderTypes = item.get_object('orderTypes').convert_2_list() 93 | element.icebergAllowed = item.get_boolean('icebergAllowed') 94 | element.ocoAllowed = item.get_boolean('ocoAllowed') 95 | element.isSpotTradingAllowed = item.get_boolean( 96 | 'isSpotTradingAllowed') 97 | element.isMarginTradingAllowed = item.get_boolean( 98 | 'isMarginTradingAllowed') 99 | 100 | val_list = item.get_array('filters') 101 | filter_list = list() 102 | for jtem in val_list.get_items(): 103 | filter_list.append(jtem.convert_2_dict()) 104 | element.filters = filter_list 105 | 106 | element_list.append(element) 107 | result.symbols = element_list 108 | 109 | result.permissions = json_data.get_object_or_default('permissions', JsonWrapper(json.loads('[]'))).convert_2_list() 110 | 111 | return result 112 | -------------------------------------------------------------------------------- /binance-spot/model/listenkeyexpired.py: -------------------------------------------------------------------------------- 1 | class ListenKeyExpired: 2 | def __init__(self): 3 | self.eventType = '' 4 | self.eventTime = 0 5 | 6 | @staticmethod 7 | def json_parse(json_data): 8 | result = ListenKeyExpired() 9 | result.eventType = json_data.get_string('e') 10 | result.eventTime = json_data.get_int('E') 11 | 12 | return result 13 | -------------------------------------------------------------------------------- /binance-spot/model/mytrade.py: -------------------------------------------------------------------------------- 1 | class MyTrade: 2 | 3 | def __init__(self): 4 | self.symbol = '' 5 | self.id = 0 6 | self.orderId = 0 7 | self.orderListId = 0 8 | self.price = 0.0 9 | self.qty = 0.0 10 | self.quoteQty = 0.0 11 | self.commission = 0.0 12 | self.commissionAsset = '' 13 | self.time = 0 14 | self.isBuyer = False 15 | self.isMaker = False 16 | self.isBestMatch = None 17 | 18 | @staticmethod 19 | def json_parse(json_data): 20 | result = MyTrade() 21 | result.symbol = json_data.get_string('symbol') 22 | result.id = json_data.get_int('id') 23 | result.orderId = json_data.get_int('orderId') 24 | result.orderListId = json_data.get_int('orderListId') 25 | result.price = json_data.get_float('price') 26 | result.qty = json_data.get_float('qty') 27 | result.quoteQty = json_data.get_float('quoteQty') 28 | result.commission = json_data.get_float('commission') 29 | result.commissionAsset = json_data.get_string('commissionAsset') 30 | result.time = json_data.get_int('time') 31 | result.isBuyer = json_data.get_boolean('buyer') 32 | result.isMaker = json_data.get_boolean('maker') 33 | result.isBestMatch = json_data.get_boolean('isBestMatch') 34 | 35 | return result 36 | -------------------------------------------------------------------------------- /binance-spot/model/order.py: -------------------------------------------------------------------------------- 1 | from common.scripts.binance_spot.impl.utils import JsonWrapper 2 | from common.scripts.binance_spot.model.exchangeinformation import Symbol 3 | 4 | 5 | class Fills: 6 | 7 | def __init__(self): 8 | self.price = 0.0 9 | self.qty = 0.0 10 | self.commission = 0.0 11 | self.commissionAsset = '' 12 | 13 | 14 | class Orders: 15 | 16 | def __init__(self): 17 | self.symbol = '' 18 | self.orderId = 0 19 | self.clientOrderId = '' 20 | 21 | 22 | class OrderReports: 23 | 24 | def __init__(self): 25 | self.symbol = '' 26 | self.origClientOrderId = '' 27 | self.orderId = 0 28 | self.orderListId = 0 29 | self.clientOrderId = '' 30 | self.price = 0.0 31 | self.origQty = 0.0 32 | self.executedQty = 0.0 33 | self.cummulativeQuoteQty = 0.0 34 | self.status = '' 35 | self.timeInForce = '' 36 | self.type = '' 37 | self.side = '' 38 | self.stopPrice = 0.0 39 | self.icebergQty = 0.0 40 | 41 | 42 | class Order: 43 | 44 | def __init__(self): 45 | self.symbol = '' 46 | self.origClientOrderId = '' 47 | self.orderId = 0 48 | self.orderListId = 0 49 | self.contingencyType = '' 50 | self.listStatusType = '' 51 | self.listOrderStatus = '' 52 | self.listClientOrderId = '' 53 | self.transactionTime = 0 54 | self.clientOrderId = '' 55 | self.transactTime = 0 56 | self.price = 0.0 57 | self.origQty = 0.0 58 | self.executedQty = 0.0 59 | self.cummulativeQuoteQty = 0.0 60 | self.status = '' 61 | self.timeInForce = '' 62 | self.type = '' 63 | self.side = '' 64 | self.stopPrice = 0.0 65 | self.icebergQty = 0.0 66 | self.time = 0 67 | self.updateTime = 0 68 | self.isWorking = False 69 | self.origQuoteOrderQty = 0.0 70 | self.fills = list() 71 | self.orders = list() 72 | self.orderReports = list() 73 | 74 | @staticmethod 75 | def json_parse(json_data: JsonWrapper): 76 | result = Order() 77 | result.symbol = json_data.get_string_or_default('symbol', '') 78 | result.origClientOrderId = json_data.get_string_or_default('origClientOrderId', '') 79 | result.orderId = json_data.get_int_or_default('orderId', 0) 80 | result.orderListId = json_data.get_int_or_default('orderListId', 0) 81 | result.contingencyType = json_data.get_string_or_default('contingencyType', '') 82 | result.listStatusType = json_data.get_string_or_default('listStatusType', '') 83 | result.listOrderStatus = json_data.get_string_or_default('listOrderStatus', '') 84 | result.listClientOrderId = json_data.get_string_or_default('listClientOrderId', '') 85 | result.transactionTime = json_data.get_int_or_default('transactionTime', 0) 86 | result.clientOrderId = json_data.get_string_or_default('clientOrderId', '') 87 | result.transactTime = json_data.get_int_or_default('transactTime', 0) 88 | result.price = json_data.get_float_or_default('price', 0.0) 89 | result.origQty = json_data.get_float_or_default('origQty', 0.0) 90 | result.executedQty = json_data.get_float_or_default('executedQty', 0.0) 91 | result.cummulativeQuoteQty = json_data.get_float_or_default('cummulativeQuoteQty', 0.0) 92 | result.status = json_data.get_string_or_default('status', '') 93 | result.timeInForce = json_data.get_string_or_default('timeInForce', '') 94 | result.type = json_data.get_string_or_default('type', '') 95 | result.side = json_data.get_string_or_default('side', '') 96 | result.stopPrice = json_data.get_float_or_default('stopPrice', 0.0) 97 | result.icebergQty = json_data.get_float_or_default('icebergQty', 0.0) 98 | result.time = json_data.get_int_or_default('time', 0) 99 | result.updateTime = json_data.get_int_or_default('updateTime', 0) 100 | result.isWorking = json_data.get_boolean_or_default('isWorking', False) 101 | result.origQuoteOrderQty = json_data.get_float_or_default('origQuoteOrderQty', 0.0) 102 | 103 | data_list = json_data.get_array_or_default('fills') 104 | element_list = list() 105 | for item in data_list.get_items(): 106 | element = Symbol() 107 | element.price = item.get_float_or_default('price', 0.0) 108 | element.qty = item.get_float_or_default('qty', 0.0) 109 | element.commission = item.get_float_or_default('commission', 0.0) 110 | element.commissionAsset = item.get_string_or_default('commissionAsset', '') 111 | 112 | element_list.append(element) 113 | result.fills = element_list 114 | 115 | data_list = json_data.get_array_or_default('orders') 116 | element_list = list() 117 | for item in data_list.get_items(): 118 | element = Orders() 119 | element.symbol = item.get_string_or_default('symbol', '') 120 | element.orderId = item.get_int_or_default('orderId', 0) 121 | element.clientOrderId = item.get_string_or_default('clientOrderId', '') 122 | 123 | element_list.append(element) 124 | result.orders = element_list 125 | 126 | data_list = json_data.get_array_or_default('orderReports') 127 | element_list = list() 128 | for item in data_list.get_items(): 129 | element = Orders() 130 | element.symbol = item.get_string_or_default('symbol', '') 131 | element.origClientOrderId = item.get_string_or_default('origClientOrderId', '') 132 | element.orderId = item.get_int_or_default('orderId', 0) 133 | element.orderListId = item.get_int_or_default('orderListId', 0) 134 | element.clientOrderId = item.get_string_or_default('clientOrderId', '') 135 | element.price = item.get_float_or_default('price', 0.0) 136 | element.origQty = item.get_float_or_default('origQty', 0.0) 137 | element.executedQty = item.get_float_or_default('executedQty', 0.0) 138 | element.cummulativeQuoteQty = item.get_float_or_default('cummulativeQuoteQty', 0.0) 139 | element.status = item.get_string_or_default('status', '') 140 | element.timeInForce = item.get_string_or_default('timeInForce', '') 141 | element.type = item.get_string_or_default('type', '') 142 | element.side = item.get_string_or_default('side', '') 143 | element.stopPrice = item.get_string_or_default('stopPrice', '') 144 | element.icebergQty = item.get_float_or_default('icebergQty', 0.0) 145 | 146 | element_list.append(element) 147 | result.orderReports = element_list 148 | 149 | return result 150 | -------------------------------------------------------------------------------- /binance-spot/model/orderOCO.py: -------------------------------------------------------------------------------- 1 | from common.scripts.binance_spot.impl.utils import JsonWrapper 2 | from common.scripts.binance_spot.model import Order 3 | 4 | class Orders: 5 | 6 | def __init__(self): 7 | self.symbol = '' 8 | self.orderId = 0 9 | self.clientOrderId = '' 10 | 11 | 12 | class OrderReports: 13 | 14 | def __init__(self): 15 | self.symbol = '' 16 | self.orderId = 0 17 | self.orderListId = 0 18 | self.clientOrderId = '' 19 | self.transactionTime = 0 20 | self.price = 0.0 21 | self.origQty = 0.0 22 | self.executedQty = 0.0 23 | self.cummulativeQuoteQty = 0.0 24 | self.status = '' 25 | self.timeInForce = '' 26 | self.type = '' 27 | self.side = '' 28 | self.stopPrice = 0.0 29 | 30 | 31 | class OrderOCO: 32 | 33 | def __init__(self): 34 | self.orderListId = 0 35 | self.contingencyType = '' 36 | self.listStatusType = '' 37 | self.listOrderStatus = '' 38 | self.listClientOrderId = '' 39 | self.transactionTime = 0 40 | self.symbol = '' 41 | self.orders = list() 42 | self.orderRexports = list() 43 | 44 | @staticmethod 45 | def json_parse(json_data: JsonWrapper): 46 | result = Order() 47 | result.orderListId = json_data.get_int_or_default('orderListId', 0) 48 | result.contingencyType = json_data.get_string_or_default('contingencyType', '') 49 | result.listStatusType = json_data.get_string_or_default('listStatusType', '') 50 | result.listOrderStatus = json_data.get_string_or_default('listOrderStatus', '') 51 | result.listClientOrderId = json_data.get_string_or_default('listClientOrderId', '') 52 | result.transactionTime = json_data.get_int_or_default('transactionTime', 0) 53 | result.symbol = json_data.get_string_or_default('symbol', '') 54 | 55 | data_list = json_data.get_array('orders') 56 | element_list = list() 57 | for item in data_list.get_items(): 58 | element = Orders() 59 | element.symbol = item.get_string_or_default('symbol', '') 60 | element.orderId = item.get_int_or_default('orderId', 0) 61 | element.clientOrderId = item.get_string_or_default('clientOrderId', '') 62 | element_list.append(element) 63 | result.orders = element_list 64 | 65 | data_list = json_data.get_array('orderReports') 66 | element_list = list() 67 | for item in data_list.get_items(): 68 | element = Orders() 69 | element.symbol = item.get_string_or_default('symbol', '') 70 | element.orderId = item.get_int_or_default('orderId', 0) 71 | element.orderListId = item.get_int_or_default('orderListId', 0) 72 | element.clientOrderId = item.get_string_or_default('clientOrderId', '') 73 | element.transactionTime = item.get_int_or_default('transactionTime', 0) 74 | element.price = item.get_float_or_default('price', 0.0) 75 | element.origQty = item.get_float_or_default('origQty', 0.0) 76 | element.executedQty = item.get_float_or_default('executedQty', 0.0) 77 | element.cummulativeQuoteQty = item.get_float_or_default('cummulativeQuoteQty', 0.0) 78 | element.status = item.get_string_or_default('status', '') 79 | element.timeInForce = item.get_string_or_default('timeInForce', '') 80 | element.type = item.get_string_or_default('type', '') 81 | element.side = item.get_string_or_default('side', '') 82 | element.stopPrice = item.get_string_or_default('stopPrice', '') 83 | element.icebergQty = item.get_float_or_default('icebergQty', 0.0) 84 | element_list.append(element) 85 | result.orders = element_list 86 | 87 | return result 88 | -------------------------------------------------------------------------------- /binance-spot/model/orderbook.py: -------------------------------------------------------------------------------- 1 | class Order: 2 | 3 | def __init__(self): 4 | self.price = 0.0 5 | self.qty = 0.0 6 | 7 | 8 | class OrderBook: 9 | 10 | def __init__(self): 11 | self.lastUpdateId = 0 12 | self.bids = list() 13 | self.asks = list() 14 | 15 | @staticmethod 16 | def json_parse(json_data): 17 | order_book = OrderBook() 18 | order_book.lastUpdateId = json_data.get_int('lastUpdateId') 19 | 20 | list_array = json_data.get_array('bids') 21 | bid_list = list() 22 | for item in list_array.get_items(): 23 | order = Order() 24 | val = item.convert_2_list() 25 | order.price = val[0] 26 | order.qty = val[1] 27 | bid_list.append(order) 28 | order_book.bids = bid_list 29 | 30 | list_array = json_data.get_array('asks') 31 | ask_list = list() 32 | for item in list_array.get_items(): 33 | order = Order() 34 | val = item.convert_2_list() 35 | order.price = val[0] 36 | order.qty = val[1] 37 | ask_list.append(order) 38 | order_book.asks = ask_list 39 | 40 | return order_book 41 | -------------------------------------------------------------------------------- /binance-spot/model/orderbookevent.py: -------------------------------------------------------------------------------- 1 | class Order: 2 | 3 | def __init__(self): 4 | self.price = 0.0 5 | self.qty = 0 6 | 7 | 8 | class OrderBookEvent: 9 | 10 | def __init__(self): 11 | self.lastUpdateId = 0 12 | self.bids = list() 13 | self.asks = list() 14 | 15 | @staticmethod 16 | def json_parse(json_data): 17 | result = OrderBookEvent() 18 | result.lastUpdateId = json_data.get_int('lastUpdateId') 19 | 20 | list_array = json_data.get_array('bids') 21 | bid_list = list() 22 | for item in list_array.get_items(): 23 | order = Order() 24 | val = item.convert_2_list() 25 | order.price = val[0] 26 | order.qty = val[1] 27 | bid_list.append(order) 28 | result.bids = bid_list 29 | 30 | list_array = json_data.get_array('asks') 31 | ask_list = list() 32 | for item in list_array.get_items(): 33 | order = Order() 34 | val = item.convert_2_list() 35 | order.price = val[0] 36 | order.qty = val[1] 37 | ask_list.append(order) 38 | result.asks = ask_list 39 | 40 | return result 41 | -------------------------------------------------------------------------------- /binance-spot/model/orderupdate.py: -------------------------------------------------------------------------------- 1 | class OrderUpdate: 2 | 3 | def __init__(self): 4 | self.eventType = '' 5 | self.eventTime = 0 6 | self.transactionTime = 0 7 | self.symbol = '' 8 | self.clientOrderId = '' 9 | self.side = None 10 | self.type = None 11 | self.timeInForce = None 12 | self.origQty = 0.0 13 | self.price = 0.0 14 | self.avgPrice = 0.0 15 | self.stopPrice = 0.0 16 | self.executionType = '' 17 | self.orderStatus = '' 18 | self.orderId = None 19 | self.lastFilledQty = 0.0 20 | self.cumulativeFilledQty = 0.0 21 | self.lastFilledPrice = 0.0 22 | self.commissionAsset = None 23 | self.commissionAmount = 0 24 | self.orderTradeTime = 0 25 | self.tradeID = None 26 | self.bidsNotional = 0.0 27 | self.asksNotional = 0.0 28 | self.isMarkerSide = None 29 | self.isReduceOnly = None 30 | self.workingType = 0.0 31 | self.isClosePosition = None 32 | self.activationPrice = 0.0 33 | self.callbackRate = 0.0 34 | self.positionSide = None 35 | 36 | @staticmethod 37 | def json_parse(json_data): 38 | result = OrderUpdate() 39 | result.eventType = json_data.get_string('e') 40 | result.eventTime = json_data.get_int('E') 41 | result.transactionTime = json_data.get_int('T') 42 | 43 | data_group = json_data.get_object('o') 44 | result.symbol = data_group.get_string('s') 45 | result.clientOrderId = data_group.get_string('c') 46 | result.side = data_group.get_string('S') 47 | result.type = data_group.get_string('o') 48 | result.timeInForce = data_group.get_string('f') 49 | result.origQty = data_group.get_float('q') 50 | result.price = data_group.get_float('p') 51 | result.avgPrice = data_group.get_float('ap') 52 | result.stopPrice = data_group.get_float('sp') 53 | result.executionType = data_group.get_string('x') 54 | result.orderStatus = data_group.get_string('X') 55 | result.orderId = data_group.get_int('i') 56 | result.lastFilledQty = data_group.get_float('l') 57 | result.cumulativeFilledQty = data_group.get_float('z') 58 | result.lastFilledPrice = data_group.get_float('L') 59 | result.commissionAsset = data_group.get_string_or_default('N', None) 60 | result.commissionAmount = data_group.get_float_or_default('n', None) 61 | result.orderTradeTime = data_group.get_int('T') 62 | result.tradeID = data_group.get_int('t') 63 | result.bidsNotional = data_group.get_float('b') 64 | result.asksNotional = data_group.get_float('a') 65 | result.isMarkerSide = data_group.get_boolean('m') 66 | result.isReduceOnly = data_group.get_boolean('R') 67 | result.workingType = data_group.get_string('wt') 68 | result.isClosePosition = data_group.get_boolean('cp') 69 | result.activationPrice = data_group.get_float_or_default('AP', None) 70 | result.callbackRate = data_group.get_float_or_default('cr', None) 71 | result.positionSide = data_group.get_string('ps') 72 | 73 | return result 74 | -------------------------------------------------------------------------------- /binance-spot/model/symbolbooktickerevent.py: -------------------------------------------------------------------------------- 1 | class SymbolBookTickerEvent: 2 | 3 | def __init__(self): 4 | self.orderBookUpdateId = 0 5 | self.symbol = '' 6 | self.bestBidPrice = 0.0 7 | self.bestBidQty = 0.0 8 | self.bestAskPrice = 0.0 9 | self.bestAskQty = 0.0 10 | 11 | @staticmethod 12 | def json_parse(json_wrapper): 13 | ticker_event = SymbolBookTickerEvent() 14 | ticker_event.orderBookUpdateId = json_wrapper.get_int('u') 15 | ticker_event.symbol = json_wrapper.get_string('s') 16 | ticker_event.bestBidPrice = json_wrapper.get_float('b') 17 | ticker_event.bestBidQty = json_wrapper.get_float('B') 18 | ticker_event.bestAskPrice = json_wrapper.get_float('a') 19 | ticker_event.bestAskQty = json_wrapper.get_float('A') 20 | return ticker_event 21 | -------------------------------------------------------------------------------- /binance-spot/model/symbolminitickerevent.py: -------------------------------------------------------------------------------- 1 | class SymbolMiniTickerEvent: 2 | 3 | def __init__(self): 4 | self.eventType = '' 5 | self.eventTime = 0 6 | self.symbol = '' 7 | self.close = 0.0 8 | self.open = 0.0 9 | self.high = 0.0 10 | self.low = 0.0 11 | self.totalTradedBaseAssetVolume = 0.0 12 | self.totalTradedQuoteAssetVolume = 0.0 13 | 14 | @staticmethod 15 | def json_parse(json_wrapper): 16 | result = SymbolMiniTickerEvent() 17 | result.eventType = json_wrapper.get_string('e') 18 | result.eventTime = json_wrapper.get_int('E') 19 | result.symbol = json_wrapper.get_string('s') 20 | result.close = json_wrapper.get_float('c') 21 | result.open = json_wrapper.get_float('o') 22 | result.high = json_wrapper.get_float('h') 23 | result.low = json_wrapper.get_float('l') 24 | result.totalTradedBaseAssetVolume = json_wrapper.get_float('v') 25 | result.totalTradedQuoteAssetVolume = json_wrapper.get_float('q') 26 | return result 27 | -------------------------------------------------------------------------------- /binance-spot/model/symbolorderbook.py: -------------------------------------------------------------------------------- 1 | class SymbolOrderBook: 2 | 3 | def __init__(self): 4 | self.symbol = '' 5 | self.bidPrice = 0.0 6 | self.bidQty = 0.0 7 | self.askPrice = 0.0 8 | self.askQty = 0.0 9 | 10 | @staticmethod 11 | def json_parse(json_data): 12 | result = SymbolOrderBook() 13 | result.symbol = json_data.get_string('symbol') 14 | result.bidPrice = json_data.get_float('bidPrice') 15 | result.bidQty = json_data.get_float('bidQty') 16 | result.askPrice = json_data.get_float('askPrice') 17 | result.askQty = json_data.get_float('askQty') 18 | return result 19 | -------------------------------------------------------------------------------- /binance-spot/model/symbolprice.py: -------------------------------------------------------------------------------- 1 | class SymbolPrice: 2 | 3 | def __init__(self): 4 | self.symbol = '' 5 | self.price = 0.0 6 | 7 | @staticmethod 8 | def json_parse(json_data): 9 | result = SymbolPrice() 10 | result.symbol = json_data.get_string('symbol') 11 | result.price = json_data.get_float('price') 12 | return result 13 | -------------------------------------------------------------------------------- /binance-spot/model/symboltickerevent.py: -------------------------------------------------------------------------------- 1 | class SymbolTickerEvent: 2 | 3 | def __init__(self): 4 | self.eventType = '' 5 | self.eventTime = 0 6 | self.symbol = '' 7 | self.priceChange = 0.0 8 | self.priceChangePercent = 0.0 9 | self.weightedAvgPrice = 0.0 10 | self.lastPrice = 0.0 11 | self.lastQty = 0 12 | self.bidPrice = 0.0 13 | self.bidQty = 0 14 | self.askPrice = 0.0 15 | self.askQty = 0 16 | self.open = 0.0 17 | self.high = 0.0 18 | self.low = 0.0 19 | self.totalTradedBaseAssetVolume = 0 20 | self.totalTradedQuoteAssetVolume = 0 21 | self.openTime = 0 22 | self.closeTime = 0 23 | self.firstId = 0 24 | self.lastId = 0 25 | self.count = 0 26 | 27 | @staticmethod 28 | def json_parse(json_wrapper): 29 | ticker_event = SymbolTickerEvent() 30 | ticker_event.eventType = json_wrapper.get_string('e') 31 | ticker_event.eventTime = json_wrapper.get_int('E') 32 | ticker_event.symbol = json_wrapper.get_string('s') 33 | ticker_event.priceChange = json_wrapper.get_float('p') 34 | ticker_event.priceChangePercent = json_wrapper.get_float('P') 35 | ticker_event.weightedAvgPrice = json_wrapper.get_float('w') 36 | ticker_event.lastPrice = json_wrapper.get_float('c') 37 | ticker_event.lastQty = json_wrapper.get_float('Q') 38 | ticker_event.bidPrice = json_wrapper.get_float('b') 39 | ticker_event.bidQty = json_wrapper.get_int('B') 40 | ticker_event.askPrice = json_wrapper.get_float('a') 41 | ticker_event.askQty = json_wrapper.get_int('A') 42 | ticker_event.open = json_wrapper.get_float('o') 43 | ticker_event.high = json_wrapper.get_float('h') 44 | ticker_event.low = json_wrapper.get_float('l') 45 | ticker_event.totalTradedBaseAssetVolume = json_wrapper.get_int('v') 46 | ticker_event.totalTradedQuoteAssetVolume = json_wrapper.get_int('q') 47 | ticker_event.openTime = json_wrapper.get_int('O') 48 | ticker_event.closeTime = json_wrapper.get_int('C') 49 | ticker_event.firstId = json_wrapper.get_int('F') 50 | ticker_event.lastId = json_wrapper.get_int('L') 51 | ticker_event.count = json_wrapper.get_int('n') 52 | return ticker_event 53 | -------------------------------------------------------------------------------- /binance-spot/model/tickerpricechangestatistics.py: -------------------------------------------------------------------------------- 1 | class TickerPriceChangeStatistics: 2 | 3 | def __init__(self): 4 | self.symbol = '' 5 | self.priceChange = 0.0 6 | self.priceChangePercent = 0.0 7 | self.weightedAvgPrice = 0.0 8 | self.prevClosePrice = 0.0 9 | self.lastPrice = 0.0 10 | self.lastQty = 0.0 11 | self.bidPrice = 0.0 12 | self.askPrice = 0.0 13 | self.openPrice = 0.0 14 | self.highPrice = 0.0 15 | self.lowPrice = 0.0 16 | self.volume = 0.0 17 | self.quoteVolume = 0.0 18 | self.openTime = 0 19 | self.closeTime = 0 20 | self.firstId = 0 21 | self.lastId = 0 22 | self.count = 0 23 | 24 | @staticmethod 25 | def json_parse(json_data): 26 | result = TickerPriceChangeStatistics() 27 | result.symbol = json_data.get_string('symbol') 28 | result.priceChange = json_data.get_float('priceChange') 29 | result.priceChangePercent = json_data.get_float('priceChangePercent') 30 | result.weightedAvgPrice = json_data.get_float('weightedAvgPrice') 31 | result.prevClosePrice = json_data.get_float('prevClosePrice') 32 | result.lastPrice = json_data.get_float('lastPrice') 33 | result.lastQty = json_data.get_float('lastQty') 34 | result.bidPrice = json_data.get_float('bidPrice') 35 | result.askPrice = json_data.get_float('askPrice') 36 | result.openPrice = json_data.get_float('openPrice') 37 | result.highPrice = json_data.get_float('highPrice') 38 | result.lowPrice = json_data.get_float('lowPrice') 39 | result.volume = json_data.get_float('volume') 40 | result.quoteVolume = json_data.get_float('quoteVolume') 41 | result.openTime = json_data.get_int('openTime') 42 | result.closeTime = json_data.get_int('closeTime') 43 | result.firstId = json_data.get_int('firstId') 44 | result.lastId = json_data.get_int('lastId') 45 | result.count = json_data.get_int('count') 46 | return result 47 | -------------------------------------------------------------------------------- /binance-spot/model/trade.py: -------------------------------------------------------------------------------- 1 | class Trade: 2 | 3 | def __init__(self): 4 | self.id = 0 5 | self.price = 0.0 6 | self.qty = 0.0 7 | self.quoteQty = 0.0 8 | self.time = 0 9 | self.isBuyerMaker = False 10 | self.isBestMatch = False 11 | 12 | @staticmethod 13 | def json_parse(json_data): 14 | result = Trade() 15 | result.id = json_data.get_int('id') 16 | result.price = json_data.get_float('price') 17 | result.qty = json_data.get_float('qty') 18 | result.quoteQty = json_data.get_float('quoteQty') 19 | result.time = json_data.get_int('time') 20 | result.isBuyerMaker = json_data.get_boolean('isBuyerMaker') 21 | result.isBestMatch = json_data.get_boolean('isBestMatch') 22 | 23 | return result 24 | -------------------------------------------------------------------------------- /binance-spot/model/tradeevent.py: -------------------------------------------------------------------------------- 1 | class TradeEvent: 2 | 3 | def __init__(self): 4 | self.eventType = '' 5 | self.eventTime = 0 6 | self.symbol = '' 7 | self.id = 0 8 | self.price = 0.0 9 | self.qty = 0 10 | self.buyerId = 0 11 | self.sellerId = 0 12 | self.time = 0 13 | self.isBuyerMaker = False 14 | self.ignore = False 15 | 16 | @staticmethod 17 | def json_parse(json_wrapper): 18 | result = AggregateTradeEvent() 19 | result.eventType = json_wrapper.get_string('e') 20 | result.eventTime = json_wrapper.get_int('E') 21 | result.symbol = json_wrapper.get_string('s') 22 | result.id = json_wrapper.get_int('t') 23 | result.price = json_wrapper.get_float('p') 24 | result.qty = json_wrapper.get_float('q') 25 | result.buyerId = json_wrapper.get_int('b') 26 | result.sellerId = json_wrapper.get_int('a') 27 | result.time = json_wrapper.get_int('T') 28 | result.isBuyerMaker = json_wrapper.get_boolean('m') 29 | result.ignore = json_wrapper.get_boolean('M') 30 | return result 31 | -------------------------------------------------------------------------------- /binance-spot/subscriptionclient.py: -------------------------------------------------------------------------------- 1 | import urllib.parse 2 | 3 | from common.scripts.binance_spot.constant.system import WebSocketDefine 4 | from common.scripts.binance_spot.impl.websocketrequestimpl import WebsocketRequestImpl 5 | from common.scripts.binance_spot.impl.websocketconnection import WebsocketConnection 6 | from common.scripts.binance_spot.impl.websocketwatchdog import WebSocketWatchDog 7 | from common.scripts.binance_spot.impl.restapirequestimpl import RestApiRequestImpl 8 | from common.scripts.binance_spot.model import * 9 | from common.scripts.binance_spot.model.constant import * 10 | 11 | # For develop 12 | from common.scripts.binance_spot.base.printobject import * 13 | 14 | 15 | class SubscriptionClient(object): 16 | 17 | def __init__(self, **kwargs): 18 | ''' 19 | Create the subscription client to subscribe the update from server. 20 | 21 | :param kwargs: The option of subscription connection. 22 | api_key: The public key applied from common.scripts.binance_spot. 23 | secret_key: The private key applied from common.scripts.binance_spot. 24 | uri: Set the URI for subscription. 25 | is_auto_connect: When the connection lost is happening on the subscription line, specify whether the client 26 | reconnect to server automatically. The connection lost means: 27 | Caused by network problem 28 | The connection close triggered by server (happened every 24 hours) 29 | No any message can be received from server within a specified time, see receive_limit_ms 30 | receive_limit_ms: Set the receive limit in millisecond. If no message is received within this limit time, 31 | the connection will be disconnected. 32 | connection_delay_failure: If auto reconnect is enabled, specify the delay time before reconnect. 33 | ''' 34 | api_key = None 35 | secret_key = None 36 | if 'api_key' in kwargs: 37 | api_key = kwargs['api_key'] 38 | if 'secret_key' in kwargs: 39 | secret_key = kwargs['secret_key'] 40 | self.__api_key = api_key 41 | self.__secret_key = secret_key 42 | self.websocket_request_impl = WebsocketRequestImpl(self.__api_key) 43 | self.connections = list() 44 | self.uri = WebSocketDefine.Uri 45 | is_auto_connect = True 46 | receive_limit_ms = 60000 47 | connection_delay_failure = 1 48 | if 'uri' in kwargs: 49 | self.uri = kwargs['uri'] 50 | if 'is_auto_connect' in kwargs: 51 | is_auto_connect = kwargs['is_auto_connect'] 52 | if 'receive_limit_ms' in kwargs: 53 | receive_limit_ms = kwargs['receive_limit_ms'] 54 | if 'connection_delay_failure' in kwargs: 55 | connection_delay_failure = kwargs['connection_delay_failure'] 56 | self.__watch_dog = WebSocketWatchDog( 57 | is_auto_connect, receive_limit_ms, connection_delay_failure) 58 | 59 | def __create_connection(self, request): 60 | connection = WebsocketConnection( 61 | self.__api_key, self.__secret_key, self.uri, self.__watch_dog, request) 62 | self.connections.append(connection) 63 | connection.connect() 64 | 65 | def unsubscribe_all(self): 66 | for conn in self.connections: 67 | conn.close() 68 | self.connections.clear() 69 | 70 | def subscribe_aggregate_trade_event(self, symbol: 'str', callback, error_handler=None): 71 | ''' 72 | Aggregate Trade Streams 73 | 74 | The Aggregate Trade Streams push trade information that is aggregated for a single taker order every 100 milliseconds. 75 | 76 | Stream Name: @aggTrade 77 | 78 | Update Speed: Real-time 79 | 80 | Payload: 81 | 82 | { 83 | "e": "aggTrade", // Event type 84 | "E": 123456789, // Event time 85 | "s": "BNBBTC", // Symbol 86 | "a": 12345, // Aggregate trade ID 87 | "p": "0.001", // Price 88 | "q": "100", // Quantity 89 | "f": 100, // First trade ID 90 | "l": 105, // Last trade ID 91 | "T": 123456785, // Trade time 92 | "m": true, // Is the buyer the market maker? 93 | "M": true // Ignore 94 | } 95 | ''' 96 | request = self.websocket_request_impl.subscribe_aggregate_trade_event( 97 | symbol, callback, error_handler) 98 | self.__create_connection(request) 99 | 100 | def subscribe_trade_event(self, symbol: 'str', callback, error_handler=None): 101 | ''' 102 | Trade Streams 103 | 104 | The Trade Streams push raw trade information; each trade has a unique buyer and seller. 105 | 106 | Stream Name: @trade 107 | 108 | Update Speed: Real-time 109 | 110 | Payload: 111 | 112 | { 113 | "e": "trade", // Event type 114 | "E": 123456789, // Event time 115 | "s": "BNBBTC", // Symbol 116 | "t": 12345, // Trade ID 117 | "p": "0.001", // Price 118 | "q": "100", // Quantity 119 | "b": 88, // Buyer order ID 120 | "a": 50, // Seller order ID 121 | "T": 123456785, // Trade time 122 | "m": true, // Is the buyer the market maker? 123 | "M": true // Ignore 124 | } 125 | ''' 126 | request = self.websocket_request_impl.subscribe_trade_event( 127 | symbol, callback, error_handler) 128 | self.__create_connection(request) 129 | 130 | def subscribe_candlestick_event(self, symbol: 'str', interval: 'CandlestickInterval', callback, 131 | error_handler=None): 132 | ''' 133 | Kline/Candlestick Streams 134 | 135 | The Kline/Candlestick Stream push updates to the current klines/candlestick every 250 milliseconds (if existing). 136 | 137 | Stream Name: @kline_ 138 | 139 | Update Speed: 2000ms 140 | 141 | Payload: 142 | 143 | { 144 | "e": "kline", // Event type 145 | "E": 123456789, // Event time 146 | "s": "BNBBTC", // Symbol 147 | "k": { 148 | "t": 123400000, // Kline start time 149 | "T": 123460000, // Kline close time 150 | "s": "BNBBTC", // Symbol 151 | "i": "1m", // Interval 152 | "f": 100, // First trade ID 153 | "L": 200, // Last trade ID 154 | "o": "0.0010", // Open price 155 | "c": "0.0020", // Close price 156 | "h": "0.0025", // High price 157 | "l": "0.0015", // Low price 158 | "v": "1000", // Base asset volume 159 | "n": 100, // Number of trades 160 | "x": false, // Is this kline closed? 161 | "q": "1.0000", // Quote asset volume 162 | "V": "500", // Taker buy base asset volume 163 | "Q": "0.500", // Taker buy quote asset volume 164 | "B": "123456" // Ignore 165 | } 166 | } 167 | ''' 168 | request = self.websocket_request_impl.subscribe_candlestick_event( 169 | symbol, interval, callback, error_handler) 170 | self.__create_connection(request) 171 | 172 | def subscribe_symbol_miniticker_event(self, symbol: 'str', callback, error_handler=None): 173 | ''' 174 | Individual Symbol Mini Ticker Stream 175 | 176 | 24hr rolling window mini-ticker statistics for a single symbol pushed every 3 seconds. These are NOT the statistics of the UTC day, 177 | but a 24hr rolling window from requestTime to 24hrs before. 178 | 179 | Stream Name: @miniTicker 180 | 181 | Update Speed: 1000ms 182 | 183 | Payload: 184 | 185 | { 186 | "e": "24hrMiniTicker", // Event type 187 | "E": 123456789, // Event time 188 | "s": "BNBBTC", // Symbol 189 | "c": "0.0025", // Close price 190 | "o": "0.0010", // Open price 191 | "h": "0.0025", // High price 192 | "l": "0.0010", // Low price 193 | "v": "10000", // Total traded base asset volume 194 | "q": "18" // Total traded quote asset volume 195 | } 196 | ''' 197 | request = self.websocket_request_impl.subscribe_symbol_miniticker_event( 198 | symbol, callback, error_handler) 199 | self.__create_connection(request) 200 | 201 | def subscribe_all_miniticker_event(self, callback, error_handler=None): 202 | ''' 203 | All Market Mini Tickers Stream 204 | 205 | 24hr rolling window mini-ticker statistics for all symbols pushed every 3 seconds. 206 | These are NOT the statistics of the UTC day, but a 24hr rolling window from requestTime to 24hrs before. 207 | Note that only tickers that have changed will be present in the array. 208 | 209 | Stream Name: !miniTicker@arr 210 | 211 | Update Speed: 1000ms 212 | 213 | Payload: 214 | 215 | [ 216 | { 217 | // Same as @miniTicker payload 218 | } 219 | ] 220 | ''' 221 | request = self.websocket_request_impl.subscribe_all_miniticker_event( 222 | callback, error_handler) 223 | self.__create_connection(request) 224 | 225 | def subscribe_symbol_ticker_event(self, symbol: 'str', callback, error_handler=None): 226 | ''' 227 | Individual Symbol Ticker Streams 228 | 229 | 24hr rollwing window ticker statistics for a single symbol pushed every 3 seconds. These are NOT the statistics of the UTC day, 230 | but a 24hr rolling window from requestTime to 24hrs before. 231 | 232 | Stream Name: @ticker 233 | 234 | Update Speed: 1000ms 235 | 236 | Payload: 237 | 238 | { 239 | "e": "24hrTicker", // Event type 240 | "E": 123456789, // Event time 241 | "s": "BNBBTC", // Symbol 242 | "p": "0.0015", // Price change 243 | "P": "250.00", // Price change percent 244 | "w": "0.0018", // Weighted average price 245 | "x": "0.0009", // First trade(F)-1 price (first trade before the 24hr rolling window) 246 | "c": "0.0025", // Last price 247 | "Q": "10", // Last quantity 248 | "b": "0.0024", // Best bid price 249 | "B": "10", // Best bid quantity 250 | "a": "0.0026", // Best ask price 251 | "A": "100", // Best ask quantity 252 | "o": "0.0010", // Open price 253 | "h": "0.0025", // High price 254 | "l": "0.0010", // Low price 255 | "v": "10000", // Total traded base asset volume 256 | "q": "18", // Total traded quote asset volume 257 | "O": 0, // Statistics open time 258 | "C": 86400000, // Statistics close time 259 | "F": 0, // First trade ID 260 | "L": 18150, // Last trade Id 261 | "n": 18151 // Total number of trades 262 | } 263 | ''' 264 | request = self.websocket_request_impl.subscribe_symbol_ticker_event( 265 | symbol, callback, error_handler) 266 | self.__create_connection(request) 267 | 268 | def subscribe_all_ticker_event(self, callback, error_handler=None): 269 | ''' 270 | All Market Tickers Stream 271 | 272 | 24hr rollwing window ticker statistics for all symbols pushed every 3 seconds. These are NOT the statistics of the UTC day, but a 24hr rolling window from requestTime to 24hrs before. 273 | Note that only tickers that have changed will be present in the array. 274 | 275 | Stream Name: !ticker@arr 276 | 277 | Update Speed: 1000ms 278 | 279 | Payload: 280 | 281 | [ 282 | { 283 | // Same as @ticker payload 284 | } 285 | ] 286 | ''' 287 | request = self.websocket_request_impl.subscribe_all_ticker_event( 288 | callback, error_handler) 289 | self.__create_connection(request) 290 | 291 | def subscribe_symbol_bookticker_event(self, symbol: 'str', callback, error_handler=None): 292 | ''' 293 | Individual Symbol Book Ticker Streams 294 | 295 | Pushes any update to the best bid or ask's price or quantity in real-time for a specified symbol. 296 | 297 | Stream Name: @bookTicker 298 | 299 | Update Speed: Real-time 300 | 301 | Payload: 302 | 303 | { 304 | "u":400900217, // order book updateId 305 | "s":"BNBUSDT", // symbol 306 | "b":"25.35190000", // best bid price 307 | "B":"31.21000000", // best bid qty 308 | "a":"25.36520000", // best ask price 309 | "A":"40.66000000" // best ask qty 310 | } 311 | ''' 312 | request = self.websocket_request_impl.subscribe_symbol_bookticker_event( 313 | symbol, callback, error_handler) 314 | self.__create_connection(request) 315 | 316 | def subscribe_all_bookticker_event(self, callback, error_handler=None): 317 | ''' 318 | All Book Tickers Stream 319 | 320 | Pushes any update to the best bid or ask's price or quantity in real-time for all symbols. 321 | 322 | Stream Name: !bookTicker 323 | 324 | Update Speed: Real-time 325 | 326 | Payload: 327 | 328 | { 329 | // Same as @bookTicker payload 330 | } 331 | ''' 332 | request = self.websocket_request_impl.subscribe_all_bookticker_event( 333 | callback, error_handler) 334 | self.__create_connection(request) 335 | 336 | def subscribe_book_depth_event(self, symbol: 'str', limit: 'int', callback, error_handler=None, update_time: 'UpdateTime' = UpdateTime.INVALID): 337 | ''' 338 | Partial Book Depth Streams 339 | 340 | Top bids and asks, Valid are 5, 10, or 20. 341 | 342 | Stream Names: @depth OR @depth@100ms. 343 | 344 | Update Speed: 1000ms or 100ms 345 | 346 | Payload: 347 | 348 | { 349 | "lastUpdateId": 160, // Last update ID 350 | "bids": [ // Bids to be updated 351 | [ 352 | "0.0024", // Price level to be updated 353 | "10" // Quantity 354 | ] 355 | ], 356 | "asks": [ // Asks to be updated 357 | [ 358 | "0.0026", // Price level to be updated 359 | "100" // Quantity 360 | ] 361 | ] 362 | } 363 | ''' 364 | print(update_time) 365 | request = self.websocket_request_impl.subscribe_book_depth_event( 366 | symbol, limit, update_time, callback, error_handler) 367 | self.__create_connection(request) 368 | 369 | def subscribe_diff_depth_event(self, symbol: 'str', callback, error_handler=None, update_time: 'UpdateTime' = UpdateTime.INVALID): 370 | ''' 371 | Diff. Depth Stream 372 | 373 | Order book price and quantity depth updates used to locally manage an order book. 374 | 375 | Stream Name: @depth OR @depth@100ms 376 | 377 | Update Speed: 1000ms or 100ms 378 | 379 | Payload: 380 | 381 | { 382 | "e": "depthUpdate", // Event type 383 | "E": 123456789, // Event time 384 | "s": "BNBBTC", // Symbol 385 | "U": 157, // First update ID in event 386 | "u": 160, // Final update ID in event 387 | "b": [ // Bids to be updated 388 | [ 389 | "0.0024", // Price level to be updated 390 | "10" // Quantity 391 | ] 392 | ], 393 | "a": [ // Asks to be updated 394 | [ 395 | "0.0026", // Price level to be updated 396 | "100" // Quantity 397 | ] 398 | ] 399 | } 400 | ''' 401 | request = self.websocket_request_impl.subscribe_diff_depth_event( 402 | symbol, update_time, callback, error_handler) 403 | self.__create_connection(request) 404 | 405 | def subscribe_user_data_event(self, listenKey: 'str', callback, error_handler=None): 406 | ''' 407 | User Data Streams 408 | ''' 409 | request = self.websocket_request_impl.subscribe_user_data_event( 410 | listenKey, callback, error_handler) 411 | self.__create_connection(request) 412 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open('README.md', 'r') as fh: 4 | long_description = fh.read() 5 | 6 | setuptools.setup( 7 | name='solo-binance-api', 8 | version='0.1.2', 9 | author='Abdeen Mohamed, Tarun ', 10 | author_email='abdeen.mohamed@outlook.com, ', 11 | description='A python library that implements the Binance Exchange REST API and Web socket communication.', 12 | long_description=long_description, 13 | long_description_content_type='text/markdown', 14 | url='https://github.com/AbdeenM/binance-api', 15 | packages=setuptools.find_packages(), 16 | classifiers=[ 17 | 'Programming Language :: Python :: 3', 18 | 'License :: OSI Approved :: MIT License', 19 | 'Operating System :: OS Independent', 20 | ], 21 | python_requires='>=3.6', 22 | ) --------------------------------------------------------------------------------