Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

平仓不稳定会报错 #3

Open
river7816 opened this issue Dec 30, 2023 · 2 comments
Open

平仓不稳定会报错 #3

river7816 opened this issue Dec 30, 2023 · 2 comments

Comments

@river7816
Copy link

river7816 commented Dec 30, 2023

from binance_trade import BinanceUM
from pprint import pprint
from datetime import datetime, timedelta
import time
import asyncio
import logging

logging.basicConfig(level=logging.INFO, format='[%(asctime)s] - %(levelname)s - %(message)s')

async def twap(client: BinanceUM, 
               symbol: str,  # 产品
               marginType: str,  # 保证金模式: ISOLATED: 逐仓 CROSSED: 全仓
               positionSide: str,  # 持仓方向 LONG: 多单 SHORT: 空单
               quantity: float,
               duration: int = 60,
               orderNum: int = 10):
    
    interval_duration = duration / orderNum
    chunk_size = quantity / orderNum
    
    chunk_size = client.trade.round_quantity(
        quantity=chunk_size,
        symbol=symbol,
    )['data']
    
    end_time = datetime.now() + timedelta(seconds=duration)
    next_time = datetime.now()
    
    while datetime.now() < end_time:
        if datetime.now() >= next_time:
            try:
                client.trade.close_market(
                    symbol=symbol,  # 产品
                    marginType=marginType,  # 保证金模式: ISOLATED: 逐仓 CROSSED: 全仓
                    positionSide=positionSide,  # 持仓方向 LONG: 多单 SHORT: 空单
                    quantity=chunk_size,  # 平仓数量,'all' 表示全部
                    timeout=10,  # 等待订单成功的超时时间
                    delay=0,  # 间隔多少秒检测订单是否成功
                    cancel=True,  # 订单超时后是否取消
                    callback=callback,  # 平仓成功触发的回调函数
                    errorback=errorback,  # 平仓失败触发的回调函数
                    newThread=False,  # 是否开启一个新的线程维护这个订单
                    newClientOrderId='',  # 客户自定义订单ID
                    meta={},  # 向回调函数中传递的参数字典
                )
            except asyncio.CancelledError:
                break
            except Exception as e:
                print(f"Error executing order: {e}")
            next_time += timedelta(seconds=interval_duration)
        await asyncio.sleep((max((next_time - datetime.now()).total_seconds(), 0)))

def callback(information):
    '''
    :param information: 交易过程信息字典
        information = {
            'symbol': <产品ID>,
            'status': <订单状态>,
            'meta': <传递过来的参数>,
            'request_param': <发送下单请求的具体参数>,
            'func_param': <open_market中的参数>,
            'get_order_result': <获取订单状态的结果>,
            'set_order_result': <下单提交的结果>,
            'error_result': <异常信息>,
            'cancel_result': <取消订单的结果>,
        }
    '''
    logging.info(information['status'])


# 失败触发的回调函数
def errorback(information):
    '''
    :param information: 交易过程信息字典
        information = {
            'symbol': <产品ID>,
            'status': <订单状态>,
            'meta': <传递过来的参数>,
            'request_param': <发送下单请求的具体参数>,
            'func_param': <open_market中的参数>,
            'get_order_result': <获取订单状态的结果>,
            'set_order_result': <下单提交的结果>,
            'error_result': <异常信息>,
            'cancel_result': <取消订单的结果>,
        }
    '''
    print('errorback')
    pprint(information)
    
if __name__ == '__main__':
    client = BinanceUM(key=api_key, secret=api_secret)

    symbol = 'ETHUSDT'  # 测试产品 可以选择:BATUSDT
    openMoney = 300  # 购买金额


    trade_dict = client.trade.open_market(
        symbol=symbol,  # 产品
        marginType='CROSSED',  # 保证金模式: ISOLATED: 逐仓 CROSSED: 全仓
        positionSide='LONG',  # 持仓方向 LONG: 多单 SHORT: 空单
        openMoney=openMoney,  # 开仓金额 开仓金额openMoney和开仓数量quantity必须输入其中一个
        leverage=1,  # 开仓杠杆
        quantity=None,  # 开仓数量 None:用openMoney计算可以购买的最大数量
        timeout=10,  # 等待订单成功的超时时间
        delay=0,  # 间隔多少秒检测订单是否成功
        cancel=True,  # 订单超时后是否取消
        callback=callback,  # 开仓成功触发的回调函数
        errorback=errorback,  # 开仓失败触发的回调函数
        newThread=False,  # 是否开启一个新的线程维护这个订单
        newClientOrderId='',  # 客户自定义订单ID
        meta={},  # 向回调函数中传递的参数字典
    )
    
    order_quantity = float(trade_dict['get_order_result']['data']['executedQty'])
    asyncio.run(twap(client, symbol, 'CROSSED', 'LONG', order_quantity))

我写了一个TWAP订单,在平仓的时候会出现可能一两个单子没法满足的情况:

[2023-12-31 00:14:17,206] - INFO - FILLED
[2023-12-31 00:14:17,235] - INFO - FILLED
[2023-12-31 00:14:23,246] - INFO - FILLED
[2023-12-31 00:14:29,245] - INFO - FILLED
[2023-12-31 00:14:35,248] - INFO - FILLED
[2023-12-31 00:14:41,246] - INFO - FILLED
[2023-12-31 00:14:47,244] - INFO - FILLED
[2023-12-31 00:14:53,253] - INFO - FILLED
[2023-12-31 00:14:59,247] - INFO - FILLED
errorback
{'cancel_result': None,
 'error_result': {'code': 'FUNC_EXCEPTION',
                  'data': {},
                  'msg': 'Traceback (most recent call last):\n'
                         '  File '
                         '"/root/miniforge3/envs/server/lib/python3.10/site-packages/binance_trade/binance_um/trade/close.py", '
                         'line 517, in inner_func\n'
                         '    error_result = main_func(**main_data)\n'
                         '  File '
                         '"/root/miniforge3/envs/server/lib/python3.10/site-packages/binance_trade/binance_um/trade/close.py", '
                         'line 482, in main_func\n'
                         "    information['status'] = "
                         "order_result['data']['status']\n"
                         "KeyError: 'data'\n"},
 'func_param': {'callback': <function callback at 0x7f2e77e6f370>,
                'cancel': True,
                'delay': 0,
                'errorback': <function errorback at 0x7f2e77e6f520>,
                'marginType': 'CROSSED',
                'meta': {},
                'newClientOrderId': '',
                'newThread': False,
                'positionSide': 'LONG',
                'quantity': 0.012,
                'symbol': 'ETHUSDT',
                'timeout': 10},
 'get_order_result': {'code': -2013, 'msg': 'Order does not exist.'},
 'meta': {},
 'request_param': {'newClientOrderId': '',
                   'positionSide': 'LONG',
                   'quantity': '0.012',
                   'side': 'SELL',
                   'symbol': 'ETHUSDT',
                   'type': 'MARKET'},
 'set_order_result': {'code': 200,
                      'data': {'avgPrice': '0.00',
                               'clientOrderId': 'th2oV2ghVoyCQfLsJs18us',
                               'closePosition': False,
                               'cumQty': '0.000',
                               'cumQuote': '0.00000',
                               'executedQty': '0.000',
                               'goodTillDate': 0,
                               'orderId': 8389765639197208592,
                               'origQty': '0.012',
                               'origType': 'MARKET',
                               'positionSide': 'LONG',
                               'price': '0.00',
                               'priceMatch': 'NONE',
                               'priceProtect': False,
                               'reduceOnly': True,
                               'selfTradePreventionMode': 'NONE',
                               'side': 'SELL',
                               'status': 'NEW',
                               'stopPrice': '0.00',
                               'symbol': 'ETHUSDT',
                               'timeInForce': 'GTC',
                               'type': 'MARKET',
                               'updateTime': 1703952905231,
                               'workingType': 'CONTRACT_PRICE'},
                      'msg': ''},
 'status': None,
 'symbol': 'ETHUSDT'}
[2023-12-31 00:15:11,243] - INFO - FILLED
@pyted
Copy link
Owner

pyted commented Jan 26, 2024

更新了binance官方的底层API,将原来的pbinance、binance_candle与binance_trade合并到了一个新的库汇中——binance_interface。

binance_interface中有全部常用函数的使用例子,包括封装的下单接口。

对于这个错误,可能与以下几点有关:

  1. open_market函数本身支持异步,可以使用newThread这个参数,我没有测试过使用asyncio.run的稳定性。
  2. 官方最近API确实有一些不稳定因素,近期测试有下单被拒绝的情况发生。

建议还是用binance_interface这个库,目前测试均稳定。

@pyted
Copy link
Owner

pyted commented Jan 26, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants