# 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)}")