exchanges-wrapper 1.4.14__tar.gz → 1.4.16__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. exchanges-wrapper-1.4.16/.deepsource.toml +12 -0
  2. exchanges-wrapper-1.4.16/.dockerignore +3 -0
  3. exchanges-wrapper-1.4.16/.github/FUNDING.yml +1 -0
  4. exchanges-wrapper-1.4.16/.github/dependabot.yml +11 -0
  5. exchanges-wrapper-1.4.16/.github/workflows/docker-image.yml +32 -0
  6. exchanges-wrapper-1.4.16/.github/workflows/python-publish.yml +40 -0
  7. exchanges-wrapper-1.4.16/CHANGELOG.md +467 -0
  8. exchanges-wrapper-1.4.16/Dockerfile +23 -0
  9. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/PKG-INFO +1 -1
  10. exchanges-wrapper-1.4.16/example/exch_client.py +422 -0
  11. exchanges-wrapper-1.4.16/example/ms_cfg.toml +5 -0
  12. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/__init__.py +1 -1
  13. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/exch_srv.py +10 -6
  14. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/http_client.py +9 -9
  15. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/huobi_parser.py +1 -1
  16. exchanges-wrapper-1.4.16/requirements.txt +11 -0
  17. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/LICENSE.md +0 -0
  18. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/README.md +0 -0
  19. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/api_pb2.py +0 -0
  20. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/api_pb2_grpc.py +0 -0
  21. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/bitfinex_parser.py +0 -0
  22. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/bybit_parser.py +0 -0
  23. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/c_structures.py +0 -0
  24. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/client.py +0 -0
  25. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/definitions.py +0 -0
  26. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/errors.py +0 -0
  27. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/events.py +0 -0
  28. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/exch_srv_cfg.toml.template +0 -0
  29. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/okx_parser.py +0 -0
  30. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/proto/exchanges_wrapper/api.proto +0 -0
  31. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/exchanges_wrapper/web_sockets.py +0 -0
  32. {exchanges_wrapper-1.4.14 → exchanges-wrapper-1.4.16}/pyproject.toml +0 -0
@@ -0,0 +1,12 @@
1
+ version = 1
2
+
3
+ exclude_patterns = ["*/api*.*",
4
+ ]
5
+
6
+ [[analyzers]]
7
+ name = "python"
8
+ enabled = true
9
+
10
+ [analyzers.meta]
11
+ runtime_version = "3.x.x"
12
+ max_line_length = 120
@@ -0,0 +1,3 @@
1
+ **/__pycache__/
2
+ exchanges_wrapper/exchanges_wrapper/
3
+ exchanges_wrapper/proto/
@@ -0,0 +1 @@
1
+ custom: ['https://github.com/DogsTailFarmer/exchanges-wrapper#donate']
@@ -0,0 +1,11 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for all configuration options:
4
+ # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5
+
6
+ version: 2
7
+ updates:
8
+ - package-ecosystem: "pip" # See documentation for possible values
9
+ directory: "/" # Location of package manifests
10
+ schedule:
11
+ interval: "weekly"
@@ -0,0 +1,32 @@
1
+ name: Docker Image CI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ release:
6
+ types: [published]
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - name: Checkout
13
+ uses: actions/checkout@v3
14
+
15
+ - name: PrepareReg Names
16
+ run: |
17
+ echo IMAGE_REPOSITORY=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
18
+ echo IMAGE_TAG=$(echo ${{ github.ref }} | tr '[:upper:]' '[:lower:]' | awk '{split($0,a,"/"); print a[3]}') >> $GITHUB_ENV
19
+
20
+ - name: Login to GHCR
21
+ uses: docker/login-action@v2
22
+ with:
23
+ registry: ghcr.io
24
+ username: ${{ github.repository_owner }}
25
+ password: ${{ secrets.GITHUB_TOKEN }}
26
+
27
+ - name: Build and push
28
+ run: |
29
+ docker build . --tag ghcr.io/$IMAGE_REPOSITORY:$IMAGE_TAG
30
+ docker push ghcr.io/$IMAGE_REPOSITORY:$IMAGE_TAG
31
+ docker build . --tag ghcr.io/$IMAGE_REPOSITORY:latest
32
+ docker push ghcr.io/$IMAGE_REPOSITORY:latest
@@ -0,0 +1,40 @@
1
+ # This workflow will upload a Python Package using Twine when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3
+
4
+ # This workflow uses actions that are not certified by GitHub.
5
+ # They are provided by a third-party and are governed by
6
+ # separate terms of service, privacy policy, and support
7
+ # documentation.
8
+
9
+ name: Upload Python Package
10
+
11
+ on:
12
+ workflow_dispatch:
13
+ release:
14
+ types: [published]
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ jobs:
20
+ deploy:
21
+
22
+ runs-on: ubuntu-latest
23
+
24
+ steps:
25
+ - uses: actions/checkout@v3
26
+ - name: Set up Python
27
+ uses: actions/setup-python@v3
28
+ with:
29
+ python-version: '3.x'
30
+ - name: Install dependencies
31
+ run: |
32
+ python -m pip install --upgrade pip
33
+ pip install build
34
+ - name: Build package
35
+ run: python -m build
36
+ - name: Publish package
37
+ uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
38
+ with:
39
+ user: __token__
40
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,467 @@
1
+ ## 1.4.16 2024-02-25
2
+ ### Fix
3
+ * `CreateLimitOrder()`: Missed `trade_id` parameter in fetch_order() call
4
+
5
+ ### Update
6
+ * Refine error handling in `http_client`
7
+
8
+ ## 1.4.15 2024-02-02
9
+ ### Fix
10
+ * `HTX`: order Status set on cumulative_filled_quantity value only and `status` from event is ignored
11
+
12
+ ## 1.4.14 2024-02-19
13
+ ### Fix
14
+ * Exception in fetch_order: 'KeyError': 'commission'
15
+ * `fetch_order_trade_list()`: variables type inconsistent
16
+ * HTX: correcting order Status depending on cumulative_filled_quantity
17
+
18
+ ## 1.4.13 2024-02-18
19
+ ### Fix
20
+ * `FetchOrder()`: conditions for generating a trading event(s)
21
+
22
+ ## 1.4.12 2024-02-12
23
+ ### Fix
24
+ * `c_structures.OrderTradesEvent`: some fields are mixed up
25
+ * Bybit: generating a redundant order fill event
26
+ * `create_trade_stream_event`: using actual order status instead of estimated status
27
+
28
+ ## 1.4.11.post1 2024-02-11
29
+ ### Fix
30
+ * Bitfinex: setting original order quantity for placed order when first getting event is `te` type
31
+
32
+ ## 1.4.11 2024-02-11
33
+ ### Fix
34
+ * Bitfinex: use `symbol` parameter for cancel all order
35
+
36
+ ## 1.4.10 2024-02-09
37
+ ### Fix
38
+ * Generate trading events on the partial filled missing event
39
+ * Dependency: Rollback `grpcio` and `grpcio-tools` to 1.48.2
40
+
41
+ ## 1.4.9 2024-02-07
42
+ ### Fix
43
+ * Some minor fixes
44
+
45
+ ## 1.4.9b5 2024-02-07
46
+ ### Update
47
+ * Dependency: Up requirements for `grpcio` and `grpcio-tools` to 1.60.1
48
+
49
+ ## 1.4.9b3 2024-02-07
50
+ ### Update
51
+ * Bitfinex: refining order processing
52
+
53
+ ## 1.4.9b2 2024-02-05
54
+ ### Fix
55
+ * Binance: `TransferToMaster`: sentence `Email address should be encoded. e.g. alice@test.com should be encoded into
56
+ alice%40test.com` from API docs the are False, must be `content += urlencode(kwargs["params"], safe="@")`
57
+
58
+ ### Update
59
+ * HTX: changed deprecated endpoint "v1/common/symbols" to "v1/settings/common/market-symbols"
60
+ * Binance: `GET /api/v3/exchangeInfo` from response remove deprecated `quotePrecision`
61
+
62
+ ## 1.4.8 2024-02-02
63
+ ### Added for new features
64
+ * Binance: `TransferToMaster` now can be used for collect assets on the sub-account
65
+
66
+ ## 1.4.7.post6 2024-01-31
67
+ ### Fix
68
+ * Bitfinex: order processing
69
+
70
+ ## 1.4.7 2024-01-25
71
+ ### Fix
72
+ * Bybit: filter LOT_SIZE.stepSize
73
+ * Bitfinex: filter LOT_SIZE.stepSize
74
+
75
+ ### Added for new features
76
+ * Binance: new method [`OneClickArrivalDeposit`](https://binance-docs.github.io/apidocs/spot/en/#one-click-arrival-deposit-apply-for-expired-address-deposit-user_data)
77
+
78
+ ### Update
79
+ * Bitfinex: refine the order processing
80
+ * Dependency: Up requirements for Python>=3.9
81
+
82
+ ## v1.4.6 2024-01-06
83
+ ### Update
84
+ * FetchOrder: Bitfinex: generate trades events for orders older than the last two weeks
85
+
86
+ ## v1.4.5 2024-01-05
87
+ ### Fix
88
+ * `exch_client.py` init error
89
+
90
+ ### Update
91
+ * replacing json with ujson to improve performance
92
+ * Dependency: Up requirements for crypto-ws-api==2.0.6
93
+
94
+ ## v1.4.4 2023-12-13
95
+ ### Update
96
+ * Before send cancel order result checking if it was be executed and generating trade event
97
+ * Rollback 1.4.3
98
+ - Binance: in create Limit order parameters adding parameter "selfTradePreventionMode": "NONE"
99
+
100
+ ## v1.4.3 2023-12-12
101
+ ### Fix
102
+ * For limit order get status EXPIRED_IN_MATCH on Binance testnet #42
103
+ + Binance: in create Limit order parameters adding parameter "selfTradePreventionMode": "NONE"
104
+ + For method json_format.ParseDict(..., ignore_unknown_fields=True) parameter added
105
+
106
+ ## v1.4.2 2023-12-11
107
+ ### Update
108
+ * Some minor improvements
109
+
110
+ ## v1.4.1 2023-12-01
111
+ ### Update
112
+ * Bybit: fetch_ledgers(): get transfer event from Sub account to Main account on Main account
113
+
114
+ ## v1.4.0 2023-11-23
115
+ ### Update
116
+ * Some minor improvements
117
+
118
+ ## v1.4.0rc6 2023-11-11
119
+ ### Fix
120
+ * FetchOrder for Demo - ByBitSub01: BTCUSDT: 0 exception: list index out of range
121
+ * OKX: get ws_api endpoint from config
122
+ * ByBit: send and handling WSS keepalive message
123
+
124
+ ## v1.4.0rc3 2023-11-01
125
+ ### Fix
126
+ * websockets v12.0 raised `ConnectionClosed` exception
127
+ * Dependency: Up requirements for crypto-ws-api==2.0.5.post3
128
+
129
+ ## v1.4.0rc1 2023-10-31
130
+ ### Fix
131
+ * Bitfinex: WSS Information message processing logic adjusted
132
+
133
+ ### Update
134
+ * Dependency: Up requirements for crypto-ws-api==2.0.5
135
+ * Other dependency
136
+ * protobuf format for:
137
+ + OpenClientConnectionRequest
138
+ + FetchOrderRequest
139
+
140
+ ### Added for new features
141
+ * Bybit exchange V5 API support implemented. Supported account type is
142
+ [Unified Trading Account](https://testnet.bybit.com/en/help-center/article/Introduction-to-Bybit-Unified-Trading-Account),
143
+ for main and sub-accounts. Spot Trading only.
144
+
145
+ ## v1.3.7.post4 2023-10-09
146
+ ### Update
147
+ * Dependency: Up requirements for crypto-ws-api==2.0.4
148
+
149
+ ## v1.3.7.post3 2023-10-05
150
+ ### Update
151
+ * Dependency: Up requirements for crypto-ws-api==2.0.3.post1
152
+
153
+ ## v1.3.7.post2 2023-09-30
154
+ ### Update
155
+ * Dependency: Up requirements for crypto-ws-api==2.0.3
156
+
157
+ ## v1.3.7.post1 2023-09-24
158
+ ### Fix
159
+ * [2023-09-24 07:10:21,076: ERROR] Fetch order trades for HuobiSub2: HTUSDT exception: Client.fetch_order_trade_list()
160
+ missing 1 required positional argument: 'trade_id'
161
+ * exchanges_wrapper.huobi_parser.account_trade_list: incorrect key for `orderId`
162
+
163
+ ### Update
164
+ * Dependency: Up requirements for crypto-ws-api==2.0.2.post1
165
+
166
+ ## v1.3.7 2023-09-19
167
+ ### Fix
168
+ * Bitfinex: fix 500 `Internal server error`, caused by a Nonce value sequence failure
169
+
170
+ ### Update
171
+ * For web socket connection migrated from aiohttp.ws_connection to websockets.client
172
+ * Bitfinex: Implemented rate limit control for the Bitfinex REST API.
173
+ * Bitfinex: Refine handling of active orders
174
+ * OnOrderBookUpdate: change queue to LifoQueue, for get last actual order book row
175
+
176
+ ### Don't fix
177
+ * gRPC [(grpcio + grpcio-tools)](https://github.com/grpc/grpc): massive memory leak for version later than 1.48.2
178
+
179
+ ## v1.3.6b7 2023-08-20
180
+ ### Fix
181
+ * The `exch_srv_cfg.toml` wants to be updated from `exch_srv_cfg.toml.template`:
182
+ ```toml
183
+ [endpoint.okx]
184
+ api_public = 'https://aws.okx.com'
185
+ api_auth = 'https://aws.okx.com'
186
+ ws_public = 'wss://wsaws.okx.com:8443/ws/v5/public'
187
+ ws_auth = 'wss://wsaws.okx.com:8443/ws/v5/private'
188
+ ws_business = 'wss://ws.okx.com:8443/ws/v5/business'
189
+ api_test = 'https://aws.okx.com'
190
+ ws_test = 'wss://wspap.okx.com:8443/ws/v5/private?brokerId=9999'
191
+ ```
192
+
193
+ ## v1.3.6b4 2023-08-18
194
+ ### Fix
195
+ * [ Can't resolve missed PARTIALLY_FILLED event #29 ](https://github.com/DogsTailFarmer/exchanges-wrapper/issues/29#issue-1857179139)
196
+ * [ OKX changed WSS endpoint for Candlesticks channel #27 ](https://github.com/DogsTailFarmer/exchanges-wrapper/issues/27#issue-1852639540)
197
+
198
+ The `exch_srv_cfg.toml` wants to be updated from `exch_srv_cfg.toml.template`:
199
+ ```toml
200
+ [endpoint.okx]
201
+ api_public = 'https://aws.okx.com'
202
+ api_auth = 'https://aws.okx.com'
203
+ ws_public = 'wss://wsaws.okx.com:8443/ws/v5/public'
204
+ ws_business = 'wss://ws.okx.com:8443/ws/v5/business'
205
+ api_test = 'https://aws.okx.com'
206
+ ws_test = 'wss://wspap.okx.com:8443/ws/v5/private?brokerId=9999'
207
+ ```
208
+ ## v1.3.5rc1 2023-08-08
209
+ ### Update
210
+ * Dependency: Up requirements for crypto-ws-api~=2.0.0rc3
211
+ * Optimise code by [Sourcery AI](https://docs.sourcery.ai/Guides/Getting-Started/PyCharm/) refactoring engine
212
+ * Some minor improvements
213
+
214
+ ## v1.3.5b0 - 2023-07-26
215
+ ### Added for new features
216
+ * Binance, OKX: Most requests use WSS first, REST API is used as a backup and in the case of single rare requests
217
+
218
+ ## v1.3.4-1 2023-07-19
219
+ ### Fix
220
+ ```
221
+ ERROR: Cannot install crypto_ws_api and grpcio==1.56.0 because these package versions have conflicting dependencies.
222
+
223
+ The conflict is caused by:
224
+ The user requested grpcio==1.56.0
225
+ exchanges-wrapper 1.3.3 depends on grpcio==1.48.1
226
+ The user requested grpcio==1.56.0
227
+ exchanges-wrapper 1.3.2 depends on grpcio==1.48.1
228
+
229
+ ```
230
+
231
+ ## v1.3.4 2023-07-17
232
+ ### Update
233
+ * Up requirements for grpcio to 1.56.0
234
+ ```bazaar
235
+ Known security vulnerabilities detected
236
+ Dependency grpcio Version < 1.53.0 Upgrade to ~> 1.53.0
237
+ ```
238
+ * Bitfinex: `exchanges_wrapper.client.Client.cancel_all_orders()`: removed unnecessary status check after cancel request
239
+
240
+ ## v1.3.3 2023-07-04
241
+ ### Update
242
+ * UserWSSession moved to crypto-ws-api pkg
243
+ * Refactoring logging
244
+ * CheckStream(): fix log spamming on passed check
245
+ * Up requirements for crypto-ws-api to 1.0.1
246
+
247
+ ## v1.3.2 - 2023-06-29
248
+ ### Added for new features
249
+ * Binance: ws_api package implemented, last version
250
+ [Websocket API](https://developers.binance.com/docs/binance-trading-api/websocket_api#general-api-information)
251
+ used for the most commonly used methods
252
+
253
+ In `exch_srv_cfg.toml` added:
254
+
255
+ ```bazaar
256
+ [endpoint]
257
+ [endpoint.binance]
258
+ ...
259
+ ws_api = 'wss://ws-api.binance.com:443/ws-api/v3'
260
+ ws_api_test = 'wss://testnet.binance.vision/ws-api/v3'
261
+
262
+ ```
263
+
264
+ ## v1.3.1 - 2023-06-20
265
+ ### Update
266
+ * Optimizing installation and initial settings
267
+
268
+ ## v1.3.0-2 - 2023-06-19
269
+ ### Update
270
+ * Binance: keepalive WSS
271
+
272
+ ## v1.3.0 - 2023-06-01
273
+ ### Fix
274
+ * exchanges_wrapper.client.Client.cancel_all_orders() set correct 'status' for cancelled orders
275
+
276
+ ### Update
277
+ * protobuf format for CancelAllOrders() and OnOrderUpdate(). Now simple use ```result = eval(json.loads(res.result))```
278
+ for unpack incoming message. **Not compatible with earlier versions**
279
+ * dependencies
280
+
281
+ ## v1.2.10-6-HotFix - 2023-04-12
282
+ ### Fix
283
+ * Binance: REST API update for endpoint: GET /api/v3/exchangeInfo was changed MIN_NOTIONAL filter
284
+
285
+ ## v1.2.10-5 - 2023-04-05
286
+ ### Update
287
+ * Minor improvements
288
+
289
+ ## v1.2.10-4 - 2023-03-04
290
+ ### Fix
291
+ * OKX: intersection wss streams for several trades on one client (same account). WSS buffer moved from
292
+ client instance to EventsDataStream instance
293
+
294
+ ## v1.2.10-3 - 2023-03-01
295
+ ### Fix
296
+ * OKX: FetchOpenOrders(): getting orders list for all pair per account instead specific one pair
297
+
298
+ ## v1.2.10-2 - 2023-02-26
299
+ ### Added for new features
300
+ * CheckStream() method which request active WSS for trade_id
301
+
302
+ ## v1.2.10 - 2023-02-22
303
+ ### Added for new features
304
+ * Add method TransferToMaster():
305
+
306
+ >Send request to transfer asset from subaccount to main account
307
+ Binance, OKX: not additional settings needed
308
+ Bitfinex: for subaccount setting 2FA method, set WITHDRAWAL permission for API key,
309
+ in config for subaccount set 2FA key and master account EMail
310
+ Huobi: in config for subaccount set master_name for Main account
311
+
312
+ ### Update
313
+ * Up requirements aiohttp to 3.8.4
314
+ * Some minor improvements
315
+
316
+ ## v1.2.9-2 - 2023-02-04
317
+ ### Fixed
318
+ * Fix DogsTailFarmer/martin-binance#50
319
+
320
+ ### Update
321
+ * Remove unnecessary shebang
322
+
323
+ ## v1.2.9-1 - 2023-01-23
324
+ ### Update
325
+ * Additional check for order status if its can't place during timeout period for avoid place duplicate order
326
+
327
+ ## v1.2.9 - 2023-01-08
328
+ ### Update
329
+ * Removing FTX smell
330
+
331
+ ## v1.2.8 - 2023-01-01
332
+ ### Added for new features
333
+ * Add connection to binance.us
334
+
335
+ ## v1.2.7-7 2022-12-15
336
+ ### Fixed
337
+ * DogsTailFarmer/martin-binance#42
338
+
339
+ ## v1.2.7-6 2022-12-08
340
+ ### Fixed
341
+ * Bitfinex: handling canceled TP order after it partially filled
342
+
343
+ ### Update
344
+ * Binance: REST API: filter type "PERCENT_PRICE" to "PERCENT_PRICE_BY_SIDE"
345
+
346
+ ## v1.2.7-5 2022-12-04
347
+ ### Update
348
+ * FetchOpenOrders() add handler for errors.QueryCanceled, in case RateLimitReached was raised elsewhere
349
+ * Some minor improvements
350
+
351
+ ## v1.2.7-4 2022-11-25
352
+ ### Fixed
353
+ * Clearing cancel previous wss start() before restart from 1.2.7-3 was a bad idea. It's kill himself. Rollback.
354
+
355
+ ## v1.2.7-3 2022-11-24
356
+ ### Fixed
357
+ * Huobi: incorrect handling for incoming ping for private channel
358
+ * OKX: refactoring wss heartbeat
359
+ * Clearing cancel previous wss start() before restart
360
+
361
+ ## v1.2.7-2 2022-11-23
362
+ ### Update
363
+ * Bitfinex: add "receive_timeout=30" parameter in ws_connect(), this is a reliable solution for monitoring the presence
364
+ of a connection
365
+
366
+ ## v1.2.7-1 2022-11-21
367
+ ### Update
368
+ * Add OKX section in config file
369
+
370
+ ## v1.2.7 2022-11-21
371
+ ### Added for new features
372
+ * OKX exchange
373
+
374
+ ## v1.2.6-1 2022-11-11
375
+ ### Fixed
376
+ * FTX: OnFundsUpdate() did not return a result
377
+
378
+ ### Added for new features
379
+ * OnBalanceUpdate() for autocorrect depo and initial balance
380
+
381
+ ### Update
382
+ * refactoring http_client module for multi exchanges purposes
383
+ * added _percent_price filter dummy for all parsers
384
+
385
+ ## v1.2.6 2022-10-13
386
+ ### Fixed
387
+ * Huobi Restart WSS for PING timeout, 20s for market and 60s for user streams
388
+ * Removed unnecessary refine amount/price in create_order() for Bitfinex, FTX and Huobi
389
+
390
+ ## v1.2.6b1 2022-10-12
391
+ ### Added for new features
392
+ * Huobi exchange
393
+
394
+ ## v1.2.5-3 2022-09-26
395
+ ### Fixed
396
+ * #2 FTX WS market stream lies down quietly
397
+
398
+ ### Update
399
+ * Slightly optimized process of docker container setup and start-up
400
+
401
+ ## v1.2.5-2 2022-09-23
402
+ ### Added for new features
403
+ * Published as Docker image
404
+
405
+ ### Update
406
+ * README.md add info about Docker image use
407
+
408
+ ## v1.2.5-1 2022-09-21
409
+ ### Update
410
+ * Restoring the closed WSS for any reason other than forced explicit shutdown
411
+
412
+ ## v1.2.5 2022-09-20
413
+ ### Update
414
+ * Correct max size on queue() for book WSS
415
+
416
+ ## v1.2.5b0 2022-09-18
417
+ ### Fixed
418
+ * [Doesn't work on bitfinex: trading rules, step_size restriction not applicable, check](https://github.com/DogsTailFarmer/martin-binance/issues/28#issue-1366945816)
419
+ * [FTX WS market stream lies down quietly](https://github.com/DogsTailFarmer/exchanges-wrapper/issues/2#issue-1362214342) Refactoring WSS control
420
+ * Keep alive Binance combined market WSS, correct restart after stop pair
421
+
422
+ ### Update
423
+ * FetchOrder for 'PARTIALLY_FILLED' event on 'binance' and 'ftx'
424
+ * User data and settings config are moved outside the package to simplify the upgrade
425
+ * Version accounting of the configuration file is given to the package
426
+
427
+ ### Added for new features
428
+ * Published as Docker image
429
+ * On first run create catalog structure for user files at ```/home/user/.MartinBinance/```
430
+
431
+ ## v1.2.4 2022-08-27
432
+ ### Fixed
433
+ * [Incomplete account setup](DogsTailFarmer/martin-binance#17)
434
+ * 1.2.3-2 Fix wss market handler, was stopped after get int type message instead of dict
435
+ * 1.2.3-5 clear console output
436
+ * 1.2.3-6 Bitfinex WSServerHandshakeError handling
437
+ * refactoring web_socket.py for correct handling and restart wss
438
+
439
+ ### Update
440
+ * up to Python 3.10.6 compatible
441
+ * reuse aiohttp.ClientSession().ws_connect() for client session
442
+
443
+ ## v1.2.3 - 2022-08-14
444
+ ### Fixed
445
+ * Bitfinex: restore active orders list after restart
446
+ * [exch_server not exiting if it can't obtain port](https://github.com/DogsTailFarmer/martin-binance/issues/12#issue-1328603498)
447
+
448
+ ## v1.2.2 - 2022-08-06
449
+ ### Fixed
450
+ * Incorrect handling fetch_open_orders response after reinit connection
451
+
452
+ ## v1.2.1 - 2022-08-04
453
+ ### Added for new features
454
+ * FTX: WSS 'orderbook' check status by provided checksum value
455
+
456
+ ### Fixed
457
+ * FTX: WSS 'ticker' incorrect init
458
+ * Bitfinex: changed priority for order status, CANCELED priority raised
459
+
460
+
461
+ ## v1.2.0 - 2022-06-30
462
+ ### Added for new features
463
+ * Bitfinex REST API / WSS implemented
464
+
465
+ ### Updated
466
+ * Optimized WSS processing methods to improve performance and fault tolerance
467
+ * Updated configuration file format for multi-exchange use
@@ -0,0 +1,23 @@
1
+ # syntax=docker/dockerfile:1
2
+ FROM python:3.10.6-slim
3
+
4
+ RUN useradd -ms /bin/bash appuser
5
+ USER appuser
6
+
7
+ ENV PATH="/home/appuser/.local/bin:${PATH}"
8
+ ENV PATH="/home/appuser/.local/lib/python3.10/site-packages:${PATH}"
9
+ ENV PYTHONUNBUFFERED=1
10
+
11
+ COPY requirements.txt requirements.txt
12
+
13
+ RUN pip3 install -r requirements.txt
14
+
15
+ COPY ./exchanges_wrapper/* /home/appuser/.local/lib/python3.10/site-packages/exchanges_wrapper/
16
+
17
+ WORKDIR "/home/appuser/.local/lib/python3.10/site-packages"
18
+
19
+ LABEL org.opencontainers.image.description="See README.md 'Get started' for setup and run package"
20
+
21
+ EXPOSE 50051
22
+
23
+ CMD ["python3","exchanges_wrapper/exch_srv.py"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: exchanges-wrapper
3
- Version: 1.4.14
3
+ Version: 1.4.16
4
4
  Summary: REST API and WebSocket asyncio wrapper with grpc powered multiplexer server
5
5
  Author-email: Thomas Marchand <thomas.marchand@tuta.io>, Jerry Fedorenko <jerry.fedorenko@yahoo.com>
6
6
  Requires-Python: >=3.9
@@ -0,0 +1,422 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Client example for exchanges-wrapper, examples of use of server methods are given
5
+ """
6
+
7
+ import asyncio
8
+ import toml
9
+ import uuid
10
+ import simplejson as json
11
+ # noinspection PyPackageRequirements
12
+ import grpc
13
+ # noinspection PyPackageRequirements
14
+ from google.protobuf import json_format
15
+ from exchanges_wrapper import api_pb2, api_pb2_grpc
16
+
17
+ # For more channel options, please see https://grpc.io/grpc/core/group__grpc__arg__keys.html
18
+ CHANNEL_OPTIONS = [('grpc.lb_policy_name', 'pick_first'),
19
+ ('grpc.enable_retries', 0),
20
+ ('grpc.keepalive_timeout_ms', 10000)]
21
+ RATE_LIMITER = 5
22
+ FILE_CONFIG = 'ms_cfg.toml'
23
+ config = toml.load(FILE_CONFIG)
24
+ EXCHANGE = config.get('exchange')
25
+ SYMBOL = 'BTCUSDT'
26
+
27
+
28
+ async def main(_exchange, _symbol):
29
+ print(f"main.account_name: {_exchange}")
30
+ # Create connection to the grpc powered server
31
+ channel = grpc.aio.insecure_channel(target='localhost:50051', options=CHANNEL_OPTIONS)
32
+ stub = api_pb2_grpc.MartinStub(channel)
33
+ trade_id = str(uuid.uuid4().hex)
34
+ client_id = None
35
+ # Register client and get client_id for reuse connection
36
+ # Example of exception handling by grpc connection
37
+ try:
38
+ client_id_msg = await stub.OpenClientConnection(api_pb2.OpenClientConnectionRequest(
39
+ trade_id=trade_id,
40
+ account_name=_exchange,
41
+ symbol=SYMBOL,
42
+ rate_limiter=RATE_LIMITER))
43
+ except asyncio.CancelledError:
44
+ pass # Task cancellation should not be logged as an error.
45
+ except grpc.RpcError as ex:
46
+ # noinspection PyUnresolvedReferences
47
+ status_code = ex.code()
48
+ # noinspection PyUnresolvedReferences
49
+ print(f"Exception on register client: {status_code.name}, {ex.details()}")
50
+ return
51
+ else:
52
+ client_id = client_id_msg.client_id
53
+ exchange = client_id_msg.exchange
54
+ print(f"main.exchange: {exchange}")
55
+ print(f"main.client_id: {client_id}")
56
+ print(f"main.srv_version: {client_id_msg.srv_version}")
57
+
58
+ # _res = await stub.OneClickArrivalDeposit(api_pb2.MarketRequest(
59
+ # trade_id=trade_id,
60
+ # client_id=client_id,
61
+ # symbol="place txId here"))
62
+ # print(json_format.MessageToDict(_res))
63
+
64
+ # Sample async call server method
65
+ _exchange_info_symbol = await stub.FetchExchangeInfoSymbol(api_pb2.MarketRequest(
66
+ trade_id=trade_id,
67
+ client_id=client_id,
68
+ symbol=_symbol))
69
+ # Unpack result
70
+ exchange_info_symbol = json_format.MessageToDict(_exchange_info_symbol)
71
+ print("\n".join(f"{k}\t{v}" for k, v in exchange_info_symbol.items()))
72
+
73
+ # Sample async functon call
74
+ open_orders = await fetch_open_orders(stub, client_id, _symbol)
75
+ print(f"open_orders: {open_orders}")
76
+
77
+ # Subscribe to WSS
78
+ # First you want to create all WSS task
79
+ # Market stream
80
+ asyncio.create_task(on_ticker_update(stub, client_id, _symbol, trade_id))
81
+ # User Stream
82
+ asyncio.create_task(on_order_update(stub, client_id, _symbol, trade_id))
83
+ # Other market and user methods are used similarly: OnKlinesUpdate, OnFundsUpdate, OnOrderBookUpdate
84
+ # Start WSS
85
+ # The values of market_stream_count directly depend on the number of market
86
+ # ws streams used in the strategy and declared above
87
+ await stub.StartStream(api_pb2.StartStreamRequest(
88
+ trade_id=trade_id,
89
+ client_id=client_id,
90
+ symbol=_symbol,
91
+ market_stream_count=1))
92
+ await asyncio.sleep(RATE_LIMITER)
93
+ # Before stop program call StopStream() method
94
+ await stub.StopStream(api_pb2.MarketRequest(trade_id=trade_id, client_id=client_id, symbol=_symbol))
95
+
96
+
97
+ async def on_ticker_update(_stub, _client_id, _symbol, trade_id):
98
+ """
99
+ 24hr rolling window mini-ticker statistics. Truncated sample.
100
+ :param trade_id:
101
+ :param _stub:
102
+ :param _client_id:
103
+ :param _symbol:
104
+ :return: {}
105
+ """
106
+ async for ticker in _stub.OnTickerUpdate(api_pb2.MarketRequest(
107
+ trade_id=trade_id,
108
+ client_id=_client_id,
109
+ symbol=_symbol)):
110
+ ticker_24h = {'openPrice': ticker.open_price,
111
+ 'lastPrice': ticker.close_price,
112
+ 'closeTime': ticker.event_time}
113
+ print(f"on_ticker_update: {ticker.symbol} {ticker_24h}")
114
+
115
+
116
+ async def on_order_update(_stub, _client_id, _symbol, trade_id):
117
+ """
118
+ Orders are updated with the executionReport event.
119
+ :param trade_id:
120
+ :param _stub:
121
+ :param _client_id:
122
+ :param _symbol:
123
+ :return: https://github.com/binance/binance-spot-api-docs/blob/master/user-data-stream.md#order-update
124
+ """
125
+ async for event in _stub.OnOrderUpdate(api_pb2.MarketRequest(
126
+ trade_id=trade_id,
127
+ client_id=_client_id,
128
+ symbol=_symbol)):
129
+ print(eval(json.loads(event.result)))
130
+
131
+
132
+ async def on_balance_update(_stub, _client_id, _symbol, trade_id):
133
+ """
134
+ Get data when asset transferred or withdrawal from account
135
+ :param _stub:
136
+ :param _client_id:
137
+ :param _symbol:
138
+ :param trade_id:
139
+ :return:
140
+ """
141
+ async for res in _stub.OnBalanceUpdate(api_pb2.MarketRequest(
142
+ trade_id=trade_id,
143
+ client_id=_client_id,
144
+ symbol=_symbol)):
145
+ print(res.balance)
146
+
147
+
148
+ async def fetch_open_orders(_stub, _client_id, _symbol):
149
+ """
150
+ Get all open orders on a symbol.
151
+ :param _stub:
152
+ :param _client_id:
153
+ :param _symbol:
154
+ :return: https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#current-open-orders-user_data
155
+ """
156
+ _active_orders = await _stub.FetchOpenOrders(api_pb2.MarketRequest(client_id=_client_id, symbol=_symbol))
157
+ active_orders = json_format.MessageToDict(_active_orders).get('items', [])
158
+ print(f"active_orders: {active_orders}")
159
+ return active_orders
160
+
161
+
162
+ async def fetch_order(_stub, _client_id, _symbol, _id: int, _filled_update_call: bool = False):
163
+ """
164
+ Check an order's status.
165
+ :param _stub:
166
+ :param _client_id:
167
+ :param _symbol:
168
+ :param _id: order id
169
+ :param _filled_update_call: if True and order's status is 'FILLED' generated event for OnOrderUpdate user stream
170
+ :return: https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#query-order-user_data
171
+ """
172
+ try:
173
+ res = await _stub.FetchOrder(api_pb2.FetchOrderRequest(
174
+ client_id=_client_id,
175
+ symbol=_symbol,
176
+ order_id=_id,
177
+ filled_update_call=_filled_update_call))
178
+ result = json_format.MessageToDict(res)
179
+ except asyncio.CancelledError:
180
+ pass # Task cancellation should not be logged as an error.
181
+ except Exception as _ex:
182
+ print(f"Exception in fetch_order: {_ex}")
183
+ return {}
184
+ else:
185
+ print(f"For order {result.get('orderId')} fetched status is {result.get('status')}")
186
+ return result
187
+
188
+
189
+ async def cancel_all_orders(_stub, _client_id, _symbol):
190
+ """
191
+ Cancel All Open Orders on a Symbol
192
+ :param _stub:
193
+ :param _client_id:
194
+ :param _symbol:
195
+ :return:
196
+ https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#cancel-all-open-orders-on-a-symbol-trade
197
+ """
198
+ res = await _stub.CancelAllOrders(api_pb2.MarketRequest(
199
+ client_id=_client_id,
200
+ symbol=_symbol))
201
+ result = eval(json.loads(res.result))
202
+ print(f"cancel_all_orders.result: {result}")
203
+
204
+
205
+ async def fetch_account_information(_stub, _client_id):
206
+ """
207
+ Account information (USER_DATA)
208
+ :param _stub:
209
+ :param _client_id:
210
+ :return: https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#account-information-user_data
211
+ """
212
+ try:
213
+ res = await _stub.FetchAccountInformation(api_pb2.OpenClientConnectionId(client_id=_client_id))
214
+ except asyncio.CancelledError:
215
+ pass
216
+ except Exception as _ex:
217
+ print(f"Exception fetch_account_information: {_ex}")
218
+ else:
219
+ balances = json_format.MessageToDict(res).get('balances', [])
220
+ print(f"fetch_account_information.balances: {balances}")
221
+
222
+
223
+ async def fetch_funding_wallet(_stub, _client_id):
224
+ """
225
+ Get balances from Funding wallet for Binance and assets from 'main' account for FTX
226
+ :param _stub:
227
+ :param _client_id:
228
+ :return: https://binance-docs.github.io/apidocs/spot/en/#funding-wallet-user_data
229
+ """
230
+ try:
231
+ res = await _stub.FetchFundingWallet(api_pb2.FetchFundingWalletRequest(
232
+ client_id=_client_id))
233
+ except asyncio.CancelledError:
234
+ pass
235
+ except Exception as _ex:
236
+ print(f"fetch_funding_wallet: {_ex}")
237
+ else:
238
+ funding_wallet = json_format.MessageToDict(res).get('balances', [])
239
+ print(f"fetch_funding_wallet.funding_wallet: {funding_wallet}")
240
+
241
+
242
+ async def fetch_order_book(_stub, _client_id, _symbol):
243
+ """
244
+ Get order book, limit=5
245
+ :param _stub:
246
+ :param _client_id:
247
+ :param _symbol:
248
+ :return: https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#order-book
249
+ """
250
+ _order_book = await _stub.FetchOrderBook(api_pb2.MarketRequest(
251
+ client_id=_client_id,
252
+ symbol=_symbol))
253
+ order_book = json_format.MessageToDict(_order_book)
254
+ print(f"fetch_order_book.order_book: {order_book}")
255
+
256
+
257
+ async def fetch_symbol_price_ticker(_stub, _client_id, _symbol):
258
+ """
259
+ Get symbol price ticker
260
+ :param _stub:
261
+ :param _client_id:
262
+ :param _symbol:
263
+ :return: https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#symbol-price-ticker
264
+ """
265
+ _price = await _stub.FetchSymbolPriceTicker(api_pb2.MarketRequest(
266
+ client_id=_client_id,
267
+ symbol=_symbol))
268
+ price = json_format.MessageToDict(_price)
269
+ print(f"fetch_symbol_price_ticker.price: {price}")
270
+
271
+
272
+ async def fetch_ticker_price_change_statistics(_stub, _client_id, _symbol):
273
+ """
274
+ 24hr ticker price change statistics
275
+ :param _stub:
276
+ :param _client_id:
277
+ :param _symbol:
278
+ :return:
279
+ https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#24hr-ticker-price-change-statistics
280
+ """
281
+ _ticker = await _stub.FetchTickerPriceChangeStatistics(api_pb2.MarketRequest(
282
+ client_id=_client_id,
283
+ symbol=_symbol))
284
+ ticker = json_format.MessageToDict(_ticker)
285
+ print(f"fetch_ticker_price_change_statistics.ticker: {ticker}")
286
+
287
+
288
+ async def fetch_klines(_stub, _client_id, _symbol, _interval, _limit):
289
+ """
290
+ Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time.
291
+ :param _stub:
292
+ :param _client_id:
293
+ :param _symbol:
294
+ :param _interval: ENUM https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#enum-definitions
295
+ :param _limit: Default 500; max 1000.
296
+ :return: https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#klinecandlestick-data
297
+ """
298
+ res = await _stub.FetchKlines(api_pb2.FetchKlinesRequest(
299
+ client_id=_client_id,
300
+ symbol=_symbol,
301
+ interval=_interval,
302
+ limit=_limit))
303
+ kline = json_format.MessageToDict(res)
304
+ print(f"fetch_klines.kline: {kline}")
305
+
306
+
307
+ async def fetch_account_trade_list(_stub, _client_id, _symbol, _limit, _start_time_ms):
308
+ """
309
+ Get trades for a specific account and symbol.
310
+ :param _stub:
311
+ :param _client_id:
312
+ :param _symbol:
313
+ :param _limit: int: Default 500; max 1000
314
+ :param _start_time_ms: int: optional, minimum time of fills to return, in Unix time (ms since 1970-01-01)
315
+ :return: https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#account-trade-list-user_data
316
+ """
317
+ _trades = await _stub.FetchAccountTradeList(api_pb2.AccountTradeListRequest(
318
+ client_id=_client_id,
319
+ symbol=_symbol,
320
+ limit=_limit,
321
+ start_time=_start_time_ms)
322
+ )
323
+ trades = json_format.MessageToDict(_trades).get('items', [])
324
+ print(f"fetch_account_trade_list.trades: {trades}")
325
+
326
+
327
+ # noinspection PyUnresolvedReferences
328
+ async def transfer2master(_stub, symbol: str, amount: str):
329
+ """
330
+ Send request to transfer asset from subaccount to main account
331
+ Binance, OKX: not additional settings needed
332
+ Bitfinex: for subaccount setting 2FA method, set WITHDRAWAL permission for API key,
333
+ in config for subaccount set 2FA key and master account EMail
334
+ Huobi: in config for subaccount set master_name for Main account
335
+ :param _stub:
336
+ :param symbol:
337
+ :param amount:
338
+ :return:
339
+ """
340
+ try:
341
+ res = await _stub.TransferToMaster(api_pb2.MarketRequest, symbol=symbol, amount=amount)
342
+ except asyncio.CancelledError:
343
+ pass # Task cancellation should not be logged as an error
344
+ except grpc.RpcError as ex:
345
+ status_code = ex.code()
346
+ print(f"Exception transfer {symbol} to main account: {status_code.name}, {ex.details()}")
347
+ except Exception as _ex:
348
+ print(f"Exception transfer {symbol} to main account: {_ex}")
349
+ else:
350
+ if res.success:
351
+ print(f"Sent {amount} {symbol} to main account")
352
+ else:
353
+ print(f"Not sent {amount} {symbol} to main account\n,{res.result}")
354
+
355
+
356
+ # Server exception handling example for methods where it's realized
357
+ # noinspection PyUnresolvedReferences
358
+ async def create_limit_order(_stub, _client_id, _symbol, _id: int, buy: bool, amount: str, price: str):
359
+ """
360
+ Send in a new Limit order.
361
+ :param _stub:
362
+ :param _client_id:
363
+ :param _symbol:
364
+ :param _id: A unique id among open orders. Automatically generated if not sent
365
+ :param buy: True id BUY_side else False
366
+ :param amount: Base asset quantity
367
+ :param price:
368
+ :return: https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#new-order--trade
369
+ """
370
+ try:
371
+ res = await _stub.CreateLimitOrder(api_pb2.CreateLimitOrderRequest(
372
+ client_id=_client_id,
373
+ symbol=_symbol,
374
+ buy_side=buy,
375
+ quantity=amount,
376
+ price=price,
377
+ new_client_order_id=_id
378
+ ))
379
+ result = json_format.MessageToDict(res)
380
+ except asyncio.CancelledError:
381
+ pass # Task cancellation should not be logged as an error
382
+ except grpc.RpcError as ex:
383
+ status_code = ex.code()
384
+ print(f"Exception creating order {_id}: {status_code.name}, {ex.details()}")
385
+ if status_code == grpc.StatusCode.FAILED_PRECONDITION:
386
+ print("Do something. See except declare in exch_srv.CreateLimitOrder()")
387
+ except Exception as _ex:
388
+ print(f"Exception creating order {_id}: {_ex}")
389
+ else:
390
+ print(f"create_limit_order.result: {result}")
391
+
392
+
393
+ # Server exception handling example for methods where it's realized
394
+ # noinspection PyUnresolvedReferences
395
+ async def cancel_order(_stub, _client_id, _symbol, _id: int):
396
+ """
397
+ Cancel an active order.
398
+ :param _stub:
399
+ :param _client_id:
400
+ :param _symbol:
401
+ :param _id: exchange order id
402
+ :return: https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#cancel-order-trade
403
+ """
404
+ try:
405
+ res = await _stub.CancelOrder(api_pb2.CancelOrderRequest(
406
+ client_id=_client_id,
407
+ symbol=_symbol,
408
+ order_id=_id))
409
+ result = json_format.MessageToDict(res)
410
+ except asyncio.CancelledError:
411
+ pass # Task cancellation should not be logged as an error.
412
+ except grpc.RpcError as ex:
413
+ status_code = ex.code()
414
+ print(f"Exception on cancel order for {_id}: {status_code.name}, {ex.details()}")
415
+ except Exception as _ex:
416
+ print(f"Exception on cancel order call for {_id}:\n{_ex}")
417
+ else:
418
+ print(f"Cancel order {_id} success: {result}")
419
+
420
+
421
+ if __name__ == "__main__":
422
+ asyncio.run(main(EXCHANGE, SYMBOL))
@@ -0,0 +1,5 @@
1
+ # Example parameters for exchanges_wrapper/exch_client.py
2
+ # Accounts name wold be identically accounts.name from exch_srv_cfg.toml
3
+ # exchange = "Demo - Binance"
4
+ exchange = "Demo - Bitfinex"
5
+ # exchange = "Demo - OKX"
@@ -12,7 +12,7 @@ __maintainer__ = "Jerry Fedorenko"
12
12
  __contact__ = "https://github.com/DogsTailFarmer"
13
13
  __email__ = "jerry.fedorenko@yahoo.com"
14
14
  __credits__ = ["https://github.com/DanyaSWorlD"]
15
- __version__ = "1.4.14"
15
+ __version__ = "1.4.16"
16
16
 
17
17
  from pathlib import Path
18
18
  import shutil
@@ -832,7 +832,8 @@ class Martin(api_pb2_grpc.MartinServicer):
832
832
  iceberg_quantity=None,
833
833
  response_type=ResponseType.RESULT.value,
834
834
  receive_window=None,
835
- test=False)
835
+ test=False
836
+ )
836
837
  except errors.HTTPError as ex:
837
838
  logger.error(f"CreateLimitOrder for {open_client.name}:{request.symbol}:{request.new_client_order_id}"
838
839
  f" exception: {ex}")
@@ -845,11 +846,14 @@ class Martin(api_pb2_grpc.MartinServicer):
845
846
  _context.set_code(grpc.StatusCode.UNKNOWN)
846
847
  else:
847
848
  if not res and client.exchange in ('binance', 'huobi', 'okx'):
848
- res = await client.fetch_order(symbol=request.symbol,
849
- order_id=None,
850
- origin_client_order_id=request.new_client_order_id,
851
- receive_window=None,
852
- response_type=False)
849
+ res = await client.fetch_order(
850
+ trade_id=request.trade_id,
851
+ symbol=request.symbol,
852
+ order_id=None,
853
+ origin_client_order_id=request.new_client_order_id,
854
+ receive_window=None,
855
+ response_type=False
856
+ )
853
857
  json_format.ParseDict(res, response, ignore_unknown_fields=True)
854
858
  logger.debug(f"CreateLimitOrder: for {open_client.name}:{request.symbol}: created: {res.get('orderId')}")
855
859
  return response
@@ -38,17 +38,15 @@ class HttpClient:
38
38
  raise ExchangeError(f"An issue occurred on exchange's side: {response.status}: {response.url}:"
39
39
  f" {response.reason}")
40
40
  if response.status == 429:
41
- logger.error(f"handle_errors RateLimitReached:response.url: {response.url}")
41
+ logger.error(f"API RateLimitReached: {response.url}")
42
42
  self.rate_limit_reached = self.exchange in ('binance', 'okx')
43
43
  raise RateLimitReached(RateLimitReached.message)
44
+
44
45
  try:
45
46
  payload = await response.json()
46
47
  except aiohttp.ContentTypeError:
47
48
  payload = None
48
- if self.exchange == 'binance' and payload and "code" in payload:
49
- # as defined here: https://github.com/binance/binance-spot-api-docs/blob/
50
- # master/errors.md#error-codes-for-binance-2019-09-25
51
- raise ExchangeError(payload["msg"])
49
+
52
50
  if response.status >= 400:
53
51
  logger.debug(f"handle_errors.response: {response.text}")
54
52
  if response.status == 400 and payload and payload.get("error", str()) == "ERR_RATE_LIMIT":
@@ -59,16 +57,18 @@ class HttpClient:
59
57
  raise IPAddressBanned(IPAddressBanned.message)
60
58
  else:
61
59
  raise HTTPError(f"Malformed request: status: {response.status}, reason: {response.reason}")
62
- if self.exchange in ('binance', 'bitfinex'):
63
- return payload
64
- elif self.exchange == 'bybit' and payload and payload.get('retCode') == 0:
60
+
61
+ if self.exchange == 'bybit' and payload and payload.get('retCode') == 0:
65
62
  return payload.get('result'), payload.get('time')
66
63
  elif self.exchange == 'huobi' and payload and (payload.get('status') == 'ok' or payload.get('ok')):
67
64
  return payload.get('data', payload.get('tick'))
68
65
  elif self.exchange == 'okx' and payload and payload.get('code') == '0':
69
66
  return payload.get('data', [])
67
+ elif (self.exchange not in ('binance', 'bitfinex') or
68
+ (self.exchange == 'binance' and payload and "code" in payload)):
69
+ raise ExchangeError(f"API request failed: {response.status}:{response.reason}:{payload}")
70
70
  else:
71
- raise HTTPError(f"API request failed: {response.status}:{response.reason}:{payload}")
71
+ return payload
72
72
 
73
73
  async def send_api_call(self,
74
74
  path,
@@ -400,7 +400,7 @@ def on_order_update(_order: {}) -> {}:
400
400
  #
401
401
  if event.get('orderStatus') in ('canceled', 'partial-canceled'):
402
402
  status = 'CANCELED'
403
- elif event.get('orderStatus') == 'filled' and cumulative_filled_quantity >= Decimal(order_quantity):
403
+ elif cumulative_filled_quantity >= Decimal(order_quantity):
404
404
  status = 'FILLED'
405
405
  elif event.get('orderStatus') == 'partial-filled' or cumulative_filled_quantity > 0:
406
406
  status = 'PARTIALLY_FILLED'
@@ -0,0 +1,11 @@
1
+ crypto-ws-api==2.0.6
2
+ grpcio==1.48.2
3
+ grpcio-tools==1.48.2
4
+ pyotp==2.9.0
5
+ simplejson==3.19.2
6
+ toml~=0.10.2
7
+ aiohttp==3.9.1
8
+ Pympler~=1.0.1
9
+ websockets==12.0
10
+ expiringdict~=1.2.2
11
+ ujson~=5.9.0