zoukankan      html  css  js  c++  java
  • 比特币搬砖对冲策略Python源码

    策略复制地址:https://www.fmz.com/strategy/21023

    策略原理

    比特币搬砖策略是入门程序化交易的基础策略。原理简单,是新手尝试程序化的好选择,在其黄金时期,比特币搬砖也带来大量的利润。掌握此策略需要有一定的基础。
    长期来看,两个交易所比特币的差价应该稳定的,如果存在足够的差价,我们便可以在价格低的交易所买入币,在价格高的交易所卖出币。这样一来两个交易所持有的币总量没变,但价值却增加了。这就是搬砖的基础原理。

    策略参数:

    主要设置差价和操作量,其中差价设为交互模式

     
     

    策略源码:

    import time
    import json
    
    def cancelAll():
        ret = False
        for e in exchanges:
            while True:
                n = 0
                for order in _C(e.GetOrders):
                    ret = True
                    e.CancelOrder(order.Id)
                    n+=1
                if n == 0:
                    break
        return ret
    
    def main():
        global MinSpreadA, MinSpreadB
        SetErrorFilter("canceled")
        if len(exchanges) != 2:
            raise Exception("只支持两个交易所对冲")
        
        LogReset()
        LogProfitReset()
        cancelAll()
        
        initStocks = 0.0
        initBalance = 0.0
        minAmount = 0.1
        lastTradeTime = 0
        lastTradeErrExchange = ''
        accountsCache = []
        hedgeNum = [0, 0]
        names = []
        baseCurrency = exchange.GetCurrency()
        for e in exchanges:
            if e.GetCurrency() != baseCurrency:
                raise Exception("必须是同样的货币才可以对冲 " + baseCurrency)
            names.append(e.GetName())
            account = _C(e.GetAccount)
            accountsCache.append(account)
            initStocks += account.Stocks
            initBalance += account.Balance
            Log("Switch", e.GetLabel(), "To", e.IO("websocket"))
        minAmount = 0.01 if baseCurrency == "BTC" else 0.1
        Log("总钱:", _N(initBalance), "总币", _N(initStocks), 'Python:', __import__('sys').version)
        while True:
            if not accountsCache:
                accountsCache = [_C(e.GetAccount) for e in exchanges]
            Sleep(LoopInterval)
            cmd = GetCommand()
            if cmd:
                Log("CMD", cmd)
                arr = cmd.split(':')
                if arr[0] == 'A->B':
                    MinSpreadA = float(arr[1])
                elif arr[0] == 'B->A':
                    MinSpreadB = float(arr[1])
                    
            depthA = exchanges[0].GetDepth()
            if not depthA:
                continue
            depthB = exchanges[1].GetDepth()
            if not depthB:
                continue
            if lastTradeTime > 0 and time.time() - lastTradeTime > BalanceTime:
                needUpdate = cancelAll()
                if not needUpdate:
                    for account in accountsCache:
                        if account.FrozenBalance >= 0.1 or account.FrozenStocks > 0.001:
                            needUpdate = True
                            break
                if needUpdate:            
                    accountsCache = [_C(e.GetAccount) for e in exchanges]
                nowStocks = 0.0
                nowBalance = 0.0
                for account in accountsCache:
                    nowStocks += account.Stocks
                    nowBalance += account.Balance
                diff = _N(nowStocks - initStocks, 5)
                isReverse = None
                if abs(diff) < minAmount:
                    LogProfit(_N(nowBalance-initBalance, 3), "总钱:", _N(nowBalance), "总币", _N(nowStocks), "币差:", diff)
                    lastTradeTime = 0
                elif diff > minAmount:
                    isReverse = depthA.Bids[0].Price < depthB.Bids[0].Price
                elif -diff > minAmount:
                    isReverse = depthA.Asks[0].Price > depthB.Asks[0].Price
                if isReverse is not None:
                    depths = [depthA, depthB]
                    opAmount = None
                    for pos in ([1, 0] if isReverse else [0, 1]):
                        if diff >= minAmount:
                            opAmount = min(diff, accountsCache[pos].Stocks, depths[pos].Bids[0].Amount + depths[pos].Bids[1].Amount)
                            diff -= opAmount
                            if opAmount >= minAmount:
                                exchanges[pos].Sell(depths[pos].Bids[1].Price, opAmount)
                        elif -diff >= minAmount:
                            opAmount = min(-diff, _N(accountsCache[pos].Balance / depths[pos].Asks[1].Price, 3), depths[pos].Asks[0].Amount + depths[pos].Asks[1].Amount)
                            diff += opAmount
                            if opAmount >= minAmount:
                                exchanges[pos].Buy(depths[pos].Asks[1].Price, opAmount)
                    if opAmount is not None:
                        lastTradeTime = time.time()
                        accountsCache = []
                continue
                # end of balanceAccount
    
            diffA = _N(depthA.Bids[0].Price - depthB.Asks[0].Price, 3)
            diffB = _N(depthB.Bids[0].Price - depthA.Asks[0].Price, 3)
            LogStatus('`' + json.dumps({'type': 'table', 'title': '运行信息', 'cols': ['名称', '', '冻结的钱', '', '冻结的币', '买一', '卖一', '阀值', '差价', '次数'], 'rows': [[names[0], accountsCache[0].Balance, accountsCache[0].FrozenBalance, accountsCache[0].Stocks, accountsCache[0].FrozenStocks, depthA.Bids[0].Price, depthA.Asks[0].Price, MinSpreadA, diffA, hedgeNum[0]], [names[1], accountsCache[1].Balance, accountsCache[1].FrozenBalance, accountsCache[1].Stocks, accountsCache[1].FrozenStocks, depthB.Bids[0].Price, depthB.Asks[0].Price, MinSpreadB, diffB, hedgeNum[0]]]}) + '`')
            HPos = 0
            if diffA >= MinSpreadA:
                orderH = depthA.Bids[0]
                orderL = depthB.Asks[0]
                exchangeH = exchanges[0]
                exchangeL = exchanges[1]
                accountH = accountsCache[0]
                accountL = accountsCache[1]
            elif diffB >= MinSpreadB:
                HPos = 1
                orderH = depthB.Bids[0]
                orderL = depthA.Asks[0]
                exchangeH = exchanges[1]
                exchangeL = exchanges[0]
                accountH = accountsCache[1]
                accountL = accountsCache[0]
            else:
                continue
    
            opPrice = _N((orderH.Price + orderL.Price) / 2.0, 2)
            opAmount = min(MaxAmount, orderH.Amount, orderL.Amount, accountH.Stocks, _N(accountL.Balance / opPrice, 3))
            if opAmount >= minAmount:
                tasks = [[exchangeH.Sell, "H"], [exchangeL.Buy, "L"]]
                if lastTradeErrExchange == "L":
                    tasks.reverse()
                lastTradeErrExchange = ""
                for task in tasks:
                    if task[0](opPrice, opAmount) is None:
                        lastTradeErrExchange = task[1]
                        break
                lastTradeTime = time.time()
                accountsCache = []
                hedgeNum[HPos] += 1
  • 相关阅读:
    js Image对象 及rollover效果
    精通javascript:元素的尺寸
    javascript 快捷操作
    精通javascript:获取位置
    javascript对象小问题
    javascript 获取元素的真实,最终的css样式
    MySQL索引
    精通javascript:元素的可见性
    javascript 图像预载入和如何判断图片是否加载完成
    ASP.NET Ajax的CalendarExtender控件被其它Div遮住问题
  • 原文地址:https://www.cnblogs.com/botvsing/p/10838631.html
Copyright © 2011-2022 走看看