Skip to content

Commit

Permalink
v1.0.13: Add order update v2 subscription
Browse files Browse the repository at this point in the history
  • Loading branch information
eynzhang committed Apr 21, 2020
1 parent b1d3872 commit 512670d
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 41 deletions.
43 changes: 8 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,9 @@ This is Huobi Python SDK, This is a lightweight python library, you can import t

The SDK supports both synchronous RESTful API invoking, and subscribe the market data from the Websocket connection.

## Huobi Python SDK Releases

## Huobi Python SDK (change log)
[Python SDK Change Log](https://github.com/HuobiRDCenter/huobi_Python/blob/master/CHANGE_LOG.md)

## Huobi Python SDK Download

- [Huobi Global API Python SDK version 1.0.12](https://github.com/HuobiRDCenter/huobi_Python/releases/tag/1.0.12)

- [Huobi Global API Python SDK version 1.0.11](https://github.com/HuobiRDCenter/huobi_Python/releases/tag/1.0.11)

- [Huobi Global API Python SDK version 1.0.10](https://github.com/HuobiRDCenter/huobi_Python/releases/tag/1.0.10)

- [Huobi Global API Python SDK version 1.0.9](https://github.com/HuobiRDCenter/huobi_Python/releases/tag/1.0.9)

- [Huobi Global API Python SDK version 1.0.8](https://github.com/HuobiRDCenter/huobi_Python/releases/tag/1.0.8)

- [Huobi Global API Python SDK version 1.0.7](https://github.com/HuobiRDCenter/huobi_Python/releases/tag/1.0.7)

- [Huobi Global API Python SDK version 1.0.6](https://github.com/HuobiRDCenter/huobi_Python/releases/tag/1.0.6)

- [Huobi Global API Python SDK version 1.0.5](https://github.com/HuobiRDCenter/huobi_Python/releases/tag/1.0.5)

- [Huobi Global API Python SDK version 1.0.4](https://github.com/HuobiRDCenter/huobi_Python/releases/tag/1.0.4)

- [Huobi Global API Python SDK version 1.0.3](https://github.com/HuobiRDCenter/huobi_Python/releases/tag/1.0.3)

- [Huobi Global API Python SDK version 1.0.2](https://github.com/HuobiRDCenter/huobi_Python/releases/tag/1.0.2)

- [Huobi Global API Python SDK version 1.0.1](https://github.com/HuobiRDCenter/huobi_Python/releases/tag/1.0.1)
Go to [Releases](https://github.com/HuobiRDCenter/huobi_Python/releases) page to view and download each release.


## Table of Contents
Expand Down Expand Up @@ -510,27 +484,26 @@ def callback(candlestick_event: 'CandlestickEvent'):
subscription_client.subscribe_candlestick_event("btcusdt", CandlestickInterval.MIN15, callback)
```

### Subscribe order update
### Subscribe orders update

*Authentication is required.*

```python
def callback(order_update_event: 'OrderUpdateEvent'):
def callback(order_update_event: 'OrdersUpdateEvent'):
print(order_update_event.data.price)

subscription_client.subscribe_order_update_event("btcusdt", callback)
subscription_client.subscribe_orders_update_event("btcusdt", callback)
```

### Subscribe account change

*Authentication is required.*

```python
def callback(account_event: 'AccountEvent'):
for change in account_event.account_change_list:
print(change.account_type)
def callback(account_event: 'AccountsUpdateEvent'):
account_event.print_object()

subscription_client.subscribe_account_event(BalanceMode.TOTAL, callback)
subscription_client.subscribe_accounts_update_event(AccountBalanceMode.TOTAL, callback)
```

### Unsubscribe
Expand Down
2 changes: 1 addition & 1 deletion example/restful/posttransferbetweenfuturespro.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
request_client = RequestClient(api_key="xxxxxx", secret_key="xxxxxx")

trans_id_one = request_client.transfer_between_futures_and_pro(amount=0.35, currency="eos",
transfer_type=TransferFuturesPro.TO_FETURES)
transfer_type=TransferFuturesPro.TO_FUTURES)
print (trans_id_one)
trans_id_two = request_client.transfer_between_futures_and_pro(amount=0.35, currency="eos",
transfer_type=TransferFuturesPro.TO_PRO)
Expand Down
24 changes: 24 additions & 0 deletions example/subscribe/subscribeordersupdate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import logging
from huobi import SubscriptionClient
from huobi.constant.test import *

logger = logging.getLogger("huobi-client")
logger.setLevel(level=logging.INFO)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
logger.addHandler(handler)

sub_client = SubscriptionClient(api_key=g_api_key, secret_key=g_secret_key)


def callback(orders_update_event: 'OrderUpdateV2Event'):
print("---- orders update : ----")
orders_update_event.print_object()
print()


def error(e: 'HuobiApiException'):
print(e.error_code + e.error_message)


sub_client.subscribe_orders_update_event("hthusd", callback, error)
1 change: 1 addition & 0 deletions huobi/constant/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class OutputKey:
KeyTick = "tick"
KeyChannelCh = "ch"
KeyChannelRep = "rep"
KeyAction = "action"



Expand Down
6 changes: 6 additions & 0 deletions huobi/impl/utils/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ def full_mbp_channel(symbol, levels):
channel["id"] = str(get_current_timestamp())
return json.dumps(channel)

def orders_update_channel(symbol):
channel = dict()
channel["action"] = "sub"
channel["ch"] = "orders#{symbol}".format(symbol=symbol)
return json.dumps(channel)

def price_depth_bbo_channel(symbol):
channel = dict()
channel["sub"] = "market." + symbol + ".bbo"
Expand Down
19 changes: 18 additions & 1 deletion huobi/impl/websocketrequestimplv2.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from huobi.impl.utils.channels import *
from huobi.impl.utils.inputchecker import *
from huobi.model import *

from huobi.model.ordersupdateevent import OrdersUpdateEvent


class WebsocketRequestImplV2(object):
Expand Down Expand Up @@ -54,4 +54,21 @@ def subscription_handler(connection):
request.update_callback = callback
request.error_handler = error_handler
request.api_version = ApiVersion.VERSION_V2
return request

def subscribe_orders_update_event(self, symbol, callback, error_handler=None):
check_should_not_none(symbol, "symbol")
check_should_not_none(callback, "callback")

def subscription_handler(connection):
connection.send(orders_update_channel(symbol))

request = WebsocketRequest()
request.subscription_handler = subscription_handler
request.auto_close = False
request.is_trading = True
request.json_parser = OrdersUpdateEvent.json_parse
request.update_callback = callback
request.error_handler = error_handler
request.api_version = ApiVersion.VERSION_V2
return request
22 changes: 20 additions & 2 deletions huobi/model/constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class WithdrawState:
REPEALED = "repealed"
INVALID = None


class DepositWithdraw:
DEPOSIT = "deposit"
WITHDRAW = "withdraw"
Expand Down Expand Up @@ -183,29 +184,35 @@ class BalanceMode:
TOTAL = "1"
INVALID = None


class AccountBalanceMode:
BALANCE = "0"
TOTAL = "1"
INVALID = None


class OperateMode:
PING = "ping"
PONG = "pong"
INVALID = None


class QueryDirection:
PREV = "prev"
NEXT = "next"
INVALID = None


class TransferFuturesPro:
TO_PRO = "futures-to-pro"
TO_FETURES ="pro-to-futures"
TO_FUTURES = "pro-to-futures"


class MatchRole:
MAKER = "maker"
TAKER = "taker"


class DepthStep:
STEP0 = "step0"
STEP1 = "step1"
Expand All @@ -227,16 +234,19 @@ class ChainDepositStatus:
PROHIBITED = "prohibited"
INVALID = None


class ChainWithdrawStatus:
ALLOWED = "allowed"
PROHIBITED = "prohibited"
INVALID = None


class InstrumentStatus:
NORMAL = "normal"
DELISTED = "delisted"
INVALID = None


class AccountChangeType:
ORDER_PLACE = "order-place"
ORDER_MATCH = "order-match"
Expand All @@ -250,6 +260,7 @@ class AccountChangeType:
OTHER = "other"
INVALID = None


class FeeDeductType:
DEDUCT_BY_HT = "ht"
DEDUCT_BY_POINT = "point"
Expand All @@ -259,4 +270,11 @@ class FeeDeductType:
class SubUidState:
UNLOCK = "unlock"
LOCK = "lock"
INVALID = None
INVALID = None


class OrderUpdateEventType:
CREATION = "creation"
TRADE = "trade"
CANCELLATION = "cancellation"
INVALID = None
75 changes: 75 additions & 0 deletions huobi/model/ordersupdate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from huobi.model import OrderType, OrderState, OrderUpdateEventType


class OrdersUpdate:

def __init__(self):
self.eventType = OrderUpdateEventType.INVALID
self.symbol = ""
self.orderId = 0
self.clientOrderId = ""
self.type = OrderType.INVALID
self.orderStatus = OrderState.INVALID
self.orderPrice = ""
self.orderSize = ""
self.orderCreateTime = 0
self.tradeId = 0
self.tradePrice = ""
self.tradeVolume = ""
self.tradeTime = 0
self.aggressor = False
self.remainAmt = ""
self.lastActTime = 0

@staticmethod
def json_parse(json_data):
obj = OrdersUpdate()
obj.eventType = json_data.get_string("eventType")
obj.symbol = json_data.get_string("symbol")
obj.orderId = json_data.get_int("orderId")
obj.clientOrderId = json_data.get_string("clientOrderId")
obj.orderStatus = json_data.get_string("orderStatus")

if obj.eventType == OrderUpdateEventType.CREATION:
obj.type = json_data.get_string_or_default("type", OrderType.INVALID)
obj.orderPrice = json_data.get_string_or_default("orderPrice", "")
obj.orderSize = json_data.get_string_or_default("orderSize", "")
obj.orderCreateTime = json_data.get_int_or_default("orderCreateTime", 0)

if obj.eventType == OrderUpdateEventType.TRADE:
obj.tradeId = json_data.get_int_or_default("tradeId", 0)
obj.tradePrice = json_data.get_string_or_default("tradePrice", "")
obj.tradeVolume = json_data.get_string_or_default("tradeVolume", "")
obj.tradeTime = json_data.get_int_or_default("tradeTime", 0)
obj.aggressor = json_data.get_boolean("aggressor", False)
obj.remainAmt = json_data.get_string_or_default("remainAmt", "")

if obj.eventType == OrderUpdateEventType.TRADE:
obj.lastActTime = json_data.get_int_or_default("lastActTime", 0)

return obj

def print_object(self, format_data=""):
from huobi.base.printobject import PrintBasic
PrintBasic.print_basic(self.eventType, format_data + "Event Type")
PrintBasic.print_basic(self.symbol, format_data + "Symbol")
PrintBasic.print_basic(self.orderId, format_data + "Order Id")
PrintBasic.print_basic(self.clientOrderId, format_data + "Client Order Id")
PrintBasic.print_basic(self.orderStatus, format_data + "order Status")

if self.eventType == OrderUpdateEventType.CREATION:
PrintBasic.print_basic(self.type, format_data + "Type")
PrintBasic.print_basic(self.orderPrice, format_data + "order Price")
PrintBasic.print_basic(self.orderSize, format_data + "order Size")
PrintBasic.print_basic(self.orderCreateTime, format_data + "Order Create Time")

if self.eventType == OrderUpdateEventType.TRADE:
PrintBasic.print_basic(self.tradeId, format_data + "Trade Id")
PrintBasic.print_basic(self.tradePrice, format_data + "Trade Price")
PrintBasic.print_basic(self.tradeVolume, format_data + "Trade Volume")
PrintBasic.print_basic(self.tradeTime, format_data + "Trade Time")
PrintBasic.print_basic(self.aggressor, format_data + "is aggressor")
PrintBasic.print_basic(self.remainAmt, format_data + "Remain Amount")

if self.eventType == OrderUpdateEventType.CANCELLATION:
PrintBasic.print_basic(self.lastActTime, format_data + "Last Activity Time")
34 changes: 34 additions & 0 deletions huobi/model/ordersupdateevent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from huobi.constant.result import OutputKey
from huobi.impl.utils.channelparser import ChannelParser
from huobi.model import Mbp
from huobi.model.ordersupdate import OrdersUpdate


class OrdersUpdateEvent:
"""
The order update received by subscription of order update.
"""

def __init__(self):
self.action = ""
self.code = 200
self.ch = ""
self.data = OrdersUpdate()

@staticmethod
def json_parse(json_wrapper):
action = json_wrapper.get_string(OutputKey.KeyAction)
ch = json_wrapper.get_string(OutputKey.KeyChannelCh)
data = json_wrapper.get_object(OutputKey.KeyData)

order_update_v2_event = OrdersUpdateEvent()
order_update_v2_event.action = action
order_update_v2_event.ch = ch
order_update_v2_event.data = OrdersUpdate.json_parse(data)
return order_update_v2_event

def print_object(self, format_data=""):
from huobi.base.printobject import PrintBasic
PrintBasic.print_basic(self.ch, format_data + "Channel")
self.data.print_object()
16 changes: 16 additions & 0 deletions huobi/subscriptionclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,22 @@ def request_mbp_event(self, symbols: 'str', level: 'int', callback, auto_close =
auto_close, error_handler)
self.__create_connection(request)

def subscribe_orders_update_event(self, symbol: 'str', callback, error_handler=None):
"""
Subscribe trade clearing by symbol
:param symbol: The symbol, like "btcusdt".
:param callback: The implementation is required. onReceive will be called if receive server's update.
example: def callback(price_depth_event: 'PriceDepthEvent'):
pass
:param error_handler: The error handler will be called if subscription failed or error happen between client and Huobi server
example: def error_handler(exception: 'HuobiApiException')
pass
:return: No return
"""
request = self.websocket_request_impl_v2.subscribe_orders_update_event(symbol, callback, error_handler)
self.__create_connection(request)

def subscribe_trade_clearing_event(self, symbols: 'str', callback, error_handler=None):
"""
Expand Down
2 changes: 1 addition & 1 deletion performance/testcase.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ def test_transfer(self):
result, tc.server_req_cost, tc.server_api_cost = self.test_client.transfer_between_futures_and_pro(
currency="trx",
amount=transfer_trx_amount,
transfer_type=TransferFuturesPro.TO_FETURES)
transfer_type=TransferFuturesPro.TO_FUTURES)
tc.run_status = RunStatus.SUCCESS if result else RunStatus.FAILED
tc.add_record()

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

setup(
name="huobi-client",
version="1.0.12",
version="1.0.13",
packages=['huobi', 'huobi.impl', 'huobi.impl.utils', 'huobi.exception', 'huobi.model', 'huobi.base', 'huobi.constant',
"performance", "tests", "huobi.demo_service", "huobi.demo_service.mbp"],
install_requires=['requests', 'apscheduler', 'websocket-client', 'urllib3']
Expand Down

0 comments on commit 512670d

Please sign in to comment.