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

ڈیجیٹل کرنسی فیوچر ٹریڈنگ کی منطق پر کچھ خیالات

مسئلہ کا منظر نامہ

ایک طویل عرصے سے، ڈیجیٹل کرنسی ایکسچینج پوزیشن API انٹرفیس کے ڈیٹا میں تاخیر کا مسئلہ ہمیشہ مجھے پریشان کرتا رہا ہے۔ مجھے ابھی تک کوئی مناسب حل نہیں ملا ہے، لہذا میں اس مسئلے کو دوبارہ پیش کروں گا۔ عام طور پر کنٹریکٹ ایکسچینج کی طرف سے فراہم کردہ مارکیٹ آرڈر دراصل کاؤنٹر پارٹی قیمت ہے، لہذا بعض اوقات اس نام نہاد "مارکیٹ آرڈر" کو استعمال کرنا ناقابل اعتبار ہے۔ لہذا، جب ہم ڈیجیٹل کرنسی فیوچر ٹریڈنگ کی حکمت عملی لکھتے ہیں، تو ہم میں سے زیادہ تر حد کے آرڈرز کا استعمال کرتے ہیں۔ ہر آرڈر دینے کے بعد، ہمیں یہ دیکھنے کے لیے پوزیشن کو چیک کرنے کی ضرورت ہے کہ آیا آرڈر پر عمل ہوا ہے اور کیا متعلقہ پوزیشن پر فائز ہے۔ مسئلہ اس پوزیشن کی معلومات میں ہے اگر آرڈر پر عمل کیا جاتا ہے، تو ایکسچینج پوزیشن انفارمیشن انٹرفیس (یعنی ایکسچینج انٹرفیس تک رسائی حاصل ہوتی ہے جب ہم ایکسچینج کو کہتے ہیں) میں نئی ​​کھلی ہوئی پوزیشن کی معلومات شامل ہونی چاہیے۔ ایکسچینج کی طرف سے واپس کیا گیا ڈیٹا پرانا ڈیٹا ہے، یعنی پوزیشن کی معلومات اس سے پہلے کہ آرڈر پر عمل درآمد ہو، پھر کوئی مسئلہ ہو گا۔ تجارتی منطق یہ سوچ سکتی ہے کہ آرڈر پر عمل نہیں ہوا ہے اور آرڈر دینا جاری رکھے گا۔ تاہم، ایکسچینج کے آرڈر پلیسمنٹ انٹرفیس میں کسی تاخیر کا سامنا نہیں ہوتا ہے، اس کے بجائے، لین دین بہت تیزی سے مکمل ہو جاتے ہیں، اور جیسے ہی وہ رکھے جاتے ہیں۔ اس کے نتیجے میں ایک سنگین نتیجہ نکلے گا کہ جب کوئی اوپننگ آپریشن شروع کیا جائے گا تو حکمت عملی بار بار آرڈر دے گی۔

حقیقی تجربہ

اس مسئلے کی وجہ سے، میں نے ایک ایسی حکمت عملی دیکھی ہے جس نے ایک پاگل مکمل لمبی پوزیشن کھولی ہے، خوش قسمتی سے، اس وقت مارکیٹ عروج پر تھی اور فلوٹنگ منافع ایک بار 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)