从零开始搭建链上dex自动化价差套利程序(11)

2023-12-13 11:33:31

风险控制

需要将仓位杠杆控制到3倍以内,由于dydx与apex没有获取仓位杠杆的接口,但是每次发送交易的数额可以决定,故而可以设置每次发送总仓位1.5倍杠杆的数额,然后设置一个变量保证每个方向上的交易不超过2次,即可保证总仓位始终小于3倍杠杆

细节:

send_order_apex(client_apex, symbol=“BTC-USDC”, side=“BUY”,type=“MARKET”,size=“0.004”, expirationEpochSeconds=currentTime+100,price=’58888’, limitFeeRate=limitFeeRate)

在apex市价交易参数里,price代表可接受的价格,故而当卖出时,此price要尽可能的调低,否则会失败,同理买进时要尽可能的高。

同时将价差计算修改为:

?# 计算价差
? ? spread1 = ((float(b_first_price_apex) -float(s_first_price_dydx))/float(b_first_price_apex))*100
? ? spread2 = ((float(b_first_price_dydx) - float(s_first_price_apex))/float(b_first_price_dydx))*100?

因为如果在apex卖,dydx买的话,apex的卖价应该大于dydx的买价,apex的卖价由apex买一价决定,dydx买价由dydx卖一价决定。反之同理。

代码修改如下:

get_depth_data_btc.py

"""
这是一个用来计算 APEX 和 dydx 之间的 BTCUSDC 价差的模块。
可以调用 calculate_spread 函数来返回两个交易所的卖一价、买一价和价差。
"""



import asyncio
from apexpro.http_public import HttpPublic
from dydx3 import Client
from dydx3.constants import MARKET_BTC_USD


# 定义交易对列表
symbol = 'BTCUSDC'
market = MARKET_BTC_USD

# 定义异步函数来获取 APEX 的价格
async def get_apex_price():
    # 初始化API客户端
    apexclient = HttpPublic("https://pro.apex.exchange")
    # 获取深度数据
    trades_data = apexclient.depth(symbol=symbol)['data']
    # 返回卖一价和买一价
    return trades_data['a'][0][0], trades_data['b'][0][0], trades_data['a'][0][1], trades_data['b'][0][1]

# 定义异步函数来获取 dydx 的价格
async def get_dydx_price():
    # 初始化API客户端
    dydxclient = Client(host='https://api.dydx.exchange')
    # 获取深度数据
    orderbook_response = dydxclient.public.get_orderbook(market=market)
    orderbook_data = orderbook_response.data
    # 返回卖一价和买一价
    return orderbook_data['asks'][0]['price'], orderbook_data['bids'][0]['price'], orderbook_data['asks'][0]['size'], orderbook_data['bids'][0]['size']

# 定义异步函数来计算价差
async def calculate_spread():
    # 创建两个任务,分别获取 APEX 和 dydx 的价格
    task1 = asyncio.create_task(get_apex_price())
    task2 = asyncio.create_task(get_dydx_price())
    # 等待两个任务完成,并获取结果
    s_first_price_apex, b_first_price_apex,s_first_size_apex,b_first_size_apex = await task1
    s_first_price_dydx, b_first_price_dydx,s_first_size_dydx,b_first_size_dydx   = await task2
    # 计算价差
    spread1 = ((float(b_first_price_apex) - float(s_first_price_dydx))/float(b_first_price_apex))*100
    spread2 = ((float(b_first_price_dydx) - float(s_first_price_apex))/float(b_first_price_dydx))*100
    return s_first_price_apex,b_first_price_apex,s_first_price_dydx,b_first_price_dydx,s_first_size_apex,b_first_size_apex,s_first_size_dydx,b_first_size_dydx,spread1,spread2


if __name__ == '__main__':
    # 创建事件循环
    loop = asyncio.get_event_loop()
    # 运行异步函数
    loop.run_until_complete(calculate_spread())
    # 关闭事件循环
    loop.close()

place_order_btc.py

from init_apex_client import init_client
import asyncio
from send_order_apex import send_order_apex
from init_dydx_client import init_dydx_client
from send_order_dydx import send_order_dydx
from dydx3.constants import MARKET_BTC_USD
from dydx3.constants import ORDER_SIDE_BUY,ORDER_SIDE_SELL
from dydx3.constants import ORDER_TYPE_MARKET,ORDER_TYPE_LIMIT
from get_depth_data_btc import calculate_spread
import time

#价格设置需要更精确,不然发不出去!

# 初始化apex客户端
client_apex = init_client()
configs = client_apex.configs()
# 获取apex用户和账户信息
client_apex.get_user()
client_apex.get_account()


# 初始化dydx客户端
client_dydx = init_dydx_client()
# 获取我们的dydx仓位 ID
account_response = client_dydx.private.get_account()
position_id = account_response.data['account']['positionId']

async def arbitrage():
  arbitrage_count = 0
  while True:
    # 计算价差
    s_first_price_apex,b_first_price_apex,s_first_price_dydx,b_first_price_dydx,s_first_size_apex,b_first_size_apex,s_first_size_dydx,b_first_size_dydx,spread1,spread2 = await calculate_spread()
    # 根据价差判断是否发送交易
    if spread1 > 0.7:
          if arbitrage_count <2:
            currentTime = time.time()
            limitFeeRate = client_apex.account['takerFeeRate']
            task_apex_sell = asyncio.create_task(
                send_order_apex(client_apex, symbol="BTC-USDC", side="SELL",
                                type="MARKET", size="0.004", expirationEpochSeconds=currentTime+100,
                                price='18888', limitFeeRate=limitFeeRate)
            )
            task_dydx_buy = asyncio.create_task(
                send_order_dydx(client_dydx, position_id, MARKET_BTC_USD, ORDER_SIDE_BUY, ORDER_TYPE_LIMIT,
                                True, '0.004', b_first_price_dydx, '0.0015', currentTime+100)
            )

            orderResult1 = await task_apex_sell
            orderResult2 = await task_dydx_buy
            arbitrage_count += 1
            if arbitrage_count >=2:
               print('above leverage ,stop')
            print(orderResult1,orderResult2)
    if spread2 > 0.7: 
      if arbitrage_count >-2:
        currentTime = time.time()
        # 异步地发送一个apex市价买单和一个dydx市价卖单
        limitFeeRate = client_apex.account['takerFeeRate']
        task_apex_buy = asyncio.create_task(
                send_order_apex(client_apex, symbol="BTC-USDC", side="BUY",
                                type="MARKET", size="0.004", expirationEpochSeconds=currentTime+100,
                                price='58888', limitFeeRate=limitFeeRate)
            )
        task_dydx_sell = asyncio.create_task(
            send_order_dydx(client_dydx, position_id, MARKET_BTC_USD, ORDER_SIDE_SELL, ORDER_TYPE_LIMIT,
                            True, '0.004', s_first_price_dydx, '0.0015', currentTime+100)
        )

        orderResult1 = await task_apex_buy
        orderResult2 = await task_dydx_sell
        arbitrage_count -= 1
        if arbitrage_count <=-2:
          print('above leverage ,stop')
        print(orderResult1,orderResult2)
    # 延时一秒,避免过于频繁
    await asyncio.sleep(1)

# 运行异步函数
asyncio.run(arbitrage())

持续运行:

写一个脚本确保因为各种异常程序退出后能够重启:

import subprocess
import time

def run_program():
    # 这里替换为你需要执行的程序命令
    process = subprocess.Popen(["python", "place_order_btc.py"])  # 例如:python your_program.py
    return process

if __name__ == "__main__":
    while True:
        program = run_program()
        while program.poll() is None:
            # 程序正在运行
            time.sleep(5)  # 每5秒检查一次程序状态
        # 程序已终止,等待一段时间后重启
        print("程序已终止,重新启动中...")
        time.sleep(3)  # 等待3秒

文章来源:https://blog.csdn.net/weixin_43680481/article/details/134825854
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。