资源加载中... loading...

双平台对冲平衡策略

Author: ianzeng123, Date: 2024-11-15 17:19:52
Tags:

参考大神策略灵感,请大家批评指正。


'''backtest
start: 2024-11-19 00:00:00
end: 2024-12-18 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Binance","currency":"TRB_USDT"},{"eid":"OKX","currency":"TRB_USDT"}]
'''

import time
import json

# 全局变量定义
depthA = depthB = None
timeBegin = timeEnd = None
askPriceA = bidPriceA = askAmountA = bidAmountA = 0
askPriceB = bidPriceB = askAmountB = bidAmountB = 0
minAmount = 20  # 最小下单量
feeA = 0.0020  # Huobi 手续费   
feeB = 0.0010  # Binance 手续费
fees = None
minProfit = 0.0002  # 最小利润
notDealAmountA = notDealAmountB = None
accountA = accountB = None
initAccountA = initAccountB = None
maxDeltaAmount = 100  # 最大可容忍币偏差
dealAmountA = 0
dealAmountB = 0
safeAmount = 800  # 安全最大成交量
profit = None
maxTime = 150  # 最大延迟过滤
accountBNB = None
reload = False

# 初始化函数
def init():
    global fees, initAccountA, initAccountB, accountA, accountB

    try:
        fees = feeA + feeB

        initAccountA = _G("initAccountA")
        initAccountB = _G("initAccountB")
        
        if initAccountA is None or initAccountB is None:
            initAccountA = _C(exchanges[0].GetAccount)
            initAccountB = _C(exchanges[1].GetAccount)
            _G("initAccountA", initAccountA)
            _G("initAccountB", initAccountB)
            Log("账号初值初始化成功")
        else:
            Log("继承初值数据成功")
        
        accountA = initAccountA
        accountB = initAccountB

    except Exception as e:
        Log("初始化失败 请重启:", e)

# 规范化深度数据
def legalize_depth(depthA, depthB):
    global askPriceA, bidPriceA, askAmountA, bidAmountA
    global askPriceB, bidPriceB, askAmountB, bidAmountB

    askPriceA = bidPriceA = askAmountA = bidAmountA = 0
    askPriceB = bidPriceB = askAmountB = bidAmountB = 0

    for ask in depthA[0]["Asks"]:
        askPriceA = ask["Price"]
        askAmountA += ask["Amount"]
        if askAmountA >= minAmount:
            break

    for bid in depthA[0]["Bids"]:
        bidPriceA = bid["Price"]
        bidAmountA += bid["Amount"]
        if bidAmountA >= minAmount:
            break

    for ask in depthB[0]["Asks"]:
        askPriceB = ask["Price"]
        askAmountB += ask["Amount"]
        if askAmountB >= minAmount:
            break

    for bid in depthB[0]["Bids"]:
        bidPriceB = bid["Price"]
        bidAmountB += bid["Amount"]
        if bidAmountB >= minAmount:
            break

# 取消所有挂单
def cancel_all_orders():
    global dealAmountA, dealAmountB

    orders = _C(exchanges[0].GetOrders)
    for order in orders:
        exchanges[0].CancelOrder(order["Id"])
        Log("成交:", order["DealAmount"], "未成交:", order["Amount"] - order["DealAmount"])
        dealAmountA -= order["Amount"] - order["DealAmount"]

    orders = _C(exchanges[1].GetOrders)
    for order in orders:
        exchanges[1].CancelOrder(order["Id"])
        Log("成交:", order["DealAmount"], "未成交:", order["Amount"] - order["DealAmount"])
        dealAmountB -= order["Amount"] - order["DealAmount"]

# 检查余额
def check_balance():
    global accountA, accountB, dealAmountA, dealAmountB

    cancel_all_orders()
    deltaStocks = (initAccountA["Stocks"] + initAccountA["FrozenStocks"] + initAccountB["Stocks"] + initAccountB["FrozenStocks"]
        - accountA["Stocks"] - accountA["FrozenStocks"] - accountB["Stocks"] - accountB["FrozenStocks"])

    deltaStocks = round(deltaStocks, 0)

    if deltaStocks < -maxDeltaAmount:  # 仓位过重
        if askPriceA > askPriceB and accountA["Stocks"] > -deltaStocks:
            exchanges[0].Sell(askPriceA, -deltaStocks)
            dealAmountA += -deltaStocks
        else:
            exchanges[1].Sell(askPriceB, -deltaStocks)
            dealAmountB += -deltaStocks
        return True

    if deltaStocks > maxDeltaAmount:  # 仓位过轻
        if bidPriceA < bidPriceB and accountA["Balance"] * 0.999 / bidPriceA > deltaStocks:
            exchanges[0].Buy(bidPriceA, deltaStocks)
            dealAmountA += deltaStocks
        else:
            exchanges[1].Buy(bidPriceB, deltaStocks)
            dealAmountB += deltaStocks
        return True

    return False

# 更新利润
def update_profit():
    global profit

    profit = (
        accountA["Balance"] + accountB["Balance"] + accountA["FrozenBalance"] + accountB["FrozenBalance"]
        + (accountA["Stocks"] + accountA["FrozenStocks"] + accountB["Stocks"] + accountB["FrozenStocks"]
        - initAccountA["Stocks"] - initAccountA["FrozenStocks"] - initAccountB["Stocks"] - initAccountB["FrozenStocks"]) * askPriceA
        - (initAccountA["Balance"] + initAccountA["FrozenBalance"] + initAccountB["Balance"] + initAccountB["FrozenBalance"]))

    return profit

# 检查套利机会
def check_opportunity():
    global dealAmountA, dealAmountB, accountA, accountB, diff_A, diff_B 

    diff_A = bidPriceB - askPriceA  # A交易所买 -> B交易所卖
    diff_B = bidPriceA - askPriceB  # B交易所买 -> A交易所卖

    if diff_A > 0 and diff_A > (minProfit + fees) * askPriceA:
        maxBuyAmount = min(accountA["Balance"] / askPriceA * 0.98, askAmountA)
        maxSellAmount = min(accountB["Stocks"], bidAmountB)
        amount = min(maxBuyAmount, maxSellAmount, safeAmount)
        amount = round(amount, 0)

        if amount >= minAmount:
            Log("huobi -> binance", amount)
            exchanges[0].Buy(askPriceA, amount)
            exchanges[1].Sell(bidPriceB, amount)
            time.sleep(3)
            dealAmountA += amount
            dealAmountB += amount
            accountA = _C(exchanges[0].GetAccount)
            accountB = _C(exchanges[1].GetAccount)
            Log("利润更新:", update_profit())

    if diff_B > 0 and diff_B > (minProfit + fees) * askPriceB:
        maxBuyAmount = min(accountB["Balance"] / askPriceB * 0.98, askAmountB)
        maxSellAmount = min(accountA["Stocks"], bidAmountA)
        amount = min(maxBuyAmount, maxSellAmount, safeAmount)
        amount = round(amount, 0)

        if amount >= minAmount:
            Log("binance -> huobi", amount)
            exchanges[1].Buy(askPriceB, amount)
            exchanges[0].Sell(bidPriceA, amount)
            time.sleep(3)
            dealAmountA += amount
            dealAmountB += amount
            accountA = _C(exchanges[0].GetAccount)
            accountB = _C(exchanges[1].GetAccount)
            Log("利润更新:", update_profit())

def main():
    global initAccountA, initAccountB
    if reload == True:
        initAccountA = _C(exchanges[0].GetAccount)
        initAccountB = _C(exchanges[1].GetAccount)
        _G("initAccountA", initAccountA)
        _G("initAccountB", initAccountB)

    init()

    checkBalanceCount = 60
    
    while True:
        accountA = exchanges[0].GetAccount()
        accountB = exchanges[1].GetAccount()
        timeBegin = int(time.time() * 1000)
        depthA = exchanges[0].Go("GetDepth")
        depthB = exchanges[1].Go("GetDepth")
        depthA = depthA.wait()
        depthB = depthB.wait()
        
        timeEnd = int(time.time() * 1000)
        # 真实交易,去除205-208注释
        #if timeEnd - timeBegin > maxTime:
        #    continue  # 延迟超过 maxTime 毫秒就放弃当组数据
        #if depthA is None or depthB is None or accountA is None or accountB is None:
        #    continue

        legalize_depth(depthA, depthB)

        if checkBalanceCount >= 60:
            checkBalanceCount = 0
            if check_balance():
                continue
        else:
            checkBalanceCount += 1
        
        check_opportunity()
        
        # 数据可视化操作
        table = {
            'type': 'table',
            'title': '持仓操作',
            'cols': ['交易所', '初始余额', '初始币数', '当前余额', '当前币数', '成交量'],
            'rows': [
                ['huobi', initAccountA.Balance + initAccountA.FrozenBalance, initAccountA.Stocks + initAccountA.FrozenStocks,
                    accountA.Balance + accountA.FrozenBalance, accountA.Stocks + accountA.FrozenStocks, dealAmountA],
                ['binance', initAccountB.Balance + initAccountB.FrozenBalance, initAccountB.Stocks + initAccountB.FrozenStocks,
                    accountB.Balance + accountB.FrozenBalance, accountB.Stocks + accountB.FrozenStocks, dealAmountB],
                ['合计', initAccountA.Balance + initAccountB.Balance, initAccountA.Stocks + initAccountB.Stocks,
                    accountA.Balance + accountA.FrozenBalance + accountB.Balance + accountB.FrozenBalance,
                    accountA.Stocks + accountA.FrozenStocks + accountB.Stocks + accountB.FrozenStocks, dealAmountA + dealAmountB],
                ['huobi盘口', askPriceA, askAmountA, bidPriceA, bidAmountA, ''],
                ['binance盘口', askPriceB, askAmountB, bidPriceB, bidAmountB, ''],
                ['收益:', str(_N(update_profit(), 8)) + '#FF0000',  '', '', ''],
                ['收益率', str(_N(100 * profit / (initAccountA.Balance + initAccountA.FrozenBalance + initAccountB.Balance + initAccountB.FrozenBalance), 6)) + '%' + '#FF0000', '', '', '', ''],
                ['总延迟', timeEnd - timeBegin, '', '', '', ''],
                ['最后更新时间', _D(), '', '', '', ''],
            ]
        }
        LogStatus('`' + json.dumps(table) + '`')

        time.sleep(10)
        


More