Type/to search
8
Follow
1364
Followers
زیر التواء آرڈر فیوچر ہیجنگ حکمت عملی کے ڈیزائن پر تحقیق اور مثالیں۔
Discussions
Created 2021-11-26 14:15:31  Updated 2023-09-20 09:24:03
 3
 2446

img

زیر التواء آرڈر فیوچر ہیجنگ حکمت عملی کے ڈیزائن پر تحقیق اور مثالیں۔

فیوچر اور اسپاٹ ہیجنگ کو ہمیشہ قیمت کے فرق کا پتہ لگانے اور قیمت کے فرق کو پورا ہونے پر ہیجنگ کے آرڈر لینے کے لیے ڈیزائن کیا گیا ہے۔ کیا اسے زیر التواء آرڈر ہیجنگ کے طور پر ڈیزائن کیا جا سکتا ہے؟ جواب ہاں میں ہے۔ آج میں قارئین کو زیر التواء آرڈر ہیجنگ کے لیے ایک ڈیزائن آئیڈیا اور کوڈ پروٹو ٹائپ متعارف کرواؤں گا۔

زیر التواء آرڈر ہیجنگ کے خیالات

جب مختلف بازاروں میں ایک ہی یا ایک ہی قسم کے بنیادی اثاثوں کی خرید و فروخت کے آرڈرز میں بڑا فرق ہوتا ہے تو ہیجنگ کا موقع ہوتا ہے۔ عام طور پر، ہم مارکیٹ آرڈرز لیں گے جو قیمت کے فرق کو پورا کرتے ہیں اور ہیج پوزیشن رکھتے ہیں۔ لہٰذا، ہیجنگ کے مقاصد دوگنا ہیں، پہلا آرڈر کی پوزیشنوں کو ہیج کرنا ہے، اور دوسرا یہ یقینی بنانا ہے کہ خرید و فروخت کی قیمتوں کے درمیان فرق ہماری توقعات کو ممکنہ حد تک پورا کرے۔ اس سلسلے میں پینڈنگ آرڈر ٹریڈنگ کا فائدہ یہ ہے کہ ٹرانزیکشن فیس کی شرح کم ہے۔ نقصان یہ ہے کہ ڈیل کو بند کرنا آسان نہیں ہے اور ایک ٹانگ پر ڈیل بند کرنا آسان ہے۔

پھر ہم مارکیٹ A کی آرڈر بک کے خرید آرڈر میں خرید آرڈر دینے کے لیے ٹریڈنگ آئیڈیا ڈیزائن کرتے ہیں، اور مارکیٹ B کی آرڈر بک کے سیل آرڈر میں سیل آرڈر دیتے ہیں۔ پھر ہم اپنے اکاؤنٹ کے زیر التواء آرڈرز کو چیک کرتے ہیں اور پتہ لگائے گئے زیر التواء آرڈرز پر کارروائی کرنے کے لیے اگلا قدم اٹھاتے ہیں۔ مثال کے طور پر، جب زیر التواء آرڈرز میں تبدیلی کا پتہ چلتا ہے، تو فیوچرز اور اسپاٹ ہیجنگ پوزیشنز فوری طور پر متوازن ہو جاتی ہیں، اور فیوچرز اور اسپاٹ پوزیشنز میں اوور فلونگ پوزیشنز کور یا بند ہو جاتی ہیں۔ ہیجڈ پوزیشنز میں اضافے کے مطابق، اگلے زیر التواء آرڈر اور مارکیٹ کے پہلے درجے کے درمیان فاصلے کو بتدریج ہیج کرنے اور قیمت میں بڑا فرق حاصل کرنے کے لیے ایڈجسٹ کیا جاتا ہے۔

ہیجنگ منطق img

کوڈ ڈیزائن

تبصرے براہ راست کوڈ میں لکھے گئے ہیں یہ مثال صرف حوالہ ڈیزائن کے لیے استعمال کی گئی ہے اور اس کا صرف OKEX V5 سمولیشن ڈسک پر تجربہ کیا گیا ہے۔ یہ مثال مکمل حکمت عملی نہیں ہے اور صرف حوالہ کے لیے ہے۔

javascript
// 临时参数 var fuContractType = "quarter" // 期货合约 var fuSymbol = "ETH_USDT" // 期货交易对 var spSymbol = "ETH_USDT" // 现货交易对 var minAmount = 0.1 // 每次交易量、最小交易量,币数 var step = 40 // 差价步长 var buff = 5 // 缓冲差价 var balanceType = "open" // 对于单腿成交平衡时, open 补仓 close 平仓 var depthManager = function(fuEx, spEx, fuCt, fuSymbol, spSymbol) { var self = {} self.fuExDepth = null self.spExDepth = null self.plusPrice = null self.minusPrice = null self.update = function() { spEx.SetCurrency(spSymbol) if (!IsVirtual()) { fuEx.SetCurrency(fuSymbol) } fuEx.SetContractType(fuCt) var fuRoutine = fuEx.Go("GetDepth") var spRoutine = spEx.Go("GetDepth") var fuDepth = fuRoutine.wait() var spDepth = spRoutine.wait() if (!fuDepth || !spDepth) { return false } self.fuExDepth = fuDepth self.spExDepth = spDepth if (fuDepth.Bids.length == 0 || fuDepth.Asks.length == 0 || spDepth.Bids.length == 0 || spDepth.Asks.length == 0) { return false } self.plusPrice = fuDepth.Bids[0].Price - spDepth.Asks[0].Price // futures Bid - spot Ask self.minusPrice = fuDepth.Asks[0].Price - spDepth.Bids[0].Price // futures Ask - spot Bid return true } self.getData = function() { return { "fuExDepth" : self.fuExDepth, "spExDepth" : self.spExDepth, "plusPrice" : self.plusPrice, "minusPrice" : self.minusPrice } } return self } var positionManager = function(fuEx, spEx, fuCt, fuSymbol, spSymbol, step, buffDiff, balanceType, initSpAcc) { var self = {} self.balanceType = balanceType self.depth = null self.level = 1 self.lastUpdateTs = 0 self.fuPos = [] self.spPos = [] self.initSpAcc = initSpAcc self.spAcc = null self.hedgePos = null self.hedgePosPrice = 0 self.minAmount = 0.01 self.offset = ["", 0] self.update = function() { spEx.SetCurrency(spSymbol) if (!IsVirtual()) { fuEx.SetCurrency(fuSymbol) } fuEx.SetContractType(fuCt) self.offset = ["", 0] var fuRoutine = fuEx.Go("GetPosition") var spRoutine = spEx.Go("GetAccount") var fuPos = fuRoutine.wait() var spAcc = spRoutine.wait() if (!fuPos || !spAcc) { return false } self.fuPos = fuPos self.spAcc = spAcc if (!self.initSpAcc) { return false } self.spPos = (spAcc.Stocks + spAcc.FrozenStocks) - (self.initSpAcc.Stocks + self.initSpAcc.FrozenStocks) // 当前减去最初,正数为做多 // 检测fuPos if (fuPos.length > 1) { return false } fuPosAmount = fuPos.length == 0 ? 0 : (fuPos[0].Type == PD_LONG ? fuPos[0].Amount : -fuPos[0].Amount) if ((fuPosAmount > 0 && self.spPos > 0) || (fuPosAmount < 0 && self.spPos < 0)) { return false } fuPosAmount = self.piece2Coin(fuPosAmount) self.hedgePos = (fuPosAmount == 0 || self.spPos == 0) ? 0 : (fuPosAmount < 0 && self.spPos > 0 ? Math.min(Math.abs(fuPosAmount), Math.abs(self.spPos)) : -Math.min(Math.abs(fuPosAmount), Math.abs(self.spPos))) var diffBalance = (spAcc.Balance + spAcc.FrozenBalance) - (self.initSpAcc.Balance + self.initSpAcc.FrozenBalance) if (self.hedgePos == 0) { self.hedgePosPrice = 0 } else { self.hedgePosPrice = fuPos[0].Price - (Math.abs(diffBalance) / Math.abs(self.spPos)) } self.offset[1] = fuPosAmount + self.spPos // 正数多头持仓溢出,负数空头持仓溢出 if (fuPosAmount > 0 && self.spPos < 0) { // 反套 self.offset[0] = "minus" } else if (fuPosAmount < 0 && self.spPos > 0) { self.offset[0] = "plus" } else if (fuPosAmount == 0 && self.spPos < 0) { self.offset[0] = "minus" } else if (fuPosAmount > 0 && self.spPos == 0) { self.offset[0] = "minus" } else if (fuPosAmount == 0 && self.spPos > 0) { self.offset[0] = "plus" } else if (fuPosAmount < 0 && self.spPos == 0) { self.offset[0] = "plus" } return true } self.getData = function() { return { "fuPos" : self.fuPos, "spPos" : self.spPos, "initSpAcc" : self.initSpAcc, "spAcc" : self.spAcc, "hedgePos" : self.hedgePos, "hedgePosPrice" : self.hedgePosPrice, } } self.keepBalance = function(depth) { var fuDepth = depth.fuExDepth var spDepth = depth.spExDepth if (self.offset[0] == "plus") { if (self.offset[1] >= self.minAmount) { if (self.balanceType == "close") { // 现货多头持仓多了,平现货多仓 spEx.Sell(-1, self.offset[1]) } else if (self.balanceType == "open") { // 现货多头持仓多了,开期货空头持仓 fuEx.SetDirection("sell") fuEx.Sell(-1, self.coin2Piece(Math.abs(self.offset[1]))) } } else if (self.offset[1] <= -self.minAmount) { if (self.balanceType == "close") { // 期货空头持仓多了,平期货空仓 fuEx.SetDirection("closesell") fuEx.Buy(-1, self.coin2Piece(Math.abs(self.offset[1]))) } else if (self.balanceType == "open") { // 期货空头持仓多了,开现货多头持仓 spEx.Buy(-1, spDepth.Asks[0].Price * Math.abs(self.offset[1])) } } return false } else if (self.offset[0] == "minus") { if (self.offset[1] >= self.minAmount) { if (self.balanceType == "close") { // 期货多头持仓多了,平期货多仓 fuEx.SetDirection("closebuy") fuEx.Sell(-1, self.coin2Piece(self.offset[1])) } else if (self.balanceType == "open") { // 期货多头持仓多了,开现货空头持仓 spEx.Sell(-1, self.offset[1]) } } else if (self.offset[1] <= -self.minAmount) { if (self.balanceType == "close") { // 现货空头持仓多了,平现货空仓 spEx.Buy(-1, spDepth.Asks[0].Price * Math.abs(self.offset[1])) } else if (self.balanceType == "open") { // 现货空头持仓多了,开期货多头持仓 fuEx.SetDirection("buy") fuEx.Buy(-1, self.coin2Piece(Math.abs(self.offset[1]))) } } return false } return true } self.process = function(depthManager) { var ts = new Date().getTime() var depth = depthManager.getData() var orders = self.getOrders() if (!orders) { return } self.depth = depth var fuOrders = orders[0] var spOrders = orders[1] if (fuOrders.length == 0 && spOrders.length == 0) { // 重置level if (self.hedgePos == 0) { self.level = 1 } else { self.level = Math.max(1, _N(self.hedgePos / self.minAmount, 0)) } // 限制最大持仓量 if (Math.abs(self.hedgePos) > 1) { return } // 挂单 var fuDepth = depth.fuExDepth var spDepth = depth.spExDepth self.update() if (self.hedgePos >= 0 && fuDepth.Bids[0].Price - spDepth.Asks[0].Price > 0) { // 正套 var distance = (step * self.level - (fuDepth.Asks[0].Price - spDepth.Bids[0].Price)) / 2 fuEx.SetDirection("sell") fuEx.Sell(fuDepth.Asks[0].Price + distance, self.coin2Piece(self.minAmount), fuDepth.Asks[0].Price, "挂单差价:", fuDepth.Asks[0].Price + distance - (spDepth.Bids[0].Price - distance)) spEx.Buy(spDepth.Bids[0].Price - distance, self.minAmount, spDepth.Bids[0].Price) } else if (self.hedgePos <= 0 && spDepth.Bids[0].Price - fuDepth.Asks[0].Price > 0) { // 反套 var distance = (step * self.level - (spDepth.Asks[0].Price - fuDepth.Bids[0].Price)) / 2 fuEx.SetDirection("buy") fuEx.Buy(fuDepth.Bids[0].Price - distance, self.coin2Piece(self.minAmount), fuDepth.Bids[0].Price, "挂单差价:", spDepth.Asks[0].Price + distance - (fuDepth.Bids[0].Price - distance)) spEx.Sell(spDepth.Asks[0].Price + distance, self.minAmount, spDepth.Asks[0].Price) } } else if (fuOrders.length == 1 && spOrders.length == 1) { var fuDepth = depth.fuExDepth var spDepth = depth.spExDepth // 判断位置 var isCancelAll = false if (self.hedgePos >= 0 && fuDepth.Bids[0].Price - spDepth.Asks[0].Price > 0) { // 正套 var distance = (step * self.level - (fuDepth.Asks[0].Price - spDepth.Bids[0].Price)) / 2 if (Math.abs(fuOrders[0].Price - (fuDepth.Asks[0].Price + distance)) > buffDiff || Math.abs(spOrders[0].Price - (spDepth.Bids[0].Price - distance)) > buffDiff) { isCancelAll = true } } else if (self.hedgePos <= 0 && spDepth.Bids[0].Price - fuDepth.Asks[0].Price > 0) { // 反套 var distance = (step * self.level - (spDepth.Asks[0].Price - fuDepth.Bids[0].Price)) / 2 if (Math.abs(spOrders[0].Price - (spDepth.Asks[0].Price + distance)) > buffDiff || Math.abs(fuOrders[0].Price - (fuDepth.Bids[0].Price - distance)) > buffDiff) { isCancelAll = true } } else { isCancelAll = true } if (isCancelAll) { self.cancelAll(fuEx, fuOrders) self.cancelAll(spEx, spOrders) self.lastUpdateTs = 0 } } else { self.cancelAll(fuEx, fuOrders) self.cancelAll(spEx, spOrders) self.lastUpdateTs = 0 } if (ts - self.lastUpdateTs > 1000 * 60 * 2) { self.update() self.keepBalance(depth) self.update() self.lastUpdateTs = ts } LogStatus(_D()) // 状态栏可以设计输出需要观察的数据、信息 } self.getOrders = function() { spEx.SetCurrency(spSymbol) if (!IsVirtual()) { fuEx.SetCurrency(fuSymbol) } fuEx.SetContractType(fuCt) var fuRoutine = fuEx.Go("GetOrders") var spRoutine = spEx.Go("GetOrders") var fuOrders = fuRoutine.wait() var spOrders = spRoutine.wait() if (!fuOrders || !spOrders) { return false } return [fuOrders, spOrders] } // 币转合约张数 self.coin2Piece = function(amount) { if (IsVirtual()) { if (fuEx.GetName() == "Futures_Binance") { return amount } else if (fuEx.GetName() == "Futures_OKCoin") { var price = (self.depth.fuExDepth.Bids[0].Price + self.depth.fuExDepth.Asks[0].Price) / 2 return _N(amount / (100 / price), 0) } else { throw "not support" } } if (fuEx.GetName() == "Futures_OKCoin") { if (fuEx.GetQuoteCurrency() == "USDT") { return _N(amount * 10, 0) } else if (fuEx.GetQuoteCurrency() == "USD") { var price = (self.depth.fuExDepth.Bids[0].Price + self.depth.fuExDepth.Asks[0].Price) / 2 return _N(amount / (100 / price), 0) } else { throw "not support" } } else { throw "not support" } } // 合约张数转币 self.piece2Coin = function(amount) { if (IsVirtual()) { if (fuEx.GetName() == "Futures_Binance") { return amount } else if (fuEx.GetName() == "Futures_OKCoin") { var price = (self.depth.fuExDepth.Bids[0].Price + self.depth.fuExDepth.Asks[0].Price) / 2 return amount * 100 / price } else { throw "not support" } } if (fuEx.GetName() == "Futures_OKCoin") { if (fuEx.GetQuoteCurrency() == "USDT") { return amount * 0.1 } else if (fuEx.GetQuoteCurrency() == "USD") { var price = (self.depth.fuExDepth.Bids[0].Price + self.depth.fuExDepth.Asks[0].Price) / 2 return amount * 100 / price } else { throw "not support" } } else { throw "not support" } } self.cancelAll = function(e, orders) { var isFirst = true while (true) { Sleep(500) if (orders && isFirst) { isFirst = false } else { orders = e.GetOrders() } if (!orders) { continue } else { for (var i = 0 ; i < orders.length ; i++) { e.CancelOrder(orders[i].Id, orders[i]) } } if (orders.length == 0) { break } } } self.CoverAll = function() { // 全部平仓 // 这里可以实现一个,一键平仓的功能 } self.setMinAmount = function(minAmount) { self.minAmount = minAmount } self.init = function() { while(!self.spAcc) { self.update() Sleep(1000) } if (!self.initSpAcc) { var positionManager_initSpAcc = _G("positionManager_initSpAcc") if (!positionManager_initSpAcc) { self.initSpAcc = self.spAcc _G("positionManager_initSpAcc", self.initSpAcc) } else { self.initSpAcc = positionManager_initSpAcc } } else { _G("positionManager_initSpAcc", self.initSpAcc) } // 打印初始信息 Log("self.initSpAcc:", self.initSpAcc.Balance, self.initSpAcc.FrozenBalance, self.initSpAcc.Stocks, self.initSpAcc.FrozenStocks) } self.init() return self } function main() { _G(null) // 清空持久化数据 LogReset(1) // 重置日志 // 以下代码可以切换OKEX模拟盘 // exchanges[0].IO("simulate", true) // exchanges[1].IO("simulate", true) var dm = depthManager(exchanges[0], exchanges[1], fuContractType, fuSymbol, spSymbol) var pm = positionManager(exchanges[0], exchanges[1], fuContractType, fuSymbol, spSymbol, step, buff, balanceType) pm.setMinAmount(minAmount) while (true) { if (!dm.update()) { Sleep(3000) continue } var cmd = GetCommand() if (cmd) { // 处理交互 Log("交互命令:", cmd) var arr = cmd.split(":") if (arr[0] == "") { pm.CoverAll() } } pm.process(dm) Sleep(5000) } }

بیک ٹیسٹ تجزیہ

img

img

یہ دیکھا جا سکتا ہے کہ آرڈر بہت کثرت سے دیے اور منسوخ کیے جاتے ہیں۔ بیک ٹیسٹنگ سسٹم کے حساب سے منافع کے حساب سے، فیوچر ایکسچینج اکاؤنٹ -0.01666 ETH کھو گیا، اور اسپاٹ ایکسچینج نے 842.23758 USDT کا منافع کمایا۔ بیک ٹیسٹ کے اختتام پر، ETH اسپاٹ قیمت 4252USDT تھی۔-0.01666 * 4252 = -70.83832000000001. سپاٹ منافع کے ساتھ مل کر، مجموعی صورت حال منافع بخش ہے۔

تاہم، یہ صرف ایک بیک ٹیسٹ ہے، اور اصل ٹریڈنگ میں مزید تفصیلات کو حل کرنا ضروری ہے۔

Related Recommendations
Comment
All comments (3)

    梦总,支持okex统一账户模式不 现货买入ETH 期货直接当保证金做空

    4 years ago

    您好, 支持OKEX V5接口的,支持这个模式。

    4 years ago

    4 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)