参考大神策略灵感,请大家批评指正。
'''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)