avatar of 发明者量化-小小梦 发明者量化-小小梦
집중하다 사신
4
집중하다
1271
수행원

디지털 화폐 계약 단순 복사 거래 로봇

만든 날짜: 2021-04-07 21:30:05, 업데이트 날짜: 2024-12-05 21:59:36
comments   11
hits   4372

디지털 화폐 계약 단순 복사 거래 로봇

디지털 화폐 계약 단순 복사 거래 로봇

이전 기사에서 우리는 간단한 스팟 복사 트레이딩 로봇을 구현했습니다. 오늘은 간단한 복사 트레이딩 로봇의 계약 버전을 구현할 것입니다.

디자인 아이디어

복사 트레이딩 로봇의 계약 버전과 현물 버전 사이에는 큰 차이가 있습니다. 현물 복사 트레이딩은 주로 계정 자산의 변화를 모니터링하여 달성할 수 있습니다. 선물 버전에서는 계좌 포지션의 변화를 모니터링해야 합니다. 따라서 선물 버전의 상황은 더 복잡합니다. 선물에는 롱 포지션, 숏 포지션, 그리고 다양한 계약이 있기 때문입니다. 이런 일련의 세부 사항을 처리해야 합니다. 핵심 아이디어는 입장의 변화를 모니터링하는 것입니다. 위치의 변화에 ​​따라 복사 작업을 트리거합니다. 처음 설계되었을 당시에는 롱 포지션과 숏 포지션을 함께 처리할 계획이었지만, 이렇게 하면 매우 복잡해진다는 것을 알게 되었습니다. 문제를 분석한 후 롱 포지션과 숏 포지션을 별도로 처리하기로 결정했습니다.

전략 구현

전략 매개변수:

디지털 화폐 계약 단순 복사 거래 로봇

백테스팅이 지원되며, 기본 설정을 사용하여 관찰 결과를 백테스팅할 수 있습니다.

전략 소스 코드:

/*backtest
start: 2021-03-18 00:00:00
end: 2021-04-07 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"},{"eid":"Futures_OKCoin","currency":"BTC_USD"},{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
*/

function test() {
    // 测试函数
    var ts = new Date().getTime()    
    if (ts % (1000 * 60 * 60 * 6) > 1000 * 60 * 60 * 5.5) {
        Sleep(1000 * 60 * 10)
        var nowPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
        var longPosAmount = nowPosAmount.long
        var shortPosAmount = nowPosAmount.short
        var x = Math.random()
        if (x > 0.7) {
            exchange.SetDirection("buy")
            exchange.Buy(-1, _N(Math.max(1, x * 10), 0), "参考账户测试开单#FF0000")
        } else if(x < 0.2) {
            exchange.SetDirection("sell")
            exchange.Sell(-1, _N(Math.max(1, x * 10), 0), "参考账户测试开单#FF0000")
        } else if(x >= 0.2 && x <= 0.5 && longPosAmount > 4) {
            exchange.SetDirection("closebuy")
            exchange.Sell(-1, longPosAmount, "参考账户测试平仓#FF0000")
        } else if(shortPosAmount > 4) {
            exchange.SetDirection("closesell")
            exchange.Buy(-1, _N(shortPosAmount / 2, 0), "参考账户测试平仓#FF0000")
        }
    }
}

function getPosAmount(pos, ct) {
    var longPosAmount = 0
    var shortPosAmount = 0
    _.each(pos, function(ele) {
        if (ele.ContractType == ct && ele.Type == PD_LONG) {
            longPosAmount = ele.Amount
        } else if (ele.ContractType == ct && ele.Type == PD_SHORT) {
            shortPosAmount = ele.Amount
        }
    })
    return {long: longPosAmount, short: shortPosAmount}
}

function trade(e, ct, type, delta) {
    var nowPosAmount = getPosAmount(_C(e.GetPosition), ct)
    var nowAmount = type == PD_LONG ? nowPosAmount.long : nowPosAmount.short
    if (delta > 0) {
        // 开仓
        var tradeFunc = type == PD_LONG ? e.Buy : e.Sell
        e.SetDirection(type == PD_LONG ? "buy" : "sell")
        tradeFunc(-1, delta)
    } else if (delta < 0) {
        // 平仓
        var tradeFunc = type == PD_LONG ? e.Sell : e.Buy
        e.SetDirection(type == PD_LONG ? "closebuy" : "closesell")
        if (nowAmount <= 0) {
            Log("未检测到持仓")
            return 
        }
        tradeFunc(-1, Math.min(nowAmount, Math.abs(delta)))
    } else {
        throw "错误"
    }
}

function main() {
    LogReset(1)
    if (exchanges.length < 2) {
        throw "没有跟单的交易所"
    }
    var exName = exchange.GetName()
    // 检测参考交易所
    if (!exName.includes("Futures_")) {
        throw "仅支持期货跟单"
    }
    Log("开始监控", exName, "交易所", "#FF0000")
    
    // 检测跟单交易所
    for (var i = 1 ; i < exchanges.length ; i++) {
        if (exchanges[i].GetName() != exName) {
            throw "跟单的期货交易所和参考交易所不同!"
        }
    }
    
    // 设置交易对、合约
    _.each(exchanges, function(e) {
        if (!IsVirtual()) {
            e.SetCurrency(refCurrency)
            if (isSimulate) {
                if (e.GetName() == "Futures_OKCoin") {
                    e.IO("simulate", true)
                }
            }
        }
        e.SetContractType(refCt)
    })

    var initRefPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
    while(true) {
        if (IsVirtual()) {    // 回测时才模拟
            test()            // 测试函数,模拟参考账户主动交易,触发跟单账户跟单        
        }
        Sleep(5000)
        var nowRefPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
        var tbl = {
            type : "table", 
            title : "持仓",
            cols : ["名称", "标签", "多仓", "空仓", "账户资产(Stocks)", "账户资产(Balance)"],
            rows : []
        }
        _.each(exchanges, function(e) {
            var pos = getPosAmount(_C(e.GetPosition), refCt)
            var acc = _C(e.GetAccount)
            tbl.rows.push([e.GetName(), e.GetLabel(), pos.long, pos.short, acc.Stocks, acc.Balance])
        })
        LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`")
        
        // 计算仓位变动量
        var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long
        var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short

        // 检测变动
        if (longPosDelta == 0 && shortPosDelta == 0) {
            continue
        } else {
            // 检测到仓位变动
            for (var i = 1 ; i < exchanges.length ; i++) {
                // 执行多头动作
                if (longPosDelta != 0) {
                    Log(exchanges[i].GetName(), exchanges[i].GetLabel(), "执行多头跟单,变动量:", longPosDelta)
                    trade(exchanges[i], refCt, PD_LONG, longPosDelta)
                }
                // 执行空头动作
                if (shortPosDelta != 0) {
                    Log(exchanges[i].GetName(), exchanges[i].GetLabel(), "执行空头跟单,变动量:", shortPosDelta)
                    trade(exchanges[i], refCt, PD_SHORT, shortPosDelta)
                }
            }
        }

        // 执行跟单操作后,更新
        initRefPosAmount = nowRefPosAmount
    }
}

시험

OKEX는 V5 인터페이스를 업데이트한 이후 OKEX 시뮬레이션 디스크를 사용할 수 있으므로 편리한 테스트를 위해 두 개의 OKEX 시뮬레이션 디스크 API 키를 사용했습니다.

첫 번째로 추가된 교환 객체는 참조 교환이고, 복사 교환은 이 교환 계정을 따라 작동합니다. OKEX 시뮬레이션 거래 페이지에서 거래소 계좌를 기준으로 3개의 ETH 분기별 코인 기반 계약을 수동으로 배치합니다.

디지털 화폐 계약 단순 복사 거래 로봇

실제 시장에서는 기준 거래소 계좌 포지션의 변화를 감지하고 그에 따른 작업이 이루어지는 것을 볼 수 있습니다.

디지털 화폐 계약 단순 복사 거래 로봇

방금 연 두 개의 계약 포지션을 닫아보도록 합시다. 닫은 후의 포지션은 그림과 같습니다.

디지털 화폐 계약 단순 복사 거래 로봇

실시간 작업을 따르고 2개의 계약을 성사시키세요.

디지털 화폐 계약 단순 복사 거래 로봇

이 전략은 최적화 없이 간단하고 이해하기 쉬운 방식으로 설계되었습니다. 개선은 여전히 ​​주문을 따를 때 자산 탐지와 같은 세부 사항을 처리해야 합니다. 설계의 단순성을 위해 주문을 따를 때 시장 주문을 사용합니다. . 이 전략은 학습 아이디어만 제공하고, 실제 거래는 필요에 따라 최적화됩니다.

전략 주소: https://www.fmz.com/strategy/270012

메시지를 남겨주세요.