2022-04-14 08:06:36 +00:00
|
|
|
from __future__ import annotations
|
|
|
|
|
2022-04-14 07:36:29 +00:00
|
|
|
from typing import Iterator
|
2022-03-07 04:06:16 +00:00
|
|
|
from typing import List
|
2022-04-16 14:52:43 +00:00
|
|
|
|
|
|
|
from loguru import logger
|
2022-03-07 04:06:16 +00:00
|
|
|
|
2022-04-09 18:00:01 +00:00
|
|
|
import bbgo_pb2
|
|
|
|
import bbgo_pb2_grpc
|
2022-03-07 04:06:16 +00:00
|
|
|
|
2022-04-13 06:52:34 +00:00
|
|
|
from .data import ErrorMessage
|
|
|
|
from .data import KLine
|
2022-04-14 07:36:29 +00:00
|
|
|
from .data import MarketDataEvent
|
2022-04-16 14:52:43 +00:00
|
|
|
from .data import Order
|
|
|
|
from .data import SubmitOrder
|
2022-04-13 09:40:21 +00:00
|
|
|
from .data import Subscription
|
2022-04-14 07:36:29 +00:00
|
|
|
from .data import UserDataEvent
|
2022-04-16 14:52:43 +00:00
|
|
|
from .enums import OrderType
|
|
|
|
from .enums import SideType
|
2022-04-14 08:06:36 +00:00
|
|
|
from .utils import get_insecure_channel
|
2022-04-13 06:52:34 +00:00
|
|
|
|
2022-03-07 04:06:16 +00:00
|
|
|
|
2022-04-09 09:30:13 +00:00
|
|
|
class UserDataService(object):
|
2022-04-14 08:06:36 +00:00
|
|
|
stub: bbgo_pb2_grpc.UserDataServiceStub
|
2022-04-09 09:30:13 +00:00
|
|
|
|
2022-04-14 08:06:36 +00:00
|
|
|
def __init__(self, host: str, port: int) -> None:
|
|
|
|
self.stub = bbgo_pb2_grpc.UserDataServiceStub(get_insecure_channel(host, port))
|
2022-04-09 09:30:13 +00:00
|
|
|
|
2022-04-14 07:36:29 +00:00
|
|
|
def subscribe(self, session: str) -> Iterator[UserDataEvent]:
|
|
|
|
request = bbgo_pb2.UserDataRequest(session)
|
|
|
|
response_iter = self.stub.Subscribe(request)
|
|
|
|
|
|
|
|
for response in response_iter:
|
|
|
|
yield UserDataEvent.from_pb(response)
|
2022-04-09 09:30:13 +00:00
|
|
|
|
|
|
|
|
2022-04-09 09:24:34 +00:00
|
|
|
class MarketService(object):
|
2022-04-14 08:06:36 +00:00
|
|
|
stub: bbgo_pb2_grpc.MarketDataServiceStub
|
2022-03-07 04:06:16 +00:00
|
|
|
|
2022-04-14 08:06:36 +00:00
|
|
|
def __init__(self, host: str, port: int) -> None:
|
|
|
|
self.stub = bbgo_pb2_grpc.MarketDataServiceStub(get_insecure_channel(host, port))
|
2022-04-09 09:24:34 +00:00
|
|
|
|
2022-04-14 07:36:29 +00:00
|
|
|
def subscribe(self, subscriptions: List[Subscription]) -> Iterator[MarketDataEvent]:
|
2022-04-13 09:40:21 +00:00
|
|
|
request = bbgo_pb2.SubscribeRequest(subscriptions=[s.to_pb() for s in subscriptions])
|
|
|
|
response_iter = self.stub.Subscribe(request)
|
|
|
|
|
|
|
|
for response in response_iter:
|
2022-04-14 07:36:29 +00:00
|
|
|
yield MarketDataEvent.from_pb(response)
|
2022-04-09 09:24:34 +00:00
|
|
|
|
|
|
|
def query_klines(self,
|
|
|
|
exchange: str,
|
|
|
|
symbol: str,
|
|
|
|
limit: int = 30,
|
2022-04-13 06:52:34 +00:00
|
|
|
interval: str = '1m',
|
|
|
|
start_time: int = None,
|
2022-04-16 14:52:43 +00:00
|
|
|
end_time: int = None) -> List[KLine]:
|
2022-04-09 09:24:34 +00:00
|
|
|
request = bbgo_pb2.QueryKLinesRequest(exchange=exchange,
|
|
|
|
symbol=symbol,
|
|
|
|
limit=limit,
|
|
|
|
interval=interval,
|
2022-04-13 06:52:34 +00:00
|
|
|
start_time=start_time,
|
|
|
|
end_time=end_time)
|
|
|
|
|
|
|
|
response = self.stub.QueryKLines(request)
|
|
|
|
|
|
|
|
klines = []
|
|
|
|
for kline in response.klines:
|
|
|
|
klines.append(KLine.from_pb(kline))
|
|
|
|
|
|
|
|
error = ErrorMessage.from_pb(response.error)
|
2022-04-16 14:52:43 +00:00
|
|
|
if error.code != 0:
|
|
|
|
logger.error(error.message)
|
2022-04-09 09:24:34 +00:00
|
|
|
|
2022-04-16 14:52:43 +00:00
|
|
|
return klines
|
2022-04-09 09:24:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TradingService(object):
|
2022-04-14 08:06:36 +00:00
|
|
|
stub: bbgo_pb2_grpc.TradingServiceStub
|
2022-04-09 09:24:34 +00:00
|
|
|
|
2022-04-14 08:06:36 +00:00
|
|
|
def __init__(self, host: str, port: int) -> None:
|
|
|
|
self.stub = bbgo_pb2_grpc.TradingServiceStub(get_insecure_channel(host, port))
|
2022-03-07 04:06:16 +00:00
|
|
|
|
|
|
|
def submit_order(self,
|
2022-04-16 14:52:43 +00:00
|
|
|
session: str,
|
2022-03-07 04:06:16 +00:00
|
|
|
exchange: str,
|
|
|
|
symbol: str,
|
2022-04-16 14:52:43 +00:00
|
|
|
side: str,
|
2022-03-07 04:06:16 +00:00
|
|
|
quantity: float,
|
2022-04-16 14:52:43 +00:00
|
|
|
order_type: str,
|
2022-03-07 04:06:16 +00:00
|
|
|
price: float = None,
|
|
|
|
stop_price: float = None,
|
2022-04-16 14:52:43 +00:00
|
|
|
client_order_id: str = None,
|
|
|
|
group_id: int = None) -> Order:
|
|
|
|
submit_order = SubmitOrder(session=session,
|
|
|
|
exchange=exchange,
|
|
|
|
symbol=symbol,
|
|
|
|
side=SideType.from_str(side),
|
|
|
|
quantity=quantity,
|
|
|
|
order_type=OrderType.from_str(order_type),
|
|
|
|
price=price,
|
|
|
|
stop_price=stop_price,
|
|
|
|
client_order_id=client_order_id,
|
|
|
|
group_id=group_id)
|
|
|
|
|
|
|
|
request = bbgo_pb2.SubmitOrderRequest(session=session, submit_orders=[submit_order.to_pb()])
|
2022-03-07 04:06:16 +00:00
|
|
|
response = self.stub.SubmitOrder(request)
|
|
|
|
|
2022-04-16 14:52:43 +00:00
|
|
|
order = Order.from_pb(response.orders[0])
|
|
|
|
error = ErrorMessage.from_pb(response.error)
|
|
|
|
if error.code != 0:
|
|
|
|
logger.error(error.message)
|
|
|
|
|
|
|
|
return order
|
|
|
|
|
|
|
|
def cancel_order(self, session: str, order_id: int = None, client_order_id: int = None) -> Order:
|
|
|
|
request = bbgo_pb2.CancelOrderRequest(
|
|
|
|
session=session,
|
|
|
|
id=order_id or "",
|
|
|
|
client_order_id=client_order_id or "",
|
|
|
|
)
|
2022-03-07 04:06:16 +00:00
|
|
|
response = self.stub.CancelOrder(request)
|
2022-04-16 14:52:43 +00:00
|
|
|
|
|
|
|
order = Order.from_pb(response.order)
|
|
|
|
error = ErrorMessage.from_pb(response.error)
|
|
|
|
if error.code != 0:
|
|
|
|
logger.error(error.message)
|
|
|
|
|
|
|
|
return order
|
2022-03-07 04:06:16 +00:00
|
|
|
|
|
|
|
def query_order(self, order_id: int = None, client_order_id: int = None) -> bbgo_pb2.QueryOrderResponse:
|
|
|
|
request = bbgo_pb2.QueryOrderRequest(id=order_id, client_order_id=client_order_id)
|
|
|
|
response = self.stub.QueryOrder(request)
|
|
|
|
return response
|
|
|
|
|
|
|
|
def query_orders(self,
|
|
|
|
exchange: str,
|
|
|
|
symbol: str,
|
|
|
|
states: List[str] = None,
|
|
|
|
order_by: str = 'asc',
|
|
|
|
group_id: int = None,
|
|
|
|
pagination: bool = True,
|
|
|
|
page: int = 0,
|
|
|
|
limit: int = 100,
|
|
|
|
offset: int = 0) -> bbgo_pb2.QueryOrdersResponse:
|
|
|
|
# set default value to ['wait', 'convert']
|
|
|
|
states = states or ['wait', 'convert']
|
|
|
|
request = bbgo_pb2.QueryOrdersRequest(exchange=exchange,
|
|
|
|
symbol=symbol,
|
|
|
|
states=states,
|
|
|
|
order_by=order_by,
|
|
|
|
group_id=group_id,
|
|
|
|
pagination=pagination,
|
|
|
|
page=page,
|
|
|
|
limit=limit,
|
|
|
|
offset=offset)
|
|
|
|
|
|
|
|
reponse = self.stub.QueryOrders(request)
|
|
|
|
return reponse
|
|
|
|
|
|
|
|
def query_trades(self,
|
|
|
|
exchange: str,
|
|
|
|
symbol: str,
|
|
|
|
timestamp: int,
|
|
|
|
order_by: str = 'asc',
|
|
|
|
pagination: bool = True,
|
|
|
|
page: int = 1,
|
|
|
|
limit: int = 100,
|
|
|
|
offset: int = 0) -> bbgo_pb2.QueryTradesResponse:
|
|
|
|
|
|
|
|
request = bbgo_pb2.QueryTradesRequest(exchange=exchange,
|
|
|
|
symbol=symbol,
|
|
|
|
timestamp=timestamp,
|
|
|
|
order_by=order_by,
|
|
|
|
pagination=pagination,
|
|
|
|
page=page,
|
|
|
|
limit=limit,
|
|
|
|
offset=offset)
|
|
|
|
response = self.stub.QueryTrades(request)
|
|
|
|
return response
|