Type/to search
8
Follow
1361
Followers
디지털 화폐 계약 단순 복사 거래 로봇
Discussions
Created 2021-04-07 21:30:05  Updated 2024-12-05 21:59:36
 11
 4627

img

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

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

디자인 아이디어

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

전략 구현

전략 매개변수:

img

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

전략 소스 코드:

javascript
/*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 분기별 코인 기반 계약을 수동으로 배치합니다.

img

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

img

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

img

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

img

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

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

메시지를 남겨주세요.

Related Recommendations
Comment
All comments (11)

    2个不同的交易所不能对接么

    4 years ago

    可以实现的,改下代码就可以了。

    4 years ago

    具体改哪里能请教一下么,我现在用的bibox期货,想对接跟单别人的okx交易所的话,需要改哪里呢

    4 years ago

    因为交易所的合约规格可能不一样,可能要根据具体情况调整跟单的代码。

    4 years ago

    发明者什么时候能对接币赢合约期货啊?币安和欧意返手续费太少了,高频机器人,手续费太伤了

    4 years ago

    我用的bibox交易所,有百分之80的返佣,FMZ完美支持

    4 years ago

    这边评估下这个交易所,还没有交易所方面联系过我们。

    4 years ago

    希望有个币安usdt的跟单版本哈

    5 years ago

    希望有币安usdt永续合约版本,执行者的API?????

    5 years ago

    希望能有火币usdt永续合约版本的

    5 years ago

    很感谢你的分享,很值得学习。

    5 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)