ccxt 4.2.80__py2.py3-none-any.whl → 4.2.82__py2.py3-none-any.whl

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.
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.gate import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Balances, Currency, FundingHistory, Greeks, Int, Leverage, Leverages, Market, MarketInterface, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
+ from ccxt.base.types import Balances, Currency, FundingHistory, Greeks, Int, Leverage, Leverages, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import PermissionDenied
@@ -151,6 +151,8 @@ class gate(Exchange, ImplicitAPI):
151
151
  'fetchOpenInterest': False,
152
152
  'fetchOpenInterestHistory': True,
153
153
  'fetchOpenOrders': True,
154
+ 'fetchOption': True,
155
+ 'fetchOptionChain': True,
154
156
  'fetchOrder': True,
155
157
  'fetchOrderBook': True,
156
158
  'fetchPosition': True,
@@ -6688,6 +6690,186 @@ class gate(Exchange, ImplicitAPI):
6688
6690
  'shortLeverage': leverageValue,
6689
6691
  }
6690
6692
 
6693
+ async def fetch_option(self, symbol: str, params={}) -> Option:
6694
+ """
6695
+ fetches option data that is commonly found in an option chain
6696
+ :see: https://www.gate.io/docs/developers/apiv4/en/#query-specified-contract-detail
6697
+ :param str symbol: unified market symbol
6698
+ :param dict [params]: extra parameters specific to the exchange API endpoint
6699
+ :returns dict: an `option chain structure <https://docs.ccxt.com/#/?id=option-chain-structure>`
6700
+ """
6701
+ await self.load_markets()
6702
+ market = self.market(symbol)
6703
+ request = {
6704
+ 'contract': market['id'],
6705
+ }
6706
+ response = await self.publicOptionsGetContractsContract(self.extend(request, params))
6707
+ #
6708
+ # {
6709
+ # "is_active": True,
6710
+ # "mark_price_round": "0.01",
6711
+ # "settle_fee_rate": "0.00015",
6712
+ # "bid1_size": 30,
6713
+ # "taker_fee_rate": "0.0003",
6714
+ # "price_limit_fee_rate": "0.1",
6715
+ # "order_price_round": "0.1",
6716
+ # "tag": "month",
6717
+ # "ref_rebate_rate": "0",
6718
+ # "name": "ETH_USDT-20240628-4500-C",
6719
+ # "strike_price": "4500",
6720
+ # "ask1_price": "280.5",
6721
+ # "ref_discount_rate": "0",
6722
+ # "order_price_deviate": "0.2",
6723
+ # "ask1_size": -19,
6724
+ # "mark_price_down": "155.45",
6725
+ # "orderbook_id": 11724695,
6726
+ # "is_call": True,
6727
+ # "last_price": "188.7",
6728
+ # "mark_price": "274.26",
6729
+ # "underlying": "ETH_USDT",
6730
+ # "create_time": 1688024882,
6731
+ # "settle_limit_fee_rate": "0.1",
6732
+ # "orders_limit": 10,
6733
+ # "mark_price_up": "403.83",
6734
+ # "position_size": 80,
6735
+ # "order_size_max": 10000,
6736
+ # "position_limit": 100000,
6737
+ # "multiplier": "0.01",
6738
+ # "order_size_min": 1,
6739
+ # "trade_size": 229,
6740
+ # "underlying_price": "3326.6",
6741
+ # "maker_fee_rate": "0.0003",
6742
+ # "expiration_time": 1719561600,
6743
+ # "trade_id": 15,
6744
+ # "bid1_price": "269.3"
6745
+ # }
6746
+ #
6747
+ return self.parse_option(response, None, market)
6748
+
6749
+ async def fetch_option_chain(self, code: str, params={}) -> OptionChain:
6750
+ """
6751
+ fetches data for an underlying asset that is commonly found in an option chain
6752
+ :see: https://www.gate.io/docs/developers/apiv4/en/#list-all-the-contracts-with-specified-underlying-and-expiration-time
6753
+ :param str currency: base currency to fetch an option chain for
6754
+ :param dict [params]: extra parameters specific to the exchange API endpoint
6755
+ :param str [params.underlying]: the underlying asset, can be obtained from fetchUnderlyingAssets()
6756
+ :param int [params.expiration]: unix timestamp of the expiration time
6757
+ :returns dict: a list of `option chain structures <https://docs.ccxt.com/#/?id=option-chain-structure>`
6758
+ """
6759
+ await self.load_markets()
6760
+ currency = self.currency(code)
6761
+ request = {
6762
+ 'underlying': currency['code'] + '_USDT',
6763
+ }
6764
+ response = await self.publicOptionsGetContracts(self.extend(request, params))
6765
+ #
6766
+ # [
6767
+ # {
6768
+ # "is_active": True,
6769
+ # "mark_price_round": "0.1",
6770
+ # "settle_fee_rate": "0.00015",
6771
+ # "bid1_size": 434,
6772
+ # "taker_fee_rate": "0.0003",
6773
+ # "price_limit_fee_rate": "0.1",
6774
+ # "order_price_round": "1",
6775
+ # "tag": "day",
6776
+ # "ref_rebate_rate": "0",
6777
+ # "name": "BTC_USDT-20240324-63500-P",
6778
+ # "strike_price": "63500",
6779
+ # "ask1_price": "387",
6780
+ # "ref_discount_rate": "0",
6781
+ # "order_price_deviate": "0.15",
6782
+ # "ask1_size": -454,
6783
+ # "mark_price_down": "124.3",
6784
+ # "orderbook_id": 29600,
6785
+ # "is_call": False,
6786
+ # "last_price": "0",
6787
+ # "mark_price": "366.6",
6788
+ # "underlying": "BTC_USDT",
6789
+ # "create_time": 1711118829,
6790
+ # "settle_limit_fee_rate": "0.1",
6791
+ # "orders_limit": 10,
6792
+ # "mark_price_up": "630",
6793
+ # "position_size": 0,
6794
+ # "order_size_max": 10000,
6795
+ # "position_limit": 10000,
6796
+ # "multiplier": "0.01",
6797
+ # "order_size_min": 1,
6798
+ # "trade_size": 0,
6799
+ # "underlying_price": "64084.65",
6800
+ # "maker_fee_rate": "0.0003",
6801
+ # "expiration_time": 1711267200,
6802
+ # "trade_id": 0,
6803
+ # "bid1_price": "307"
6804
+ # },
6805
+ # ]
6806
+ #
6807
+ return self.parse_option_chain(response, None, 'name')
6808
+
6809
+ def parse_option(self, chain, currency: Currency = None, market: Market = None):
6810
+ #
6811
+ # {
6812
+ # "is_active": True,
6813
+ # "mark_price_round": "0.1",
6814
+ # "settle_fee_rate": "0.00015",
6815
+ # "bid1_size": 434,
6816
+ # "taker_fee_rate": "0.0003",
6817
+ # "price_limit_fee_rate": "0.1",
6818
+ # "order_price_round": "1",
6819
+ # "tag": "day",
6820
+ # "ref_rebate_rate": "0",
6821
+ # "name": "BTC_USDT-20240324-63500-P",
6822
+ # "strike_price": "63500",
6823
+ # "ask1_price": "387",
6824
+ # "ref_discount_rate": "0",
6825
+ # "order_price_deviate": "0.15",
6826
+ # "ask1_size": -454,
6827
+ # "mark_price_down": "124.3",
6828
+ # "orderbook_id": 29600,
6829
+ # "is_call": False,
6830
+ # "last_price": "0",
6831
+ # "mark_price": "366.6",
6832
+ # "underlying": "BTC_USDT",
6833
+ # "create_time": 1711118829,
6834
+ # "settle_limit_fee_rate": "0.1",
6835
+ # "orders_limit": 10,
6836
+ # "mark_price_up": "630",
6837
+ # "position_size": 0,
6838
+ # "order_size_max": 10000,
6839
+ # "position_limit": 10000,
6840
+ # "multiplier": "0.01",
6841
+ # "order_size_min": 1,
6842
+ # "trade_size": 0,
6843
+ # "underlying_price": "64084.65",
6844
+ # "maker_fee_rate": "0.0003",
6845
+ # "expiration_time": 1711267200,
6846
+ # "trade_id": 0,
6847
+ # "bid1_price": "307"
6848
+ # }
6849
+ #
6850
+ marketId = self.safe_string(chain, 'name')
6851
+ market = self.safe_market(marketId, market)
6852
+ timestamp = self.safe_timestamp(chain, 'create_time')
6853
+ return {
6854
+ 'info': chain,
6855
+ 'currency': None,
6856
+ 'symbol': market['symbol'],
6857
+ 'timestamp': timestamp,
6858
+ 'datetime': self.iso8601(timestamp),
6859
+ 'impliedVolatility': None,
6860
+ 'openInterest': None,
6861
+ 'bidPrice': self.safe_number(chain, 'bid1_price'),
6862
+ 'askPrice': self.safe_number(chain, 'ask1_price'),
6863
+ 'midPrice': None,
6864
+ 'markPrice': self.safe_number(chain, 'mark_price'),
6865
+ 'lastPrice': self.safe_number(chain, 'last_price'),
6866
+ 'underlyingPrice': self.safe_number(chain, 'underlying_price'),
6867
+ 'change': None,
6868
+ 'percentage': None,
6869
+ 'baseVolume': None,
6870
+ 'quoteVolume': None,
6871
+ }
6872
+
6691
6873
  def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
6692
6874
  if response is None:
6693
6875
  return None
@@ -50,7 +50,7 @@ class hyperliquid(Exchange, ImplicitAPI):
50
50
  'createMarketSellOrderWithCost': False,
51
51
  'createOrder': True,
52
52
  'createOrders': True,
53
- 'createReduceOnlyOrder': False,
53
+ 'createReduceOnlyOrder': True,
54
54
  'editOrder': True,
55
55
  'fetchAccounts': False,
56
56
  'fetchBalance': True,
@@ -851,7 +851,7 @@ class hyperliquid(Exchange, ImplicitAPI):
851
851
  orderType['limit'] = {
852
852
  'tif': timeInForce,
853
853
  }
854
- orderParams = self.omit(orderParams, ['clientOrderId', 'slippage', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'timeInForce', 'client_id'])
854
+ orderParams = self.omit(orderParams, ['clientOrderId', 'slippage', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'timeInForce', 'client_id', 'reduceOnly', 'postOnly'])
855
855
  orderObj = {
856
856
  'a': self.parse_to_int(market['baseId']),
857
857
  'b': isBuy,
@@ -1920,9 +1920,9 @@ class hyperliquid(Exchange, ImplicitAPI):
1920
1920
  userAux, params = self.handle_option_and_params(params, methodName, 'user')
1921
1921
  user = userAux
1922
1922
  user, params = self.handle_option_and_params(params, methodName, 'address', userAux)
1923
- if user is not None:
1923
+ if (user is not None) and (user != ''):
1924
1924
  return [user, params]
1925
- if self.walletAddress is not None:
1925
+ if (self.walletAddress is not None) and (self.walletAddress != ''):
1926
1926
  return [self.walletAddress, params]
1927
1927
  raise ArgumentsRequired(self.id + ' ' + methodName + '() requires a user parameter inside \'params\' or the wallet address set')
1928
1928
 
ccxt/async_support/okx.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.okx import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Account, Balances, Currency, Greeks, Int, Leverage, Market, MarketInterface, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
+ from ccxt.base.types import Account, Balances, Currency, Greeks, Int, Leverage, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import PermissionDenied
@@ -117,6 +117,8 @@ class okx(Exchange, ImplicitAPI):
117
117
  'fetchOpenInterestHistory': True,
118
118
  'fetchOpenOrder': None,
119
119
  'fetchOpenOrders': True,
120
+ 'fetchOption': True,
121
+ 'fetchOptionChain': True,
120
122
  'fetchOrder': True,
121
123
  'fetchOrderBook': True,
122
124
  'fetchOrderBooks': False,
@@ -1834,16 +1836,27 @@ class okx(Exchange, ImplicitAPI):
1834
1836
  first = self.safe_value(data, 0, {})
1835
1837
  return self.parse_ticker(first, market)
1836
1838
 
1837
- async def fetch_tickers_by_type(self, type, symbols: Strings = None, params={}):
1839
+ async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
1840
+ """
1841
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1842
+ :see: https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-tickers
1843
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1844
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1845
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
1846
+ """
1838
1847
  await self.load_markets()
1848
+ symbols = self.market_symbols(symbols)
1849
+ market = self.get_market_from_symbols(symbols)
1850
+ marketType = None
1851
+ marketType, params = self.handle_market_type_and_params('fetchTickers', market, params)
1839
1852
  request = {
1840
- 'instType': self.convert_to_instrument_type(type),
1853
+ 'instType': self.convert_to_instrument_type(marketType),
1841
1854
  }
1842
- if type == 'option':
1855
+ if marketType == 'option':
1843
1856
  defaultUnderlying = self.safe_value(self.options, 'defaultUnderlying', 'BTC-USD')
1844
1857
  currencyId = self.safe_string_2(params, 'uly', 'marketId', defaultUnderlying)
1845
1858
  if currencyId is None:
1846
- raise ArgumentsRequired(self.id + ' fetchTickersByType() requires an underlying uly or marketId parameter for options markets')
1859
+ raise ArgumentsRequired(self.id + ' fetchTickers() requires an underlying uly or marketId parameter for options markets')
1847
1860
  else:
1848
1861
  request['uly'] = currencyId
1849
1862
  response = await self.publicGetMarketTickers(self.extend(request, params))
@@ -1873,26 +1886,9 @@ class okx(Exchange, ImplicitAPI):
1873
1886
  # ]
1874
1887
  # }
1875
1888
  #
1876
- tickers = self.safe_value(response, 'data', [])
1889
+ tickers = self.safe_list(response, 'data', [])
1877
1890
  return self.parse_tickers(tickers, symbols)
1878
1891
 
1879
- async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
1880
- """
1881
- fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1882
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-tickers
1883
- :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1884
- :param dict [params]: extra parameters specific to the exchange API endpoint
1885
- :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
1886
- """
1887
- await self.load_markets()
1888
- symbols = self.market_symbols(symbols)
1889
- first = self.safe_string(symbols, 0)
1890
- market = None
1891
- if first is not None:
1892
- market = self.market(first)
1893
- type, query = self.handle_market_type_and_params('fetchTickers', market, params)
1894
- return await self.fetch_tickers_by_type(type, symbols, query)
1895
-
1896
1892
  def parse_trade(self, trade, market: Market = None) -> Trade:
1897
1893
  #
1898
1894
  # public fetchTrades
@@ -4439,18 +4435,7 @@ class okx(Exchange, ImplicitAPI):
4439
4435
  if fee is None:
4440
4436
  raise ArgumentsRequired(self.id + ' withdraw() requires a "fee" string parameter, network transaction fee must be ≥ 0. Withdrawals to OKCoin or OKX are fee-free, please set "0". Withdrawing to external digital asset address requires network transaction fee.')
4441
4437
  request['fee'] = self.number_to_string(fee) # withdrawals to OKCoin or OKX are fee-free, please set 0
4442
- if 'password' in params:
4443
- request['pwd'] = params['password']
4444
- elif 'pwd' in params:
4445
- request['pwd'] = params['pwd']
4446
- else:
4447
- options = self.safe_value(self.options, 'withdraw', {})
4448
- password = self.safe_string_2(options, 'password', 'pwd')
4449
- if password is not None:
4450
- request['pwd'] = password
4451
- query = self.omit(params, ['fee', 'password', 'pwd'])
4452
- if not ('pwd' in request):
4453
- raise ExchangeError(self.id + ' withdraw() requires a password parameter or a pwd parameter, it must be the funding password, not the API passphrase')
4438
+ query = self.omit(params, ['fee'])
4454
4439
  response = await self.privatePostAssetWithdrawal(self.extend(request, query))
4455
4440
  #
4456
4441
  # {
@@ -6927,6 +6912,139 @@ class okx(Exchange, ImplicitAPI):
6927
6912
  order = self.safe_value(data, 0)
6928
6913
  return self.parse_order(order, market)
6929
6914
 
6915
+ async def fetch_option(self, symbol: str, params={}) -> Option:
6916
+ """
6917
+ fetches option data that is commonly found in an option chain
6918
+ :see: https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-ticker
6919
+ :param str symbol: unified market symbol
6920
+ :param dict [params]: extra parameters specific to the exchange API endpoint
6921
+ :returns dict: an `option chain structure <https://docs.ccxt.com/#/?id=option-chain-structure>`
6922
+ """
6923
+ await self.load_markets()
6924
+ market = self.market(symbol)
6925
+ request = {
6926
+ 'instId': market['id'],
6927
+ }
6928
+ response = await self.publicGetMarketTicker(self.extend(request, params))
6929
+ #
6930
+ # {
6931
+ # "code": "0",
6932
+ # "msg": "",
6933
+ # "data": [
6934
+ # {
6935
+ # "instType": "OPTION",
6936
+ # "instId": "BTC-USD-241227-60000-P",
6937
+ # "last": "",
6938
+ # "lastSz": "0",
6939
+ # "askPx": "",
6940
+ # "askSz": "0",
6941
+ # "bidPx": "",
6942
+ # "bidSz": "0",
6943
+ # "open24h": "",
6944
+ # "high24h": "",
6945
+ # "low24h": "",
6946
+ # "volCcy24h": "0",
6947
+ # "vol24h": "0",
6948
+ # "ts": "1711176035035",
6949
+ # "sodUtc0": "",
6950
+ # "sodUtc8": ""
6951
+ # }
6952
+ # ]
6953
+ # }
6954
+ #
6955
+ result = self.safe_list(response, 'data', [])
6956
+ chain = self.safe_dict(result, 0, {})
6957
+ return self.parse_option(chain, None, market)
6958
+
6959
+ async def fetch_option_chain(self, code: str, params={}) -> OptionChain:
6960
+ """
6961
+ fetches data for an underlying asset that is commonly found in an option chain
6962
+ :see: https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-tickers
6963
+ :param str currency: base currency to fetch an option chain for
6964
+ :param dict [params]: extra parameters specific to the exchange API endpoint
6965
+ :param str [params.uly]: the underlying asset, can be obtained from fetchUnderlyingAssets()
6966
+ :returns dict: a list of `option chain structures <https://docs.ccxt.com/#/?id=option-chain-structure>`
6967
+ """
6968
+ await self.load_markets()
6969
+ currency = self.currency(code)
6970
+ request = {
6971
+ 'uly': currency['code'] + '-USD',
6972
+ 'instType': 'OPTION',
6973
+ }
6974
+ response = await self.publicGetMarketTickers(self.extend(request, params))
6975
+ #
6976
+ # {
6977
+ # "code": "0",
6978
+ # "msg": "",
6979
+ # "data": [
6980
+ # {
6981
+ # "instType": "OPTION",
6982
+ # "instId": "BTC-USD-240323-52000-C",
6983
+ # "last": "",
6984
+ # "lastSz": "0",
6985
+ # "askPx": "",
6986
+ # "askSz": "0",
6987
+ # "bidPx": "",
6988
+ # "bidSz": "0",
6989
+ # "open24h": "",
6990
+ # "high24h": "",
6991
+ # "low24h": "",
6992
+ # "volCcy24h": "0",
6993
+ # "vol24h": "0",
6994
+ # "ts": "1711176207008",
6995
+ # "sodUtc0": "",
6996
+ # "sodUtc8": ""
6997
+ # },
6998
+ # ]
6999
+ # }
7000
+ #
7001
+ result = self.safe_list(response, 'data', [])
7002
+ return self.parse_option_chain(result, None, 'instId')
7003
+
7004
+ def parse_option(self, chain, currency: Currency = None, market: Market = None):
7005
+ #
7006
+ # {
7007
+ # "instType": "OPTION",
7008
+ # "instId": "BTC-USD-241227-60000-P",
7009
+ # "last": "",
7010
+ # "lastSz": "0",
7011
+ # "askPx": "",
7012
+ # "askSz": "0",
7013
+ # "bidPx": "",
7014
+ # "bidSz": "0",
7015
+ # "open24h": "",
7016
+ # "high24h": "",
7017
+ # "low24h": "",
7018
+ # "volCcy24h": "0",
7019
+ # "vol24h": "0",
7020
+ # "ts": "1711176035035",
7021
+ # "sodUtc0": "",
7022
+ # "sodUtc8": ""
7023
+ # }
7024
+ #
7025
+ marketId = self.safe_string(chain, 'instId')
7026
+ market = self.safe_market(marketId, market)
7027
+ timestamp = self.safe_integer(chain, 'ts')
7028
+ return {
7029
+ 'info': chain,
7030
+ 'currency': None,
7031
+ 'symbol': market['symbol'],
7032
+ 'timestamp': timestamp,
7033
+ 'datetime': self.iso8601(timestamp),
7034
+ 'impliedVolatility': None,
7035
+ 'openInterest': None,
7036
+ 'bidPrice': self.safe_number(chain, 'bidPx'),
7037
+ 'askPrice': self.safe_number(chain, 'askPx'),
7038
+ 'midPrice': None,
7039
+ 'markPrice': None,
7040
+ 'lastPrice': self.safe_number(chain, 'last'),
7041
+ 'underlyingPrice': None,
7042
+ 'change': None,
7043
+ 'percentage': None,
7044
+ 'baseVolume': self.safe_number(chain, 'volCcy24h'),
7045
+ 'quoteVolume': None,
7046
+ }
7047
+
6930
7048
  def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
6931
7049
  if not response:
6932
7050
  return None # fallback to default error handler
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.2.80'
7
+ __version__ = '4.2.82'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
ccxt/binance.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.binance import ImplicitAPI
8
8
  import hashlib
9
9
  import json
10
- from ccxt.base.types import Balances, Currency, Greeks, Int, Leverage, Leverages, MarginMode, MarginModes, Market, MarketInterface, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
+ from ccxt.base.types import Balances, Currency, Greeks, Int, Leverage, Leverages, MarginMode, MarginModes, Market, MarketInterface, Num, Option, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import PermissionDenied
@@ -133,6 +133,8 @@ class binance(Exchange, ImplicitAPI):
133
133
  'fetchOpenInterestHistory': True,
134
134
  'fetchOpenOrder': True,
135
135
  'fetchOpenOrders': True,
136
+ 'fetchOption': True,
137
+ 'fetchOptionChain': False,
136
138
  'fetchOrder': True,
137
139
  'fetchOrderBook': True,
138
140
  'fetchOrderBooks': False,
@@ -11410,3 +11412,89 @@ class binance(Exchange, ImplicitAPI):
11410
11412
  'symbol': market['symbol'],
11411
11413
  'marginMode': 'isolated' if isIsolated else 'cross',
11412
11414
  }
11415
+
11416
+ def fetch_option(self, symbol: str, params={}) -> Option:
11417
+ """
11418
+ fetches option data that is commonly found in an option chain
11419
+ :see: https://binance-docs.github.io/apidocs/voptions/en/#24hr-ticker-price-change-statistics
11420
+ :param str symbol: unified market symbol
11421
+ :param dict [params]: extra parameters specific to the exchange API endpoint
11422
+ :returns dict: an `option chain structure <https://docs.ccxt.com/#/?id=option-chain-structure>`
11423
+ """
11424
+ self.load_markets()
11425
+ market = self.market(symbol)
11426
+ request = {
11427
+ 'symbol': market['id'],
11428
+ }
11429
+ response = self.eapiPublicGetTicker(self.extend(request, params))
11430
+ #
11431
+ # [
11432
+ # {
11433
+ # "symbol": "BTC-241227-80000-C",
11434
+ # "priceChange": "0",
11435
+ # "priceChangePercent": "0",
11436
+ # "lastPrice": "2750",
11437
+ # "lastQty": "0",
11438
+ # "open": "2750",
11439
+ # "high": "2750",
11440
+ # "low": "2750",
11441
+ # "volume": "0",
11442
+ # "amount": "0",
11443
+ # "bidPrice": "4880",
11444
+ # "askPrice": "0",
11445
+ # "openTime": 0,
11446
+ # "closeTime": 0,
11447
+ # "firstTradeId": 0,
11448
+ # "tradeCount": 0,
11449
+ # "strikePrice": "80000",
11450
+ # "exercisePrice": "63944.09893617"
11451
+ # }
11452
+ # ]
11453
+ #
11454
+ chain = self.safe_dict(response, 0, {})
11455
+ return self.parse_option(chain, None, market)
11456
+
11457
+ def parse_option(self, chain, currency: Currency = None, market: Market = None):
11458
+ #
11459
+ # {
11460
+ # "symbol": "BTC-241227-80000-C",
11461
+ # "priceChange": "0",
11462
+ # "priceChangePercent": "0",
11463
+ # "lastPrice": "2750",
11464
+ # "lastQty": "0",
11465
+ # "open": "2750",
11466
+ # "high": "2750",
11467
+ # "low": "2750",
11468
+ # "volume": "0",
11469
+ # "amount": "0",
11470
+ # "bidPrice": "4880",
11471
+ # "askPrice": "0",
11472
+ # "openTime": 0,
11473
+ # "closeTime": 0,
11474
+ # "firstTradeId": 0,
11475
+ # "tradeCount": 0,
11476
+ # "strikePrice": "80000",
11477
+ # "exercisePrice": "63944.09893617"
11478
+ # }
11479
+ #
11480
+ marketId = self.safe_string(chain, 'symbol')
11481
+ market = self.safe_market(marketId, market)
11482
+ return {
11483
+ 'info': chain,
11484
+ 'currency': None,
11485
+ 'symbol': market['symbol'],
11486
+ 'timestamp': None,
11487
+ 'datetime': None,
11488
+ 'impliedVolatility': None,
11489
+ 'openInterest': None,
11490
+ 'bidPrice': self.safe_number(chain, 'bidPrice'),
11491
+ 'askPrice': self.safe_number(chain, 'askPrice'),
11492
+ 'midPrice': None,
11493
+ 'markPrice': None,
11494
+ 'lastPrice': self.safe_number(chain, 'lastPrice'),
11495
+ 'underlyingPrice': self.safe_number(chain, 'exercisePrice'),
11496
+ 'change': self.safe_number(chain, 'priceChange'),
11497
+ 'percentage': self.safe_number(chain, 'priceChangePercent'),
11498
+ 'baseVolume': self.safe_number(chain, 'volume'),
11499
+ 'quoteVolume': None,
11500
+ }
ccxt/bitrue.py CHANGED
@@ -421,7 +421,7 @@ class bitrue(Exchange, ImplicitAPI):
421
421
  '-1022': AuthenticationError, # {"code":-1022,"msg":"Signature for self request is not valid."}
422
422
  '-1100': BadRequest, # createOrder(symbol, 1, asdf) -> 'Illegal characters found in parameter 'price'
423
423
  '-1101': BadRequest, # Too many parameters; expected %s and received %s.
424
- '-1102': BadRequest, # Param %s or %s must be sent, but both were empty
424
+ '-1102': BadRequest, # Param %s or %s must be sent, but both were empty # {"code":-1102,"msg":"timestamp IllegalArgumentException.","data":null}
425
425
  '-1103': BadRequest, # An unknown parameter was sent.
426
426
  '-1104': BadRequest, # Not all sent parameters were read, read 8 parameters but was sent 9
427
427
  '-1105': BadRequest, # Parameter %s was empty.