एफएमजेड लाइब्रेरी में पिछले लेखों में, हमने क्रम और स्थिति के लिए कई प्रकार की सिंक्रनाइज़ेशन रणनीतियों को डिज़ाइन किया है।
ये ऑर्डर और पोजीशन सिंक्रनाइज़ेशन को प्राप्त करने के लिए एक रणनीति में संदर्भ खातों और सिंक्रनाइज़ेड खातों का प्रबंधन करते हैं। और आज हम एक अलग डिजाइन की कोशिश करेंगे, हम एफएमजेड क्वांट ट्रेडिंग प्लेटफॉर्म के शक्तिशाली विस्तारित एपीआई इंटरफ़ेस के आधार पर ऑर्डर सिंक्रनाइज़ेशन प्रबंधन प्रणाली डिजाइन करेंगे।
सबसे पहले, हमें कुछ अच्छे सुझावों और जरूरतों की आवश्यकता है। ऊपर दिए गए दो पिछले क्रम और स्थिति सिंक्रनाइज़ेशन रणनीतियों में, जिनमें कई स्पष्ट कमियां हैं, जिन पर हम एक साथ चर्चा करेंगे।
समाधान:
FMZOrder Synchronous Server
Real Bot में रणनीति). फिर बस FMZ विस्तारित API KEY (ध्यान दें कि यह एक्सचेंज खाते की API KEY नहीं है) और ऑर्डर सिंक्रोनस सर्वर वास्तविक बॉट आईडी को संदर्भ खाते के मालिक (ऑर्डर लीडर) को प्रदान करें.
जब संदर्भ खाते के मालिक (ऑर्डर अनुयायियों) वास्तविक बॉट (संदर्भ खाता)Order Synchronization Management System Class Library (Single Server)
इस लेख में दी गई प्रणाली में) एक संकेत भेजता है, सिंक्रनाइज़ेशन खाते के मालिक का वास्तविक बॉट व्यापार संकेत प्राप्त करेगा और स्वचालित रूप से अगला आदेश देगा।
Order Synchronization Management System Class Library (Single Server)
इस लेख में दी गई प्रणाली में रणनीति), ताकि संदर्भ खाते के मालिक (ऑर्डर-लीडर) इस टेम्पलेट क्लास लाइब्रेरी को सीधे अपनी रणनीति में एम्बेड कर सकें ताकि क्रम और स्थिति सिंक्रनाइज़ेशन का कार्य प्राप्त हो सके।तो इस प्रणाली में 2 भाग होते हैंः
एक बार जब हम अपनी आवश्यकताओं को परिभाषित कर लेते हैं, तो चलिए डिजाइन करना शुरू करते हैं!
ध्यान दें कि यह एक रणनीति नहीं है. यह FMZ का एक टेम्पलेट क्लास लाइब्रेरी है. एक टेम्पलेट क्लास लाइब्रेरी की अवधारणा को FMZ एपीआई प्रलेखन में खोजा जा सकता है और हम इसे फिर से नहीं दोहराएंगे.
टेम्पलेट वर्ग पुस्तकालय कोडः
// Global variables
var keyName_label = "label"
var keyName_robotId = "robotId"
var keyName_extendAccessKey = "extendAccessKey"
var keyName_extendSecretKey = "extendSecretKey"
var fmzExtendApis = parseConfigs([config1, config2, config3, config4, config5])
var mapInitRefPosAmount = {}
function parseConfigs(configs) {
var arr = []
_.each(configs, function(config) {
if (config == "") {
return
}
var strArr = config.split(",")
if (strArr.length != 4) {
throw "configs error!"
}
var obj = {}
obj[keyName_label] = strArr[0]
obj[keyName_robotId] = strArr[1]
obj[keyName_extendAccessKey] = strArr[2]
obj[keyName_extendSecretKey] = strArr[3]
arr.push(obj)
})
return arr
}
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
}
})
var timestamp = new Date().getTime()
return {ts: timestamp, long: longPosAmount, short: shortPosAmount}
}
function sendCommandRobotMsg (robotId, accessKey, secretKey, msg) {
// https://www.fmz.com/api/v1?access_key=xxx&secret_key=yyyy&method=CommandRobot&args=[186515,"ok12345"]
var url = "https://www.fmz.com/api/v1?access_key=" + accessKey + "&secret_key=" + secretKey + "&method=CommandRobot&args=[" + robotId + ',"' + msg + '"]'
Log(url)
var ret = HttpQuery(url)
return ret
}
function follow(nowPosAmount, symbol, ct, type, delta) {
var msg = ""
var nowAmount = type == PD_LONG ? nowPosAmount.long : nowPosAmount.short
if (delta > 0) {
// open the position
var tradeDirection = type == PD_LONG ? "buy" : "sell"
// send signals
msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)
} else if (delta < 0) {
// close the position
var tradeDirection = type == PD_LONG ? "closebuy" : "closesell"
if (nowAmount <= 0) {
Log("no positions found")
return
}
// send signals
msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)
} else {
throw "error"
}
if (msg) {
_.each(fmzExtendApis, function(extendApiConfig) {
var ret = sendCommandRobotMsg(extendApiConfig[keyName_robotId], extendApiConfig[keyName_extendAccessKey], extendApiConfig[keyName_extendSecretKey], msg)
Log("call the CommandRobot interface, ", "label:", extendApiConfig[keyName_label], ", msg:", msg, ", ret:", ret)
Sleep(1000)
})
}
}
$.PosMonitor = function(exIndex, symbol, ct) {
var ts = new Date().getTime()
var ex = exchanges[exIndex]
// judge the type of ex
var exName = ex.GetName()
var isFutures = exName.includes("Futures_")
var exType = isFutures ? "futures" : "spot"
if (!isFutures) {
throw "only future-following is supported"
}
if (exType == "futures") {
// caching symbol ct
var buffSymbol = ex.GetCurrency()
var buffCt = ex.GetContractType()
// switch to the corresponding contract pair, contract code
ex.SetCurrency(symbol)
if (!ex.SetContractType(ct)) {
throw "SetContractType failed"
}
// monitor positions
var keyInitRefPosAmount = "refPos-" + exIndex + "-" + symbol + "-" + ct // refPos-exIndex-symbol-contractType
var initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
if (!initRefPosAmount) {
// no initialization data, initialize it
mapInitRefPosAmount[keyInitRefPosAmount] = getPosAmount(_C(ex.GetPosition), ct)
initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
}
// monitor
var nowRefPosAmount = getPosAmount(_C(ex.GetPosition), ct)
// calculate the position changes
var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long
var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short
// detect changes
if (!(longPosDelta == 0 && shortPosDelta == 0)) {
// Perform long positions
if (longPosDelta != 0) {
Log(ex.GetName(), ex.GetLabel(), symbol, ct, "Perform long position-following, changes in volume:", longPosDelta)
follow(nowRefPosAmount, symbol, ct, PD_LONG, longPosDelta)
}
// Perform short positions
if (shortPosDelta != 0) {
Log(ex.GetName(), ex.GetLabel(), symbol, ct, "Perform short position-following, changes in volume:", shortPosDelta)
follow(nowRefPosAmount, symbol, ct, PD_SHORT, shortPosDelta)
}
// Update after performing the order-following operation
mapInitRefPosAmount[keyInitRefPosAmount] = nowRefPosAmount
}
// restore symbol ct
ex.SetCurrency(buffSymbol)
ex.SetContractType(buffCt)
} else if (exType == "spot") {
// Spots
}
}
$.getTbl = function() {
var tbl = {
"type" : "table",
"title" : "synchronization of data",
"cols" : [],
"rows" : []
}
// construct the table headers
tbl.cols.push("monitor the account: refPos-exIndex-symbol-contractType")
tbl.cols.push(`monitor the position: {"timestamp":xxx,"long positions":xxx,"short positions":xxx}`)
_.each(fmzExtendApis, function(extendApiData, index) {
tbl.cols.push(keyName_robotId + "-" + index)
})
// Write data in
_.each(mapInitRefPosAmount, function(initRefPosAmount, key) {
var arr = [key, JSON.stringify(initRefPosAmount)]
_.each(fmzExtendApis, function(extendApiData) {
arr.push(extendApiData[keyName_robotId])
})
tbl.rows.push(arr)
})
return tbl
}
// Example of the strategy call that references the template class library
function main() {
// Clear all logs
LogReset(1)
// Switch to OKEX demo to test
exchanges[0].IO("simulate", true)
// Set the contract
exchanges[0].SetCurrency("ETH_USDT")
exchanges[0].SetContractType("swap")
// Timed trading interval
var tradeInterval = 1000 * 60 * 3 // Trade for every three minutes to observe the order-following signals
var lastTradeTS = new Date().getTime()
while (true) {
// Other logic of the strategy...
// Simulated trading triggers for testing
var ts = new Date().getTime()
if (ts - lastTradeTS > tradeInterval) {
Log("Trade the simulation order-leading strategies, position changes", "#FF0000")
exchanges[0].SetDirection("buy")
exchanges[0].Buy(-1, 1)
lastTradeTS = ts
}
// Interface functions that use templates
$.PosMonitor(0, "ETH_USDT", "swap") // Multiple monitors can be set up to monitor different exchange objects on the order-following strategy
var tbl = $.getTbl()
// Display status bar
LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
Sleep(1000)
}
}
डिजाइन बहुत सरल है, वर्ग पुस्तकालय में 2 कार्यात्मक कार्य हैं। जब एफएमजेड प्लेटफॉर्म पर एक प्रोग्रामेटिक ट्रेडिंग रणनीति टेम्पलेट क्लास लाइब्रेरी का संदर्भ देती है।Order Synchronization Management System Class Library (Single Server)
. तो रणनीति निम्नलिखित कार्यों का उपयोग कर सकते हैं.
$.पोस मॉनिटर इस फ़ंक्शन का उद्देश्य रणनीति में विनिमय वस्तुओं की स्थिति परिवर्तन की निगरानी करना है और फिर टेम्पलेट के मापदंडों में सेट वास्तविक बॉट बाजार को ट्रेडिंग सिग्नल भेजना हैः ऑर्डर सिंक्रनाइज़ेशन मैनेजमेंट सिस्टम क्लास लाइब्रेरी (एकल सर्वर) ।
$.getTbl मॉनिटर किए गए सिंक्रनाइज़ेशन डेटा पर लौटें.
उपयोग का उदाहरण हैmain
ऑर्डर सिंक्रनाइज़ेशन मैनेजमेंट सिस्टम क्लास लाइब्रेरी (एकल सर्वर) टेम्पलेट का कार्यः
// Example of the strategy call that references the template class library
function main() {
// Clear all logs
LogReset(1)
// Switch to OKEX demo to test
exchanges[0].IO("simulate", true)
// Set the contract
exchanges[0].SetCurrency("ETH_USDT")
exchanges[0].SetContractType("swap")
// Timed trading interval
var tradeInterval = 1000 * 60 * 3 // Trade for every three minutes to observe the order-following signals
var lastTradeTS = new Date().getTime()
while (true) {
// Other logic of the strategy...
// Simulated trading triggers for testing
var ts = new Date().getTime()
if (ts - lastTradeTS > tradeInterval) {
Log("Trade the simulation order-leading strategies, position changes", "#FF0000")
exchanges[0].SetDirection("buy")
exchanges[0].Buy(-1, 1)
lastTradeTS = ts
}
// Interface functions by using templates
$.PosMonitor(0, "ETH_USDT", "swap") // Multiple monitors can be set up to monitor different exchange objects on the order-following strategy
var tbl = $.getTbl()
// Display status bar
LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
Sleep(1000)
}
}
एक टेम्पलेट क्लास लाइब्रेरी भी एक रणनीति वास्तविक बॉट खुद से बना सकते हैं, जो आमतौर पर टेम्पलेट क्लास लाइब्रेरी का परीक्षण करने के लिए प्रयोग किया जाता है, जैसे कि टेम्पलेट का परीक्षण। आप मान सकते हैं किmain
एक टेम्पलेट में फ़ंक्शन हैmain
अपनी एक रणनीति का कार्य।
परीक्षण कोड OKEX डेमो का उपयोग करके लिखा गया है, आपको FMZ पर OKEX डेमो एपीआई की को एक संदर्भ खाते (ऑर्डर-लीडिंग) के रूप में कॉन्फ़िगर करने की आवश्यकता है, और यह मुख्य फ़ंक्शन में डेमो पर स्विच करना शुरू कर देता है। फिर ट्रेडिंग जोड़ी को ETH_USDT पर सेट करें और कॉन्ट्रैक्ट को स्वैप करने के लिए सेट करें। फिर यह एक जबकि लूप में प्रवेश करता है। लूप में, रणनीति लेनदेन के ट्रिगरिंग का अनुकरण करने के लिए हर 3 मिनट में एक ऑर्डर रखा जाता है।$.PosMonitor(0, "ETH_USDT", "swap")
जबकि लूप में बुलाया जाता है, इस फ़ंक्शन का पहला पैरामीटर 0 पर पारित किया जाता है, जिसका अर्थ है कि thes एक्सचेंज ऑब्जेक्ट एक्सचेंजों की निगरानी करना[0], ETH_USDT ट्रेडिंग जोड़ी की निगरानी करना, स्वैप अनुबंध। फिर यह कॉल करेगा$.getTbl()
चार्ट की जानकारी प्राप्त करने के लिए, उपयोगLogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
स्थिति पट्टी पर प्रदर्शित चार्ट डेटा बनाने के लिए।
तो हम देख सकते हैं कि हम रणनीति एक निश्चित प्रजाति की स्थिति की निगरानी करने की क्षमता है, और स्थिति परिवर्तन का उपयोग कर संदेश भेजने के लिए कर सकते हैं$.PosMonitor(0, "ETH_USDT", "swap")
एक रणनीति में जो टेम्पलेट को संदर्भित करती है।
परीक्षण से पहले, हम रणनीति मापदंडों के डिजाइन का वर्णन करेंगेOrder Synchronization Management System Class Library (Single Server)
.
हमने अभी एक टेम्पलेट के इंटरफेस फ़ंक्शन का उपयोग करने के बारे में बात की है ताकि एक रणनीति को ऑर्डर-लीडिंग फ़ंक्शन के लिए अपग्रेड किया जा सके। स्थिति बदलने पर भेजे गए संकेत के बारे में क्या, यह किसके लिए भेजा जाएगा?
किसको भेजना है, यह प्रश्नOrder Synchronization Management System Class Library (Single Server)
.
हम देख सकते हैं कि वहाँ हैं 5 पैरामीटर, समर्थन करने के लिए 5 धक्का (यह अपने आप को विस्तारित किया जा सकता है अगर यह वृद्धि की जरूरत है), डिफ़ॉल्ट पैरामीटर खाली स्ट्रिंग्स हैं, यानी, संसाधित नहीं. विन्यास स्ट्रिंग प्रारूपः label,robotId,accessKey,secretKey
लेबल एक सिंक्रनाइज़ खाते के लिए एक लेबल, इसका उपयोग किसी खाते के लिए एक लेबल सेट करने के लिए किया जाता है जिसका नाम इच्छा पर सेट किया जा सकता है।
robotId
रोबोट आईडी,Order Synchronous Server
वास्तविक बॉट सिंक्रोनस खाते के मालिक द्वारा बनाया गया।
accessKey एफएमजेड की विस्तारित एपीआई अभिगम कुंजी
गुप्त कुंजी एफएमजेड का विस्तारित एपीआई गुप्त कुंजी
ऑर्डर सिंक्रनाइज़ेशन मैनेजमेंट सिस्टम (सिंक्रोनोस सर्वर) का अस्थायी कोडः
function main() {
LogReset(1)
while (true) {
var cmd = GetCommand()
if (cmd) {
// cmd: ETH_USDT,swap,buy,1
Log("cmd: ", cmd)
}
Sleep(1000)
}
}
हम देख सकते हैं कि सिंक्रनाइज़ किए गए खाते के मालिक के वास्तविक बॉट ने संदेश प्राप्त कियाःETH_USDT,swap,buy,1
..
फिर यह हमें ट्रेडिंग जोड़े, अनुबंध कोड, व्यापार दिशाओं, और जानकारी में राशि के आधार पर अगले चरण में अपने स्वयं के स्वचालित आदेश-अनुसरण करने की अनुमति देगा।
अब तक,Order Synchronization Management System (Synchronous Server)
अस्थायी कोड है, हम अगले अंक में इसके डिजाइन का अन्वेषण करना जारी रखेंगे।