पिछले लेख में, हमने एक साथ एक सरल हेज रणनीति लागू की, और फिर हम सीखेंगे कि रणनीति को कैसे अपग्रेड किया जाए। रणनीति में बहुत अधिक संशोधन नहीं हैं, लेकिन संशोधनों के विवरणों पर ध्यान देने की आवश्यकता है। कोड में कुछ स्थानों की परिभाषाओं को पिछले लोगों की तुलना में संशोधित किया गया है, जिन्हें विशेष रूप से समझने की आवश्यकता है।
A->B
औरB->A
, साथ ही क्षैतिज प्रसार ट्रिगर लाइनों, हम सीधे उपयोग कर सकते हैंchart plot library
; लाभ सरलता और उपयोग में आसानी है। यहाँ से, हम भी सीखते हैं कि कैसे FMZ के कार्य का उपयोग करने के लिएtemplate library
together.इसके बाद, आइए उन डिजाइनर विचारों को एक-एक करके लागू करें।
एक उदाहरण के रूप में Binance स्पॉट बॉट ले लो. स्पॉट मार्जिन मोड पर स्विच करने के लिए, कोड का उपयोग करेंexchanges[i].IO
, पैरामीटर आयात करेंtrade_normal
अलग-थलग मार्जिन पर स्विच करने और आयात करने के लिएtrade_super_margin
के लिए क्रॉस मार्जिन पर स्विच किया, जो बैकटेस्ट में समर्थित नहीं है. जो केवल बॉट्स में इस्तेमाल किया जा सकता है.
प्रारंभिक तैयारी के दौरानmain
कार्य, जोड़ेंः
// switch the margin mode
for (var i = 0 ; i < exchanges.length ; i++) { // traverse and detect all exchange objects added
if (exchanges[i].GetName() == "Binance" && marginType != 0) { // if the exchange object represented by the current index i is Binance Spot, and the parameter marginType on the strategy interface is not selected as the "common spot" option, execute the switch
if (marginType == 1) {
Log(exchanges[i].GetName(), "set to isolated margin")
exchanges[i].IO("trade_normal")
} else if (marginType == 2) {
Log(exchanges[i].GetName(), "set to cross margin")
exchanges[i].IO("trade_super_margin")
}
}
}
यहाँ रणनीति केवल Binance Spot के स्पॉट मार्जिन मोड को स्विच करने के लिए कोड जोड़ती है, इसलिए रणनीति मापदंडों में स्विच सेटिंग केवल Binance Spot के लिए काम करती है।
कैप्सुलेटेड प्लॉटिंग टेम्पलेट्स का उपयोग करना बहुत सरल है. टेम्पलेट नाम हम यहाँ उपयोग कर रहे हैंchart plot Library
आप सीधे एफएमजेड के स्क्वायर प्लेटफॉर्म पर इसकी खोज कर सकते हैं।
या आप सीधे लिंक पर क्लिक कर सकते हैंःhttps://www.fmz.com/strategy/27293टेम्पलेट के प्रतिलिपि पृष्ठ पर जाने के लिए।
बटन पर क्लिक करें और आप आसानी से अपने स्वयं के रणनीति पुस्तकालय के लिए टेम्पलेट कॉपी कर सकते हैं.
फिर, रणनीति संपादन पृष्ठ पर, आप टेम्पलेट कॉलम में उपयोग करने के लिए टेम्पलेट लाइब्रेरी की जांच कर सकते हैं. इसे जांचने के बाद रणनीति को सहेजें, और रणनीति इस टेम्पलेट का उपयोग करेगी. यह टेम्पलेट लाइब्रेरी के उपयोग का केवल एक संक्षिप्त विवरण है. चूंकि रणनीति ने पहले ही इस टेम्पलेट का संदर्भ दिया है, इसलिए ऑपरेशन को दोहराने की आवश्यकता नहीं है. जब आप स्क्वायर में रणनीति कोड की प्रतिलिपि बनाते हैं, तो आप देख सकते हैं किchart plot Library
रणनीति संपादन पृष्ठ के टेम्पलेट बार में संदर्भित किया गया है।
यहाँ हम मुख्य रूप से सीखते हैं किchart plot 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
दो, अर्थात्targetDiffPriceA2B
औरtargetDiffPriceB2A
.
अगला, आप चार्ट पर डेटा आकर्षित करने के लिए चार्ट प्लॉट पुस्तकालय के चार्ट प्लॉट फ़ंक्शन का उपयोग कर सकते हैं।
// plot
$.PlotHLine(targetDiffPriceA2B, "A->B") // the first parameter of the 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")
जब रणनीति चलाया जाता है, चार्ट इस तरह प्रदर्शित किया जाएगा.
इसके बाद, वास्तविक समय में फैलाव वक्र खींचें; ओवर ड्रॉइंग से बचने के लिए, संतुलन का पता लगाने में वास्तविक समय में फैलाव वक्रों को प्लॉट करने वाला कोड डालें। s
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) // plot real-time spread curves
$.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price) // the first parameter is the curve name, and the second parameter is the curve value 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 condition satisfied
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("triggerA->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks) // prompt message
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 condition satisfied
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("triggerB->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks) // prompt message
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
रणनीति कोड में इंटरैक्टिव डिटेक्शन और प्रोसेसिंग कोड डिजाइन करें।
// interaction
var cmd = GetCommand() // every time when the loop is operated here, it will detect whether an interactive command is sent; if no, return null string
if (cmd) { // interactive command detected, such as A2B:123
Log("received command:", cmd)
var arr = cmd.split(":") // split out the interactive control name and the value in the input box; arr[0] means A2B, and arr[1] means 123
if (arr[0] == "A2B") { // judge whether the triggered interactive control is A2B
Log("modify parameterA2B,", diffAsPercentage ? "parameter of spread ratio:" : "parameter of spread:", arr[1])
if (diffAsPercentage) {
hedgeDiffPercentageB2A = parseFloat(arr[1]) // modify the spread trigger line
} else {
hedgeDiffPriceA2B = parseFloat(arr[1]) // modify the spread trigger line
}
} else if (arr[0] == "B2A") { // detected the triggered control is B2A
Log("modify parameterB2A,", diffAsPercentage ? "parameter of spread ratio:" : "parameter of spread:", arr[1])
if (diffAsPercentage) {
hedgeDiffPercentageA2B = parseFloat(arr[1])
} else {
hedgeDiffPriceB2A = parseFloat(arr[1])
}
}
}
स्थिति पट्टी के डेटा को अधिक विनियमित और देखने में आसान बनाएं।
var tbl = {
"type" : "table",
"title" : "data",
"cols" : ["platform", "Currency", "frozenCurrrency", "quoteCurrency", "frozenQuoteCurrency", "triggerSpread", "currentSpread"],
"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