이전 기사에서는 간단한 스팟 오더 감독 봇을 구현했고, 오늘 우리는 간단한 오더 감독 봇의 계약 버전을 구현할 것입니다.
계약 버전의 주문 감독 봇과 스포트 버전의 큰 차이가 있습니다. 스포트 주문 감독은 주로 계정 자산의 변화를 모니터링함으로써 실현 될 수 있습니다. 선물 버전은 계정에서의 위치 변화를 모니터링해야합니다. 따라서 선물 버전의 상황은 더 복잡합니다. 왜냐하면 선물의 긴 포지션과 짧은 포지션에 대한 다른 계약이 있기 때문에 일련의 세부 사항을 처리해야합니다. 핵심 아이디어는 포지션 변화를 모니터링하고 포지션 변화에 따라 주문 감독 조치를 유발하는 것입니다. 원래는 긴 포지션과 짧은 포지션을 함께 처리하도록 설계되었지만 문제를 분석한 후 긴 포지션과 짧은 포지션을 별도로 처리하기로 결정되었습니다.
전략 파라미터:
백테스트를 지원하고, 관찰을 위한 백테스트를 위해 기본 설정을 직접 사용할 수 있습니다.
소스 코드:
/*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() {
// test function
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), "the reference account tests ordering#FF0000")
} else if(x < 0.2) {
exchange.SetDirection("sell")
exchange.Sell(-1, _N(Math.max(1, x * 10), 0), "the reference account tests ordering#FF0000")
} else if(x >= 0.2 && x <= 0.5 && longPosAmount > 4) {
exchange.SetDirection("closebuy")
exchange.Sell(-1, longPosAmount, "the reference account tests closing positions#FF0000")
} else if(shortPosAmount > 4) {
exchange.SetDirection("closesell")
exchange.Buy(-1, _N(shortPosAmount / 2, 0), "he reference account tests closing position#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) {
// open position
var tradeFunc = type == PD_LONG ? e.Buy : e.Sell
e.SetDirection(type == PD_LONG ? "buy" : "sell")
tradeFunc(-1, delta)
} else if (delta < 0) {
// close position
var tradeFunc = type == PD_LONG ? e.Sell : e.Buy
e.SetDirection(type == PD_LONG ? "closebuy" : "closesell")
if (nowAmount <= 0) {
Log("no position detected")
return
}
tradeFunc(-1, Math.min(nowAmount, Math.abs(delta)))
} else {
throw "error"
}
}
function main() {
LogReset(1)
if (exchanges.length < 2) {
throw "no platform with order supervision"
}
var exName = exchange.GetName()
// detect the platform for reference
if (!exName.includes("Futures_")) {
throw "only support futures order supervising"
}
Log("start monitoring", exName, "platform", "#FF0000")
// detect the order supervising platform
for (var i = 1 ; i < exchanges.length ; i++) {
if (exchanges[i].GetName() != exName) {
throw "The order supervising platform is different from the reference platform!"
}
}
// set trading pair and contract
_.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()) { // only simulate during backtest
test() // test function, which simulates a reference account to trade automatically, to trigger the order supervising of the account
}
Sleep(5000)
var nowRefPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
var tbl = {
type : "table",
title : "position",
cols : ["name", "label", "long", "short", "account asset (Stocks)", "account assest (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) + "`")
// calculate the position amount of change
var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long
var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short
// detect the change
if (longPosDelta == 0 && shortPosDelta == 0) {
continue
} else {
// detect the position change
for (var i = 1 ; i < exchanges.length ; i++) {
// execute the action of long
if (longPosDelta != 0) {
Log(exchanges[i].GetName(), exchanges[i].GetLabel(), "Execute long order supervising, amount of change:", longPosDelta)
trade(exchanges[i], refCt, PD_LONG, longPosDelta)
}
// execute the action of short
if (shortPosDelta != 0) {
Log(exchanges[i].GetName(), exchanges[i].GetLabel(), "Execute short order supervising, amount of change:", shortPosDelta)
trade(exchanges[i], refCt, PD_SHORT, shortPosDelta)
}
}
}
// after the operation of order supervising, update
initRefPosAmount = nowRefPosAmount
}
}
OKEX가 V5 인터페이스를 업데이트하고 OKEX 시뮬레이션 봇을 사용할 수 있다는 사실을 고려하여, 저는 두 개의 OKEX 시뮬레이션 봇의 API KAY를 매우 편리하게 테스트했습니다.
추가해야 하는 첫 번째 교환 대상은 레퍼런스 플랫폼이고, 주문 감독 플랫폼은 레퍼런스 플랫폼의 계정을 따라 작동합니다. OKEX 시뮬레이션 봇 페이지에서, 참조 플랫폼 계정은 3 ETH 분기 암호화 마진 계약을 수동으로 배치합니다.
보트가 위치 변화를 감지하고 다음 동작을 하는 것을 볼 수 있습니다.
이제 우리가 방금 열었던 2개의 계약 포지션을 닫으려 합니다. 포지션을 닫은 후 포지션은 그림에서 나타납니다.
로봇이 따라와 2건의 계약을 체결했습니다.
전략은 최적화 없이 간단하고 이해하기 쉬운 방식으로 설계되었습니다. 개선된 부분은 또한 주문을 감독할 때 자산 탐지와 같은 세부 사항을 다루어야 합니다. 디자인을 단순화하기 위해 시장 주문은 주문 감독 주문에 사용됩니다. 전략은 학습 아이디어를 제공 할 뿐이며, 봇은 귀하의 필요에 따라 최적화 될 수 있습니다.
전략 주소:https://www.fmz.com/strategy/270012
여러분의 의견을 남길 수 있습니다.