Type/to search
8
Follow
1369
Followers
डिजिटल मुद्रा वायदा कारोबार के तर्क पर कुछ विचार
Discussions
Created 2020-06-01 09:52:45  Updated 2023-10-08 19:41:25
 6
 2787

img

डिजिटल मुद्रा वायदा कारोबार के तर्क पर कुछ विचार

समस्या परिदृश्य

लंबे समय से, डिजिटल मुद्रा विनिमय स्थिति एपीआई इंटरफ़ेस की डेटा विलंब समस्या ने मुझे हमेशा परेशान किया है। मुझे अभी तक कोई उपयुक्त समाधान नहीं मिला है, इसलिए मैं इस समस्या को पुनः प्रस्तुत करूंगा। आमतौर पर अनुबंध एक्सचेंज द्वारा प्रदान किया गया बाजार आदेश वास्तव में प्रतिपक्ष मूल्य होता है, इसलिए कभी-कभी इस तथाकथित "बाजार आदेश" का उपयोग करना अविश्वसनीय होता है। इसलिए, जब हम डिजिटल मुद्रा वायदा व्यापार रणनीतियों को लिखते हैं, तो हम में से अधिकांश सीमा आदेशों का उपयोग करते हैं। प्रत्येक ऑर्डर देने के बाद, हमें यह देखने के लिए स्थिति की जांच करनी होगी कि क्या ऑर्डर निष्पादित हुआ है और क्या संबंधित स्थिति कायम है। समस्या इस स्थिति की जानकारी में निहित है। यदि ऑर्डर निष्पादित किया जाता है, तो एक्सचेंज स्थिति सूचना इंटरफ़ेस (यानी, एक्सचेंज इंटरफ़ेस वास्तव में एक्सेस किया जाता है जब हम एक्सचेंज.गेटपोजिशन को कॉल करते हैं) द्वारा लौटाए गए डेटा में नई खुली स्थिति की जानकारी शामिल होनी चाहिए। हालाँकि, यदि एक्सचेंज द्वारा लौटाया गया डेटा पुराना डेटा है, अर्थात, अभी दिए गए ऑर्डर के निष्पादित होने से पहले की स्थिति की जानकारी है, तो समस्या होगी। ट्रेडिंग लॉजिक यह सोच सकता है कि ऑर्डर निष्पादित नहीं हुआ है और ऑर्डर जारी रख सकता है। हालांकि, एक्सचेंज के ऑर्डर प्लेसमेंट इंटरफ़ेस में कोई देरी नहीं होती है। इसके बजाय, लेनदेन बहुत तेज़ी से पूरे होते हैं, और ऑर्डर दिए जाने के तुरंत बाद निष्पादित हो जाते हैं। इसका एक गंभीर परिणाम यह होगा कि जब कोई प्रारंभिक ऑपरेशन शुरू होगा तो रणनीति बार-बार ऑर्डर देगी।

वास्तविक अनुभव

इस समस्या के कारण, मैंने एक ऐसी रणनीति देखी है जिसने एक पागल पूर्ण लंबी स्थिति खोली। सौभाग्य से, उस समय बाजार में तेजी थी और फ्लोटिंग लाभ एक बार 10BTC से अधिक हो गया था। सौभाग्य से, बाजार तेजी से बढ़ रहा है, यदि इसमें गिरावट आती तो परिणाम पूर्वानुमानित होता।

हल करने का प्रयास करें

  • समाधान 1
    रणनीति का ऑर्डर लॉजिक केवल एक ऑर्डर देने के लिए डिज़ाइन किया जा सकता है, और ऑर्डर मूल्य उस समय प्रतिद्वंद्वी की कीमत के साथ-साथ एक बड़ा स्लिपेज होता है, ताकि एक निश्चित गहराई के प्रतिद्वंद्वी ऑर्डर ले सकें। ऐसा करने का लाभ यह है कि आप केवल एक ही ऑर्डर देते हैं और यह स्थिति संबंधी जानकारी पर आधारित नहीं होता है। इससे डुप्लिकेट ऑर्डर की समस्या से बचा जा सकता है, लेकिन कभी-कभी कीमत में बहुत अधिक परिवर्तन होने पर ऑर्डर देने से एक्सचेंज की मूल्य सीमा प्रणाली सक्रिय हो सकती है, और यह संभव है कि बड़ी स्लिपेज के बावजूद भी ऑर्डर निष्पादित नहीं होगा, जिससे अवसर चूक जाएगा। .

  • समाधान 2
    एक्सचेंज के मार्केट ऑर्डर फ़ंक्शन का उपयोग करें और FMZ पर -1 को मूल्य के रूप में पास करें, जो एक मार्केट ऑर्डर है। वर्तमान में, OKEX फ्यूचर्स इंटरफ़ेस को वास्तविक मार्केट ऑर्डर का समर्थन करने के लिए अपग्रेड किया गया है।

  • समाधान 3
    हम अभी भी पुराने ट्रेडिंग लॉजिक का उपयोग करते हैं और लिमिट ऑर्डर का उपयोग करके ऑर्डर प्लेस करते हैं, लेकिन हम पोजीशन डेटा विलंब के कारण उत्पन्न समस्या को हल करने के लिए ट्रेडिंग लॉजिक में कुछ डिटेक्शन जोड़ते हैं। जाँच करें कि क्या ऑर्डर देने के बाद ऑर्डर बिना रद्द किए लंबित ऑर्डर सूची से गायब हो जाता है (पेंडिंग ऑर्डर सूची से गायब होने की दो संभावनाएँ हैं: 1 रद्दीकरण और 2 पूर्ति)। यदि ऐसी स्थिति का पता चलता है और ऑर्डर की मात्रा और ऑर्डर वॉल्यूम पिछली बार जैसा ही है। इस समय, आपको इस बात पर ध्यान देना चाहिए कि क्या स्थिति डेटा में देरी हो रही है। प्रोग्राम को प्रतीक्षा तर्क में प्रवेश करने दें और स्थिति की जानकारी फिर से प्राप्त करें। आप संख्या को अनुकूलित और बढ़ाना भी जारी रख सकते हैं ट्रिगरिंग प्रतीक्षा की। यदि यह एक निश्चित संख्या से अधिक है, तो इसका मतलब है कि स्थिति इंटरफ़ेस डेटा में देरी हो रही है। समस्या गंभीर है, इसलिए इस लेनदेन का तर्क समाप्त हो गया है।

योजना 3 पर आधारित डिजाइन

javascript
// 参数 /* 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); } // 检测directBreak 并且持仓未变的情况 if (preNeedOpen == needOpen && directBreak) { Log("疑似仓位数据延迟,等待30秒", "#FF0000") Sleep(30000) nowPosition = GetPosition(e, contractType, direction); if (nowPosition) { needOpen = opAmount - (nowPosition.Amount - initAmount); } /* timeoutCount++ if (timeoutCount > 10) { Log("连续10次疑似仓位延迟,下单失败!", "#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, "开多仓", contractType, ticker); } else { orderId = e.Sell(ticker.Buy - SlidePrice, amount, "开空仓", 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, "平多仓", contractType, ticker); } else if (position.Type == PD_SHORT) { e.SetDirection("closesell"); e.Buy(ticker.Sell + SlidePrice, amount, "平空仓", 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
यह टेम्पलेट एक बीटा संस्करण है। सुझाव और टिप्पणियाँ स्वागत योग्य हैं। हम स्थिति डेटा विलंब की समस्या को हल करने के लिए इसे अनुकूलित करना जारी रखेंगे।

Related Recommendations
Comment
All comments (6)

    最好的办法应该是用ws,订单一有更新让服务器马上通知你,而不是一次次去询问

    6 years ago

    然鹅,WS接口也有不靠谱的时候,惹气麻烦比REST协议更甚。。

    6 years ago

    ws基本不会出问题,就算关键时候断线了,建立好重连机制也不会有问题;当然也有完全的解决方法,这你得自己摸索了

    6 years ago

    遇到过不稳定的WS ,各种故障。各有利弊吧。

    6 years ago

    碰到过这个问题,我的解决办法是记录一下下单前的持仓,然后下ioc订单后记录id,循环获取订单状态,如果是成交/部分成交,循环对比当前持仓和记录的持仓,当这两个值不同就跳出循环。

    6 years ago

    好的感谢, 学习下。

    6 years ago
  • 1
Forums
PINE Language
Get the app
iPhone Download
© 2015 - ∞ INVENTOR PTE LTD (SG)