이전 기사에서 우리는 간단한 헤지 전략을 함께 실행했고, 그 다음에는 이 전략을 업그레이드하는 방법을 배우게 될 것입니다. 전략의 변화는 크지 않지만 변경 사항에 대한 세부 사항은 주의가 필요합니다. 코드 내의 일부 장소의 정의는 이전 것과 달라졌습니다. 이해해야합니다.
A exchange -> B exchange
, B exchange -> A exchange
, 그리고 퍼진을 유발하는 수평선을 그립니다.line drawing class library
직접적으로 처리 할 수 있습니다. 이 장점은 사용하기 쉽다는 것입니다.template class library
FMZ의 기능다음으로, 이 디자인을 하나씩 구현해 보겠습니다.
예를 들어 Binance 스팟 실제 봇을 가져, 스팟 레버레이드 모드로 전환, 코드를 사용exchanges[i].IO
, 매개 변수를 입력trade_normal
지점별로 레버리지로 전환하고 입력trade_super_margin
레버리지 풀 포지션으로 전환하려면 백테스팅이 지원되지 않습니다. 이것은 실제 봇에서만 사용됩니다.
준비 단계의 시작에 추가main
기능:
// Switch leverage mode
for (var i = 0 ; i < exchanges.length ; i++) { // Traverse and detect all added exchange objects
if (exchanges[i].GetName() == "Binance" && marginType != 0) { //If the exchange object represented by the current i-index is Binance spot, and the parameter marginType of the strategy interface is not the option of "common currency", execute the switch operation
if (marginType == 1) {
Log(exchanges[i].GetName(), "Set to leveraged position-by-position")
exchanges[i].IO("trade_normal")
} else if (marginType == 2) {
Log(exchanges[i].GetName(), "Set to leveraged full position")
exchanges[i].IO("trade_super_margin")
}
}
}
이 전략은 바이낸스 스팟의 코인-투-코인 레버리지 모드를 전환하는 코드를 추가합니다. 따라서 전략 매개 변수에 대한 스위치 설정은 바이낸스 스팟에서만 유효합니다.
이미 포장 된 그림 템플릿을 사용하는 것이 매우 쉽습니다. 우리가 사용하는 템플릿 이름은Line Drawing Library
FMZ 플랫폼 전략 광장에서 직접 검색하면 얻을 수 있습니다.
또는 링크를 직접 클릭하세요:https://www.fmz.com/strategy/27293이 템플릿의 복사 페이지로 이동합니다.
이 템플릿 클래스 라이브러리를 자신의 전략 라이브러리로 복사하기 위해 버튼을 클릭합니다.
다음에는 전략 편집 페이지의 템플릿 컬럼에서 사용할 템플릿 클래스 라이브러리를 확인할 수 있습니다. 템플릿을 확인한 후 전략을 저장하면 전략이 이 템플릿을 참조합니다. 이것은 템플릿 클래스 라이브러리의 사용에 대한 간략한 설명입니다. 이 전략은 이미 이 템플릿을 참조했기 때문에 작업을 반복할 필요가 없습니다. 이 전략을 전략 광장에 복사하면Line Drawing Library
전략 편집 페이지의 템플릿 바에 참조되었습니다.
우리는 주로Line Drawing Library
그래프를 그리기 위해서요.
우리는A->B
, 확산B->A
, 그리고 스프레드의 트리거 라인입니다. 우리는 위의 그림과 같이 두 개의 곡선 (현행 A에서 B, B에서 A 스프레드), 두 개의 수평선 (트리거 스프레드 라인) 을 그리어야 합니다.
왜냐하면 우리는 일방적인 헤지링을 설계하고 싶어하기 때문입니다.A->B
그리고B->A
우리는 이전 기사에서 본 디자인을 사용할 수 없습니다.
이전 기사 에서:
var targetDiffPrice = hedgeDiffPrice
if (diffAsPercentage) {
targetDiffPrice = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentage
}
하나의 트리거 스프레드만 있습니다.targetDiffPrice
- 네
여기서 우리는 코드를 변환해야 합니다. 먼저 매개 변수를 변환해야 합니다.
그러면 코드를 수정합니다:
var targetDiffPriceA2B = hedgeDiffPriceA2B
var targetDiffPriceB2A = hedgeDiffPriceB2A
if (diffAsPercentage) {
targetDiffPriceA2B = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageA2B
targetDiffPriceB2A = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageB2A
}
이 방법으로, 차이 트리거 라인은 이전targetDiffPrice
2번으로targetDiffPriceA2B
, targetDiffPriceB2A
- 그래요
다음 단계는 도표에 이 데이터를 그리는 것입니다. 라인 드로잉 라이브러리의 드로잉 라인 함수를 사용하여요.
// drawing
$.PlotHLine(targetDiffPriceA2B, "A->B") // The first parameter of this function is the value of the horizontal line in the Y-axis direction, and the second parameter is the display text
$.PlotHLine(targetDiffPriceB2A, "B->A")
전략이 실행될 때, 이런 차트가 있습니다.
다음으로 실시간 스프레드 곡선을 그리는 것을 피하기 위해 선을 지나치게 그리십시오. 실시간 스프레드 데이터의 곡선을 그리는 코드를 균형을 확인합니다.
if (ts - lastKeepBalanceTS > keepBalanceCyc * 1000) {
nowAccs = _C(updateAccs, exchanges)
var isBalance = keepBalance(initAccs, nowAccs, [depthA, depthB])
cancelAll()
if (isBalance) {
lastKeepBalanceTS = ts
if (isTrade) {
var nowBalance = _.reduce(nowAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
var initBalance = _.reduce(initAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
LogProfit(nowBalance - initBalance, nowBalance, initBalance, nowAccs)
isTrade = false
}
}
$.PlotLine("A2B", depthA.Bids[0].Price - depthB.Asks[0].Price) // Draw real-time spread curves
$.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price) // The first parameter is the name of the curve, and the second parameter is the value of the curve at the current moment, that is, the value in the Y-axis direction at the current moment
}
이 방법으로, 드로잉 코드는 4줄에 불과하며, 전략이 실행시 그래프를 표시할 수 있습니다.
앞서 언급했듯이 스프레드 트리거 라인은 두 개로 수정되었으며,A->B
그리고B->A
따라서 이전 주문 가격 알고리즘을 사용할 수 없으며 시장 가격에 슬립 가격을 추가하는 방법을 사용합니다.
if (depthA.Bids[0].Price - depthB.Asks[0].Price > targetDiffPriceA2B && Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount) >= minHedgeAmount) { // A -> B market conditions are met
var priceSell = depthA.Bids[0].Price - slidePrice
var priceBuy = depthB.Asks[0].Price + slidePrice
var amount = Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount)
if (nowAccs[0].Stocks > minHedgeAmount && nowAccs[1].Balance * 0.8 / priceSell > minHedgeAmount) {
amount = Math.min(amount, nowAccs[0].Stocks, nowAccs[1].Balance * 0.8 / priceSell, maxHedgeAmount)
Log("trigger A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks) // Tips
hedge(exB, exA, priceBuy, priceSell, amount)
cancelAll()
lastKeepBalanceTS = 0
isTrade = true
}
} else if (depthB.Bids[0].Price - depthA.Asks[0].Price > targetDiffPriceB2A && Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount) >= minHedgeAmount) { // B -> A market conditions are met
var priceBuy = depthA.Asks[0].Price + slidePrice
var priceSell = depthB.Bids[0].Price - slidePrice
var amount = Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount)
if (nowAccs[1].Stocks > minHedgeAmount && nowAccs[0].Balance * 0.8 / priceBuy > minHedgeAmount) {
amount = Math.min(amount, nowAccs[1].Stocks, nowAccs[0].Balance * 0.8 / priceBuy, maxHedgeAmount)
Log("trigger B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks) //Tips
hedge(exA, exB, priceBuy, priceSell, amount)
cancelAll()
lastKeepBalanceTS = 0
isTrade = true
}
}
구매 및 판매 가격이 두 개의 데이터로 분리되기 때문에 헤지 함수는hedge
또한 수정되어야 합니다.
function hedge(buyEx, sellEx, priceBuy, priceSell, amount) {
var buyRoutine = buyEx.Go("Buy", priceBuy, amount)
var sellRoutine = sellEx.Go("Sell", priceSell, amount)
Sleep(500)
buyRoutine.wait()
sellRoutine.wait()
}
또한 이 변경 사항에 근거한 몇 가지 작은 조정도 있습니다. 여기서 반복하지 않겠습니다. 자세한 내용은 코드에서 볼 수 있습니다.
전략에 상호 작용을 추가하여 전략이 실시간으로 스프레드 트리거 라인을 수정 할 수 있습니다. 이것은 반 자동 전략의 설계 요구 사항입니다. 전략 상호 작용 설계도 매우 간단합니다. 먼저 전략 편집 페이지에서 전략에 상호 작용 컨트롤을 추가합니다.
두 개의 컨트롤을 추가, 하나는 A2B와 하나 B2A라고 합니다. 컨트롤 입력 상자에 값을 입력 한 후, 입력 상자 오른쪽의 버튼을 클릭합니다. 명령어는 즉시 전략에 전송됩니다, 예를 들어: 값을 입력123
입력 상자에서A2B
버튼을 누르면 즉시 전략에 명령이 보내집니다.
A2B:123
전략 코드에서 대화형 탐지 및 처리 코드를 설계합니다.
// interact
var cmd = GetCommand() // Every time the loop is executed here, it checks whether there is an interactive command, and returns to an empty string if not.
if (cmd) { // An interactive command was detected, such as A2B:123
Log("command received:", cmd)
var arr = cmd.split(":") // Split out the interactive control name and the value in the input box, arr[0] is A2B, arr[1] is 123
if (arr[0] == "A2B") { // Determine whether the triggered interactive control is A2B
Log("Modify the parameters of A2B, ", diffAsPercentage ? "The parameter is the difference percentage" : "The parameter is the difference:", arr[1])
if (diffAsPercentage) {
hedgeDiffPercentageB2A = parseFloat(arr[1]) // Modify the trigger spread line
} else {
hedgeDiffPriceA2B = parseFloat(arr[1]) // Modify the trigger spread line
}
} else if (arr[0] == "B2A") { // Triggered control detected is B2A
Log("Modify the parameters of B2A, ", diffAsPercentage ? "The parameter is the difference percentage" : "The parameter is the difference:", arr[1])
if (diffAsPercentage) {
hedgeDiffPercentageA2B = parseFloat(arr[1])
} else {
hedgeDiffPriceB2A = parseFloat(arr[1])
}
}
}
상태 표시줄 데이터를 더 조직적이고 쉽게 관찰 할 수 있도록하십시오.
var tbl = {
"type" : "table",
"title" : "data",
"cols" : ["exchange", "coin", "freeze coin", "denominated currency", "freeze denominated currency", "trigger spread", "current spread"],
"rows" : [],
}
tbl.rows.push(["A:" + exA.GetName(), nowAccs[0].Stocks, nowAccs[0].FrozenStocks, nowAccs[0].Balance, nowAccs[0].FrozenBalance, "A->B:" + targetDiffPriceA2B, "A->B:" + (depthA.Bids[0].Price - depthB.Asks[0].Price)])
tbl.rows.push(["B:" + exB.GetName(), nowAccs[1].Stocks, nowAccs[1].FrozenStocks, nowAccs[1].Balance, nowAccs[1].FrozenBalance, "B->A:" + targetDiffPriceB2A, "B->A:" + (depthB.Bids[0].Price - depthA.Asks[0].Price)])
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
백테스팅은 테스트 전략, 예비 탐지 기능에 불과하며 많은 버그가 백테스팅 단계에서 실제로 테스트 될 수 있습니다. 백테스팅 결과에 너무 많은 관심을 기울이는 것은 필요하지 않습니다. 최종 전략은 여전히 실제 환경에서 테스트되어야합니다.
전략 소스 코드:https://www.fmz.com/strategy/302834