FMZ 플랫폼은 많은 사용자의 요구에 대응하여 최근 분산 플랫폼 dYdX를 지원했습니다. 전략이있는 친구들이 dYdX에서 행복하게 채굴 할 수 있습니다. 얼마 전, 나는 무작위 거래 전략을 쓰고 싶었습니다. 수익을 얻거나 얻지 못해도 상관 없습니다. 목적은 제 기술을 연습하고 전략 디자인을 가르치는 것입니다. 다음으로, 함께 무작위 플랫폼 전략을 설계하십시오. 전략의 성능에 대해 걱정하지 말고 전략 디자인을 배우십시오.
기사에서 전략의 채굴 스크린 샷.
좋은 채굴 전략 아이디어를 공유하는 친구들을 환영합니다!
브레인스토밍을 해 봅시다. 우리는 지표나 가격을 보지 않고 무작위로 주문을 할 수 있는 전략을 설계할 계획입니다. 주문은 단지 장기 및 단위, 즉 확률에 베팅하는 것뿐입니다. 그 다음 1에서 100까지의 무작위 숫자를 사용하여 장기 또는 단위를 결정합니다.
길게 하는 조건: 1에서 50까지의 무작위 숫자 단축 조건: 51에서 100까지의 무작위 숫자
롱과 쇼트 두 가지 모두 50개의 숫자가 필요합니다. 다음으로, 포지션을 닫는 방법에 대해 생각해 봅시다. 베팅이기 때문에, 이기는 또는 잃는 표준이 있어야합니다. 그런 다음, 이기는 또는 잃는 표준으로 고정된 스톱프로피트와 스톱러스를 설정하십시오. 스톱프로피트를 승리, 스톱러스를 잃는 것으로 간주하십시오. 스톱프로피트와 스톱러스의 적절성에 관해서는, 실제로 이익과 손실 비율, 그리고 승리율에도 영향을 미칩니다! (이렇게 전략을 설계하는 것이 효과적입니까? 긍정적 인 수학적 기대가 보장 될 수 있습니까? 어쨌든, 먼저 해 봅시다! 그것은 학습과 연구용이기 때문에!)
거래는 무료가 아닙니다. 그리고 슬립포인트와 수수료와 같은 요소가 있습니다. 우리의 무작위 거래 승률을 50% 이하로 끌어내기에 충분합니다. 포지션을 늘리기 위해 복수로 확장하는 것이 좋습니다. 베팅이기 때문에 10번이나 8번 연속적으로 손실할 확률은 매우 크지 않아야합니다. 그래서 첫 번째 거래에서 가능한 한 작은 오더 금액을 배치하는 디자인을 하고 싶습니다. 그러면 베팅을 잃으면 오더 금액을 증가시키고 무작위 주문을 계속합니다.
좋습니다. 전략은 이렇게 간단합니다.
디자인 소스 코드:
var openPrice = 0
var ratio = 1
var totalEq = null
var nowEq = null
function cancelAll() {
while (1) {
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
break
}
for (var i = 0 ; i < orders.length ; i++) {
exchange.CancelOrder(orders[i].Id, orders[i])
Sleep(500)
}
Sleep(500)
}
}
function main() {
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("reset all data", "#FF0000")
}
exchange.SetContractType(ct)
var initPos = _C(exchange.GetPosition)
if (initPos.length != 0) {
throw "Position detected when starting the strategy!"
}
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("setPrecision", pricePrecision, amountPrecision)
if (!IsVirtual()) {
var recoverTotalEq = _G("totalEq")
if (!recoverTotalEq) {
var currTotalEq = _C(exchange.GetAccount).Balance // equity
if (currTotalEq) {
totalEq = currTotalEq
_G("totalEq", currTotalEq)
} else {
throw "fail to obtain the initial equity"
}
} else {
totalEq = recoverTotalEq
}
} else {
totalEq = _C(exchange.GetAccount).Balance
}
while (1) {
if (openPrice == 0) {
// update account information, and calculate the profit
var nowAcc = _C(exchange.GetAccount)
nowEq = IsVirtual() ? nowAcc.Balance : nowAcc.Balance // equity
LogProfit(nowEq - totalEq, nowAcc)
var direction = Math.floor((Math.random()*100)+1) // 1~50 , 51~100
var depth = _C(exchange.GetDepth)
if (depth.Asks.length <= 2 || depth.Bids.length <= 2) {
Sleep(1000)
continue
}
if (direction > 50) {
// long
openPrice = depth.Bids[1].Price
exchange.SetDirection("buy")
exchange.Buy(Math.abs(openPrice) + slidePrice, amount * ratio)
} else {
// short
openPrice = -depth.Asks[1].Price
exchange.SetDirection("sell")
exchange.Sell(Math.abs(openPrice) - slidePrice, amount * ratio)
}
Log("place", direction > 50 ? "buy order" : "sell order", ",price:", Math.abs(openPrice))
continue
}
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
var pos = _C(exchange.GetPosition)
if (pos.length == 0) {
openPrice = 0
continue
}
// detect close positions
while (1) {
var depth = _C(exchange.GetDepth)
if (depth.Asks.length <= 2 || depth.Bids.length <= 2) {
Sleep(1000)
continue
}
var stopLossPrice = openPrice > 0 ? Math.abs(openPrice) - stopLoss : Math.abs(openPrice) + stopLoss
var stopProfitPrice = openPrice > 0 ? Math.abs(openPrice) + stopProfit : Math.abs(openPrice) - stopProfit
var winOrLoss = 0 // 1 win , -1 loss
// plot
$.PlotLine("bid", depth.Bids[0].Price)
$.PlotLine("ask", depth.Asks[0].Price)
// stop loss
if (openPrice > 0 && depth.Bids[0].Price < stopLossPrice) {
exchange.SetDirection("closebuy")
exchange.Sell(depth.Bids[0].Price - slidePrice, pos[0].Amount)
winOrLoss = -1
} else if (openPrice < 0 && depth.Asks[0].Price > stopLossPrice) {
exchange.SetDirection("closesell")
exchange.Buy(depth.Asks[0].Price + slidePrice, pos[0].Amount)
winOrLoss = -1
}
// stop profit
if (openPrice > 0 && depth.Bids[0].Price > stopProfitPrice) {
exchange.SetDirection("closebuy")
exchange.Sell(depth.Bids[0].Price - slidePrice, pos[0].Amount)
winOrLoss = 1
} else if (openPrice < 0 && depth.Asks[0].Price < stopProfitPrice) {
exchange.SetDirection("closesell")
exchange.Buy(depth.Asks[0].Price + slidePrice, pos[0].Amount)
winOrLoss = 1
}
// detect pending orders
Sleep(2000)
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
pos = _C(exchange.GetPosition)
if (pos.length == 0) {
if (winOrLoss == -1) {
ratio++
} else if (winOrLoss == 1) {
ratio = 1
}
break
}
} else {
// cancel pending orders
cancelAll()
Sleep(2000)
pos = _C(exchange.GetPosition)
// after canceling, update positions, which needs to be detected again
if (pos.length == 0) {
if (winOrLoss == -1) {
ratio++
} else if (winOrLoss == 1) {
ratio = 1
}
break
}
}
var tbl = {
"type" : "table",
"title" : "info",
"cols" : ["totalEq", "nowEq", "openPrice", "bid1Price", "ask1Price", "ratio", "pos.length"],
"rows" : [],
}
tbl.rows.push([totalEq, nowEq, Math.abs(openPrice), depth.Bids[0].Price, depth.Asks[0].Price, ratio, pos.length])
tbl.rows.push(["pos", "type", "amount", "price", "--", "--", "--"])
for (var j = 0 ; j < pos.length ; j++) {
tbl.rows.push([j, pos[j].Type, pos[j].Amount, pos[j].Price, "--", "--", "--"])
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
}
} else {
// cancel pending orders
// reset openPrice
cancelAll()
openPrice = 0
}
Sleep(1000)
}
}
전략 매개 변수
좋습니다. 전략은 이름이 필요합니다. 그리고 "어느 것이 더 큰지 추측하세요 (dYdX 버전) "라고 부르겠습니다.
백테스트는 참고용일 뿐이야! 주로 전략에 버그가 있는지 확인하기 위해서입니다. 바이낸스 미래에셋증권으로 백테스트를 합니다.
백테스트는 끝났어, 버그가 없네. 하지만 백테스트 시스템이 일치한 것 같네.
이 전략은 학습과 참조를 위한 것입니다.안 돼!! 안 돼진짜 로봇에 쓰라고!