python trade库 下单 开多 开空 平仓例子

# is_simulated_mode 模拟盘交易 1 真实交易  0
# coin_name 合约的名称 ETH-USDT-SWAP
# level 杠杆倍数 整数
# action 1 做多 0 做空
# close_action 2 平仓 none 不平仓
# inital_money 本金
# stop_percent 止损比例,不能超过100%
# is_has_stop 是否有止盈止损
def trade(is_simulated_mode,buy_price,sell_price,coin_name,level,action,close_action, inital_money,stop_percent,is_has_stop=0):
    api_key = os.getenv('okx_real_api_key')
    secret_key = os.getenv('okx_real_secret_key')
    passphrase = os.getenv('okx_real_passphrase')
    # 模拟盘交易 1 真实交易  0
    trade_db_path = os.path.join(current_folder_path, 'db', 'trade.db')
    trade_conn = sqlite3.connect(trade_db_path)
    is_simulated = str(is_simulated_mode)
    # 初始化客户端
    account_api = Account.AccountAPI(api_key, secret_key, passphrase, False ,flag=is_simulated,debug=False)
    trade_api = Trade.TradeAPI(api_key, secret_key, passphrase, False,flag=is_simulated,debug=False)

    # 设置交易参数
    # action = 1 # 1代表做多,0代表做空
    # coin_name = "ETH-USDT-SWAP"  # 合约ID
    current_price  =  Decimal(buy_price)  # 合约当前的价格 这个从sm20的表中取
    tdMode = "isolated"  # 交易模式:cross:全仓, isolated:逐仓 全仓模式风险极高,只能采用逐仓模式,大不了单个仓爆仓
    # 统统都以市场价进行,快速交易
    ordType = "market"  # 市价单
    lever = str(level)  # 杠杆倍数
    # 平仓还是持仓判断
    side = ''
    # 是否平仓
    is_close_order = 0 
    if close_action == 2 or close_action == '2':
        is_close_order = 1
    trade_cursor = trade_conn.cursor()
    
    # 查询swap表中的contract_value值,这个是合约的其他信息
    # ct_val: 合约价值,表示每张合约的价值。这个其实是最小每张合约的数量
    # min_size: 最小订单数量,表示合约的最小交易数量。
    # max_size: 止损单的最大数量
    min_size = 1
    max_size = 1
    ct_val = 1
    is_has_ct_val = False
    trade_cursor.execute("SELECT min_size,max_size,ct_val FROM swap WHERE name = ?", (coin_name,))
    re_ct_result = trade_cursor.fetchone()
    if re_ct_result is not None and re_ct_result[2] is not None:  # 如果没有查询到数据,则返回None
        min_size = re_ct_result[0]
        if min_size is None or str(min_size) == '1.0':
            min_size = 1
        max_size = re_ct_result[1]
        ct_val = re_ct_result[2]
        if ct_val > 0:
            ct_val = Decimal(ct_val)
        else:

            ct_val = 1
    try:
        amount = int(inital_money)
        # 暂时设置为50 否则会遇到报错 Your order amount exceeds the max order amount.
        # amount = 30
        # 止损比例
        if stop_percent >= 1:  # 如果设置的止损比例大于100%,则设置为60%
            stop_percent = 0.6
        oz = current_price * Decimal(ct_val)
        if oz == Decimal(0):
            print("合约价值为0,除法出现错误")
            return
        order_size_first = (amount * int(level)) / oz
        # 最小张数的单位就是min_size
        order_size= Decimal(order_size_first).quantize(Decimal(str(min_size)), rounding=ROUND_DOWN)
        if order_size == 0:
            print("可以下单数量为0,实力不允许,大侠有钱再来玩这把")
            return
        # 判断系统是否有默认的最大值最小值设置,如果有就遵从系统设置,如果没有就不设置,等待okx的api报错
        if is_has_ct_val:
            if order_size > max_size:
                order_size = max_size
            elif order_size < min_size:
                order_size = min_size
            else:
                print("这就是正常的情况了,orderside设置正确,无需操作")

        # 止损价格
        stop_price = ""
        # 止盈价格
        take_profit_price = ""
        max_dot_num = 1E-8
        if is_close_order == 0:
            # 正常下单:多单 空单
            if action == 0:
                # 做空
                side = "sell" 
                posSide = "short"
                if is_has_stop == 1:
                    take_profit_price = current_price * Decimal(1 - (stop_percent))
                    take_profit_price= Decimal(take_profit_price).quantize(Decimal(str(max_dot_num)), rounding=ROUND_DOWN)

                    stop_price = current_price * Decimal(1 + (stop_percent ))  # 计算出止损的价格
                    stop_price= Decimal(stop_price).quantize(Decimal(str(max_dot_num)), rounding=ROUND_DOWN)
            else:
                # 做多
                side = "buy"
                posSide = "long"
                if is_has_stop == 1:
                    take_profit_price = current_price * Decimal(1 + (stop_percent ))
                    take_profit_price= Decimal(take_profit_price).quantize(Decimal(str(max_dot_num)), rounding=ROUND_DOWN)
                    stop_price = current_price * Decimal(1 - (stop_percent))  # 计算出止损的价格
                    stop_price= Decimal(stop_price).quantize(Decimal(str(max_dot_num)), rounding=ROUND_DOWN)
            
            # # 设置杠杆
            account_api.set_leverage(instId=coin_name, lever=lever, mgnMode=tdMode,posSide=posSide)
            # print(f"设置杠杆结果: {result}")

            # instId: 交易品种ID,如"BTC-USDT"
            # tdMode: 交易模式,如"cash"(现金),"cross"(全仓),"isolated"(逐仓)
            # side: 订单方向,"buy"或"sell"
            # ordType: 订单类型,如"market"(市价),"limit"(限价)等
            # sz: 委托数量
            # ccy: 保证金币种,仅适用于逐仓(可选)
            # clOrdId: 客户自定义订单ID(可选)
            # tag: 订单标签(可选)
            # posSide: 持仓方向,如"long","short"(可选)
            # px: 委托价格,仅适用于限价单(可选)
            # reduceOnly: 是否只减仓,true或false(可选)
            # tgtCcy: 币币交易时,sz的单位,"base_ccy"或"quote_ccy"(可选)
            # tpTriggerPx: 止盈触发价(可选)
            # tpOrdPx: 止盈委托价(可选)
            # slTriggerPx: 止损触发价(可选)
            # slOrdPx: 止损委托价(可选)
            # tpTriggerPxType: 止盈触发价类型(可选)
            # slTriggerPxType: 止损触发价类型(可选)
            # quickMgnType: 快速保证金类型(可选)
            # stpId: 自成交保护组ID(可选)
            # stpMode: 自成交保护模式(可选)
            # attachAlgoOrds: 附加的算法订单(可选)

            # slTriggerPxType(止损触发价类型)参数通常有以下几种类型:
            # last:最新成交价格触发 默认
            # index:指数价格触发
            # mark:标记价格触发
            
            
            # stop_price需要换算成十亿分之一的精度,适合插件的要求,否则会报错
            # 定义默认金额最小为十亿分之一
            if is_has_stop == 1:
                stop_price = Decimal(stop_price).quantize(Decimal('1E-20'), rounding=ROUND_DOWN)
                take_profit_price = Decimal(take_profit_price).quantize(Decimal('1E-20'), rounding=ROUND_DOWN)
            result = trade_api.place_order(instId=coin_name, 
                                        tdMode=tdMode, 
                                        side=side, 
                                        ordType=ordType, 
                                        #    slTriggerPxType="last", # 默认就是last,不需要设置
                                        slTriggerPx=str(stop_price),
                                        slOrdPx=str(stop_price), # 这里设置为空就会以当前市场价来执行
                                        tpTriggerPx=str(take_profit_price),  # 止盈 添加止盈触发价格
                                        tpOrdPx=str(take_profit_price),      # 止盈 添加止盈订单价格
                                        sz=str(order_size),
                                        posSide=posSide)
            
            is_ordered_success = result['data'][0]['sCode'] == '0'
            if is_ordered_success:
                print("下单成功")

            else:
                # 开始重试
                error_msg = result['data'][0]['sMsg']
                print("下单失败,原因如下"+error_msg)
        else:
            current_price = Decimal(sell_price)
            # 平仓操作
            if action == 0:
                # 空单平仓
                side = "buy" 
                posSide = "short"
            else:
                # 多单平仓
                side = "sell" 
                posSide = "long"
            result = trade_api.place_order(instId=coin_name, 
                                    tdMode=tdMode, 
                                    side=side, 
                                    ordType=ordType, 
                                    sz=str(order_size),
                                    posSide=posSide)
            is_ordered_success = result['data'][0]['sCode'] == '0'
            if is_ordered_success:
                # 平仓成功
                # 插入成功的订单信息
                print("平仓成功")
            else:
                # 平仓失败
                # 记录详细的失败信息,要发送企业微信失败提醒
                print(f"{coin_name}平仓失败,失败原因{result['data'][0]['sMsg']}")
    except Exception as e:
        print(f"发生错误: {str(e)}")


作者:spike

分类: Python

创作时间:2024-09-29

更新时间:2024-09-29

联系方式放在中括号之中例如[[email protected]],回复评论在开头加上标号例如:#1