लंबे समय से, डिजिटल मुद्रा विनिमय के स्थिति एपीआई इंटरफ़ेस की डेटा देरी समस्या ने मुझे हमेशा परेशान किया है। मुझे इस समस्या से निपटने का उचित तरीका नहीं मिला है। मुझे समस्या के दृश्य को पुनः पेश करने दें। आमतौर पर, अनुबंध विनिमय द्वारा प्रदान किए गए बाजार मूल्य आदेश वास्तव में समकक्ष मूल्य हैं, इसलिए कभी-कभी इस तथाकथित
इस समस्या के कारण, मैंने पागलपन से लंबी स्थिति से भरी एक रणनीति खोली है। सौभाग्य से, उस समय बाजार में तेजी आई, और फ्लोटिंग लाभ 10BTC से अधिक हो गया। सौभाग्य से, बाजार में तेजी से वृद्धि हुई। यदि यह तेजी से गिर गया, तो हम परिणाम की कल्पना कर सकते हैं।
समाधान 1 रणनीति को केवल एक ऑर्डर देने के लिए डिज़ाइन किया जा सकता है, और ऑर्डर की कीमत वर्तमान ट्रेडिंग प्रतिद्वंद्वी की कीमत और एक बड़ी स्लाइडिंग कीमत है, ताकि प्रतिद्वंद्वी के ऑर्डर की एक निश्चित गहराई ले जाया जा सके। इसका लाभ यह है कि केवल एक ऑर्डर रखा जाएगा, और इसे स्थिति की जानकारी के आधार पर न्याय नहीं किया जाएगा। इससे दोहराए गए ऑर्डर की समस्या से बचा जा सकता है, लेकिन कभी-कभी ऑर्डर देने से एक्सचेंज की मूल्य सीमा तंत्र को ट्रिगर किया जा सकता है जब मूल्य परिवर्तन अपेक्षाकृत बड़ा होता है, और स्लाइडिंग मूल्य को बढ़ाना संभव है और फिर भी सौदा करने में विफल रहता है, इस प्रकार अवसर खो देता है।
समाधान 2 एक्सचेंज के मार्केट प्राइस ऑर्डर फ़ंक्शन के साथ, कीमत को बाजार मूल्य ऑर्डर के रूप में एफएमजेड पर -1 पर स्थानांतरित किया जाता है। वर्तमान में, ओकेएक्स वायदा इंटरफ़ेस को वास्तविक बाजार मूल्य आदेश का समर्थन करने के लिए अपग्रेड किया गया है।
समाधान 3 हम अभी भी पिछले ट्रेडिंग लॉजिक का उपयोग करते हैं और मूल्य सीमा ऑर्डर के साथ ऑर्डर देते हैं, लेकिन हम स्थिति डेटा देरी के कारण होने वाली समस्या को हल करने की कोशिश करने के लिए ट्रेडिंग लॉजिक में कुछ डिटेक्शन जोड़ते हैं। जांचें कि क्या ऑर्डर बिना रद्द किए लंबित ऑर्डर की सूची से सीधे गायब हो गया है (लंबित ऑर्डर की सूची से गायब होने की दो संभावनाएं हैंः 1. रद्दीकरण और 2. भरा हुआ) । यदि ऐसी स्थिति का पता लगाया जाता है, और फिर से रखे गए ऑर्डर की मात्रा पिछले ऑर्डर के समान है, तो यह ध्यान रखना महत्वपूर्ण है कि क्या स्थिति डेटा में देरी है। स्थिति की जानकारी को फिर से प्राप्त करने के लिए प्रोग्राम को प्रतीक्षा लॉजिक में प्रवेश करने दें, या यहां तक कि प्रतीक्षा समय को ट्रिगर करने के लिए प्रतीक्षा समय की संख्या को अनुकूलित करना और बढ़ाना जारी रखें, यदि यह एक निश्चित संख्या में स्थानों से अधिक है, तो यह इंगित करता है कि इंटरफ़ेस डेटा देरी गंभीर है, जिससे ट्रेडिंग लॉजिक समाप्त हो जाता है।
// Parameters
/*
var MinAmount = 1
var SlidePrice = 5
var Interval = 500
*/
function GetPosition(e, contractType, direction) {
e.SetContractType(contractType)
var positions = _C(e.GetPosition);
for (var i = 0; i < positions.length; i++) {
if (positions[i].ContractType == contractType && positions[i].Type == direction) {
return positions[i]
}
}
return null
}
function Open(e, contractType, direction, opAmount) {
var initPosition = GetPosition(e, contractType, direction);
var isFirst = true;
var initAmount = initPosition ? initPosition.Amount : 0;
var nowPosition = initPosition;
var directBreak = false
var preNeedOpen = 0
var timeoutCount = 0
while (true) {
var ticker = _C(e.GetTicker)
var needOpen = opAmount;
if (isFirst) {
isFirst = false;
} else {
nowPosition = GetPosition(e, contractType, direction);
if (nowPosition) {
needOpen = opAmount - (nowPosition.Amount - initAmount);
}
// Check directBreak and the position remains unchanged
if (preNeedOpen == needOpen && directBreak) {
Log("Suspected position data is delayed, wait for 30 seconds", "#FF0000")
Sleep(30000)
nowPosition = GetPosition(e, contractType, direction);
if (nowPosition) {
needOpen = opAmount - (nowPosition.Amount - initAmount);
}
/*
timeoutCount++
if (timeoutCount > 10) {
Log("Suspected position is delayed for 10 consecutive times, and the order is failed!", "#FF0000")
break
}
*/
} else {
timeoutCount = 0
}
}
if (needOpen < MinAmount) {
break;
}
var amount = needOpen;
preNeedOpen = needOpen
e.SetDirection(direction == PD_LONG ? "buy" : "sell");
var orderId;
if (direction == PD_LONG) {
orderId = e.Buy(ticker.Sell + SlidePrice, amount, "open long positions", contractType, ticker);
} else {
orderId = e.Sell(ticker.Buy - SlidePrice, amount, "open short positions", contractType, ticker);
}
directBreak = false
var n = 0
while (true) {
Sleep(Interval);
var orders = _C(e.GetOrders);
if (orders.length == 0) {
if (n == 0) {
directBreak = true
}
break;
}
for (var j = 0; j < orders.length; j++) {
e.CancelOrder(orders[j].Id);
if (j < (orders.length - 1)) {
Sleep(Interval);
}
}
n++
}
}
var ret = {
price: 0,
amount: 0,
position: nowPosition
};
if (!nowPosition) {
return ret;
}
if (!initPosition) {
ret.price = nowPosition.Price;
ret.amount = nowPosition.Amount;
} else {
ret.amount = nowPosition.Amount - initPosition.Amount;
ret.price = _N(((nowPosition.Price * nowPosition.Amount) - (initPosition.Price * initPosition.Amount)) / ret.amount);
}
return ret;
}
function Cover(e, contractType, opAmount, direction) {
var initPosition = null;
var position = null;
var isFirst = true;
while (true) {
while (true) {
Sleep(Interval);
var orders = _C(e.GetOrders);
if (orders.length == 0) {
break;
}
for (var j = 0; j < orders.length; j++) {
e.CancelOrder(orders[j].Id);
if (j < (orders.length - 1)) {
Sleep(Interval);
}
}
}
position = GetPosition(e, contractType, direction)
if (!position) {
break
}
if (isFirst == true) {
initPosition = position;
opAmount = Math.min(opAmount, initPosition.Amount)
isFirst = false;
}
var amount = opAmount - (initPosition.Amount - position.Amount)
if (amount <= 0) {
break
}
var ticker = _C(exchange.GetTicker)
if (position.Type == PD_LONG) {
e.SetDirection("closebuy");
e.Sell(ticker.Buy - SlidePrice, amount, "close long positions", contractType, ticker);
} else if (position.Type == PD_SHORT) {
e.SetDirection("closesell");
e.Buy(ticker.Sell + SlidePrice, amount, "close short positions", contractType, ticker);
}
Sleep(Interval)
}
return position
}
$.OpenLong = function(e, contractType, amount) {
if (typeof(e) == "string") {
amount = contractType
contractType = e
e = exchange
}
return Open(e, contractType, PD_LONG, amount);
}
$.OpenShort = function(e, contractType, amount) {
if (typeof(e) == "string") {
amount = contractType
contractType = e
e = exchange
}
return Open(e, contractType, PD_SHORT, amount);
};
$.CoverLong = function(e, contractType, amount) {
if (typeof(e) == "string") {
amount = contractType
contractType = e
e = exchange
}
return Cover(e, contractType, amount, PD_LONG);
};
$.CoverShort = function(e, contractType, amount) {
if (typeof(e) == "string") {
amount = contractType
contractType = e
e = exchange
}
return Cover(e, contractType, amount, PD_SHORT);
};
function main() {
Log(exchange.GetPosition())
var info = $.OpenLong(exchange, "quarter", 100)
Log(info, "#FF0000")
Log(exchange.GetPosition())
info = $.CoverLong(exchange, "quarter", 30)
Log(exchange.GetPosition())
Log(info, "#FF0000")
info = $.CoverLong(exchange, "quarter", 80)
Log(exchange.GetPosition())
Log(info, "#FF0000")
}
टेम्पलेट का पताःhttps://www.fmz.com/strategy/203258
टेम्पलेट इंटरफ़ेस को उसी तरह से कहा जाता है जैसे$.OpenLong
, $.CoverLong
उपरोक्त मुख्य कार्य में।
टेम्पलेट एक बीटा संस्करण है, और आप सुझाव देने के लिए स्वागत कर रहे हैं. हम इसे अनुकूलित करने के लिए जारी रहेगा ताकि हम स्थिति डेटा देरी की समस्या से निपटने कर सकते हैं.