Type/to search
8
Follow
1364
Followers
کریپٹو کرنسی حلقوں میں مقداری تجارت میں نئے بچے، براہ کرم اس پر ایک نظر ڈالیں - آپ کو کریپٹو کرنسی حلقوں میں مقداری تجارت کے قریب لے جانا (VIII)
Discussions
Created 2021-06-18 18:24:23  Updated 2024-12-04 21:16:56
 6
 4520

img

کریپٹو کرنسی حلقوں میں مقداری تجارت میں نئے بچے، براہ کرم اس پر ایک نظر ڈالیں - آپ کو کریپٹو کرنسی حلقوں میں مقداری تجارت کے قریب لے جانا (VIII)

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

مجھے پہلے آپ کو ایک سپائلر دینے دیں، حکمت عملی کام کر رہی ہے، اور میں تھوڑا پرجوش ہوں!

img

img

img

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

حکمت عملی کے ڈیزائن پر واپس، پچھلے مضمون میں کوڈ کی بنیاد پر، حکمت عملی کو اس کے ساتھ شامل کیا گیا ہے:

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

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

حکمت عملی کو تھوڑی دیر تک چلنے دیں~

تقریباً 3 دن تک جانچ کرنے کے بعد، قیمت کے فرق میں اتار چڑھاو دراصل قابل قبول ہے۔

img

img

img

آپ دیکھ سکتے ہیں کہ فنڈنگ ​​کی شرح سے کچھ آمدنی ہوتی ہے۔

img

آئیے حکمت عملی کے ماخذ کوڈ کا اشتراک کریں:

var arrNearContractType = strNearContractType.split(",") var arrFarContractType = strFarContractType.split(",") var nets = null var initTotalEquity = null var OPEN_PLUS = 1 var COVER_PLUS = 2 function createNet(begin, diff, initAvgPrice, diffUsagePercentage) { if (diffUsagePercentage) { diff = diff * initAvgPrice } var oneSideNums = 3 var up = [] var down = [] for (var i = 0 ; i < oneSideNums ; i++) { var upObj = { sell : false, price : begin + diff / 2 + i * diff } up.push(upObj) var j = (oneSideNums - 1) - i var downObj = { sell : false, price : begin - diff / 2 - j * diff } if (downObj.price <= 0) { // 价格不能小于等于0 continue } down.push(downObj) } return down.concat(up) } function createCfg(symbol) { var cfg = { extension: { layout: 'single', height: 300, col: 6 }, title: { text: symbol }, xAxis: { type: 'datetime' }, series: [{ name: 'plus', data: [] }] } return cfg } function formatSymbol(originalSymbol) { var arr = originalSymbol.split("-") return [arr[0] + "_" + arr[1], arr[0], arr[1]] } function main() { if (isSimulate) { exchange.IO("simulate", true) // 切换为模拟环境 Log("仅支持OKEX V5 API,切换为OKEX V5 模拟盘:") } else { exchange.IO("simulate", false) // 切换为实盘 Log("仅支持OKEX V5 API,切换为OKEX V5 实盘:") } if (exchange.GetName() != "Futures_OKCoin") { throw "支持OKEX期货" } // 初始化 if (isReset) { _G(null) LogReset(1) LogProfitReset() LogVacuum() Log("重置所有数据", "#FF0000") } // 初始化标记 var isFirst = true // 收益打印周期 var preProfitPrintTS = 0 // 总权益 var totalEquity = 0 var posTbls = [] // 持仓表格数组 // 声明arrCfg var arrCfg = [] _.each(arrNearContractType, function(ct) { arrCfg.push(createCfg(formatSymbol(ct)[0])) }) var objCharts = Chart(arrCfg) objCharts.reset() // 创建对象 var exName = exchange.GetName() + "_V5" var nearConfigureFunc = $.getConfigureFunc()[exName] var farConfigureFunc = $.getConfigureFunc()[exName] var nearEx = $.createBaseEx(exchange, nearConfigureFunc) var farEx = $.createBaseEx(exchange, farConfigureFunc) // 预先写入需要订阅的合约 _.each(arrNearContractType, function(ct) { nearEx.pushSubscribeSymbol(ct) }) _.each(arrFarContractType, function(ct) { farEx.pushSubscribeSymbol(ct) }) while (true) { var ts = new Date().getTime() // 获取行情数据 nearEx.goGetTickers() farEx.goGetTickers() var nearTickers = nearEx.getTickers() var farTickers = farEx.getTickers() if (!farTickers || !nearTickers) { Sleep(2000) continue } var tbl = { type : "table", title : "远期-近期差价", cols : ["交易对", "远期", "近期", "正对冲", "反对冲"], rows : [] } var subscribeFarTickers = [] var subscribeNearTickers = [] _.each(farTickers, function(farTicker) { _.each(arrFarContractType, function(symbol) { if (farTicker.originalSymbol == symbol) { subscribeFarTickers.push(farTicker) } }) }) _.each(nearTickers, function(nearTicker) { _.each(arrNearContractType, function(symbol) { if (nearTicker.originalSymbol == symbol) { subscribeNearTickers.push(nearTicker) } }) }) var pairs = [] _.each(subscribeFarTickers, function(farTicker) { _.each(subscribeNearTickers, function(nearTicker) { if (farTicker.symbol == nearTicker.symbol) { var pair = {symbol: nearTicker.symbol, nearTicker: nearTicker, farTicker: farTicker, plusDiff: farTicker.bid1 - nearTicker.ask1, minusDiff: farTicker.ask1 - nearTicker.bid1} pairs.push(pair) tbl.rows.push([pair.symbol, farTicker.originalSymbol, nearTicker.originalSymbol, pair.plusDiff, pair.minusDiff]) for (var i = 0 ; i < arrCfg.length ; i++) { if (arrCfg[i].title.text == pair.symbol) { objCharts.add([i, [ts, pair.plusDiff]]) } } } }) }) // 初始化 if (isFirst) { isFirst = false var recoveryNets = _G("nets") var recoveryInitTotalEquity = _G("initTotalEquity") if (!recoveryNets) { // 检查持仓 _.each(subscribeFarTickers, function(farTicker) { var pos = farEx.getFuPos(farTicker.originalSymbol, ts) if (pos.length != 0) { Log(farTicker.originalSymbol, pos) throw "初始化时有持仓" } }) _.each(subscribeNearTickers, function(nearTicker) { var pos = nearEx.getFuPos(nearTicker.originalSymbol, ts) if (pos.length != 0) { Log(nearTicker.originalSymbol, pos) throw "初始化时有持仓" } }) // 构造nets nets = [] _.each(pairs, function (pair) { farEx.goGetAcc(pair.farTicker.originalSymbol, ts) nearEx.goGetAcc(pair.nearTicker.originalSymbol, ts) var obj = { "symbol" : pair.symbol, "farSymbol" : pair.farTicker.originalSymbol, "nearSymbol" : pair.nearTicker.originalSymbol, "initPrice" : (pair.nearTicker.ask1 + pair.farTicker.bid1) / 2, "prePlus" : pair.farTicker.bid1 - pair.nearTicker.ask1, "net" : createNet((pair.farTicker.bid1 - pair.nearTicker.ask1), diff, (pair.nearTicker.ask1 + pair.farTicker.bid1) / 2, true), "initFarAcc" : farEx.getAcc(pair.farTicker.originalSymbol, ts), "initNearAcc" : nearEx.getAcc(pair.nearTicker.originalSymbol, ts), "farTicker" : pair.farTicker, "nearTicker" : pair.nearTicker, "farPos" : null, "nearPos" : null, } nets.push(obj) }) var currTotalEquity = getTotalEquity() if (currTotalEquity) { initTotalEquity = currTotalEquity } else { throw "初始化获取总权益失败!" } } else { // 恢复 nets = recoveryNets initTotalEquity = recoveryInitTotalEquity } } // 检索网格,检查是否触发交易 _.each(nets, function(obj) { var currPlus = null _.each(pairs, function(pair) { if (pair.symbol == obj.symbol) { currPlus = pair.plusDiff obj.farTicker = pair.farTicker obj.nearTicker = pair.nearTicker } }) if (!currPlus) { Log("没有查询到", obj.symbol, "的差价") return } // 检查网格,动态添加 while (currPlus >= obj.net[obj.net.length - 1].price) { obj.net.push({ sell : false, price : obj.net[obj.net.length - 1].price + diff * obj.initPrice, }) } while (currPlus <= obj.net[0].price) { var price = obj.net[0].price - diff * obj.initPrice if (price <= 0) { break } obj.net.unshift({ sell : false, price : price, }) } // 检索网格 for (var i = 0 ; i < obj.net.length - 1 ; i++) { var p = obj.net[i] var upP = obj.net[i + 1] if (obj.prePlus <= p.price && currPlus > p.price && !p.sell) { if (hedge(nearEx, farEx, obj.nearSymbol, obj.farSymbol, obj.nearTicker, obj.farTicker, hedgeAmount, OPEN_PLUS)) { // 正对冲开仓 p.sell = true } } else if (obj.prePlus >= p.price && currPlus < p.price && upP.sell) { if (hedge(nearEx, farEx, obj.nearSymbol, obj.farSymbol, obj.nearTicker, obj.farTicker, hedgeAmount, COVER_PLUS)) { // 正对冲平仓 upP.sell = false } } } obj.prePlus = currPlus // 记录本次差价,作为缓存,下次用于判断上穿下穿 // 增加其它表格输出 }) if (ts - preProfitPrintTS > 1000 * 60 * 5) { // 5分钟打印一次 var currTotalEquity = getTotalEquity() if (currTotalEquity) { totalEquity = currTotalEquity LogProfit(totalEquity - initTotalEquity, "&") // 打印动态权益收益 } // 检查持仓 posTbls = [] // 重置,更新 _.each(nets, function(obj) { var currFarPos = farEx.getFuPos(obj.farSymbol) var currNearPos = nearEx.getFuPos(obj.nearSymbol) if (currFarPos && currNearPos) { obj.farPos = currFarPos obj.nearPos = currNearPos } var posTbl = { "type" : "table", "title" : obj.symbol, "cols" : ["合约代码", "数量", "价格"], "rows" : [] } _.each(obj.farPos, function(pos) { posTbl.rows.push([pos.symbol, pos.amount, pos.price]) }) _.each(obj.nearPos, function(pos) { posTbl.rows.push([pos.symbol, pos.amount, pos.price]) }) posTbls.push(posTbl) }) preProfitPrintTS = ts } // 显示网格 var netTbls = [] _.each(nets, function(obj) { var netTbl = { "type" : "table", "title" : obj.symbol, "cols" : ["网格"], "rows" : [] } _.each(obj.net, function(p) { var color = "" if (p.sell) { color = "#00FF00" } netTbl.rows.push([JSON.stringify(p) + color]) }) netTbl.rows.reverse() netTbls.push(netTbl) }) LogStatus(_D(), "总权益:", totalEquity, "初始总权益:", initTotalEquity, " 浮动盈亏:", totalEquity - initTotalEquity, "\n`" + JSON.stringify(tbl) + "`" + "\n`" + JSON.stringify(netTbls) + "`" + "\n`" + JSON.stringify(posTbls) + "`") Sleep(interval) } } function getTotalEquity() { var totalEquity = null var ret = exchange.IO("api", "GET", "/api/v5/account/balance", "ccy=USDT") if (ret) { try { totalEquity = parseFloat(ret.data[0].details[0].eq) } catch(e) { Log("获取账户总权益失败!") return null } } return totalEquity } function hedge(nearEx, farEx, nearSymbol, farSymbol, nearTicker, farTicker, amount, tradeType) { var farDirection = null var nearDirection = null if (tradeType == OPEN_PLUS) { farDirection = farEx.OPEN_SHORT nearDirection = nearEx.OPEN_LONG } else { farDirection = farEx.COVER_SHORT nearDirection = nearEx.COVER_LONG } var nearSymbolInfo = nearEx.getSymbolInfo(nearSymbol) var farSymbolInfo = farEx.getSymbolInfo(farSymbol) nearAmount = nearEx.calcAmount(nearSymbol, nearDirection, nearTicker.ask1, amount * nearSymbolInfo.multiplier) farAmount = farEx.calcAmount(farSymbol, farDirection, farTicker.bid1, amount * farSymbolInfo.multiplier) if (!nearAmount || !farAmount) { Log(nearSymbol, farSymbol, "下单量计算错误:", nearAmount, farAmount) return } nearEx.goGetTrade(nearSymbol, nearDirection, nearTicker.ask1, nearAmount[0]) farEx.goGetTrade(farSymbol, farDirection, farTicker.bid1, farAmount[0]) var nearIdMsg = nearEx.getTrade() var farIdMsg = farEx.getTrade() return [nearIdMsg, farIdMsg] } function onexit() { Log("执行扫尾函数", "#FF0000") _G("nets", nets) _G("initTotalEquity", initTotalEquity) Log("保存数据:", _G("nets"), _G("initTotalEquity")) }

img

حکمت عملی کا عوامی پتہ: https://www.fmz.com/strategy/288559

حکمت عملی ایک ٹیمپلیٹ لائبریری کا استعمال کرتی ہے جسے میں نے خود لکھا ہے، اس لیے میں اسے عوامی نہیں کروں گا تاکہ اس ٹیمپلیٹ کو استعمال نہ کیا جا سکے۔

اگر آپ دلچسپی رکھتے ہیں، تو آپ جانچ کے لیے OKEX V5 سمولیشن ڈسک ترتیب دے سکتے ہیں۔
اوہ! ویسے اس حکمت عملی کو پیچھے نہیں دیکھا جا سکتا۔

Related Recommendations
Comment
All comments (6)

    时隔两年,梦总~这个策略如何设定不同交易对,不同的开仓数量

    3 years ago
    // 声明arrCfg var arrCfg = [] _.each(arrNearContractType, function(ct) { arrCfg.push(createCfg(formatSymbol(ct)[0])) })

    把hedgeAmount 这个参数也做类似这样的处理,把这个参数设计成一个字符串类似:100,200,330 。 这样100就对应第一个对冲组合,然后具体去使用就行了。

    3 years ago

    改到了币安来,但是下单那块不懂ok怎么操作的,下单还没改成功

    5 years ago

    下单那块可以自己封装一下,例子中用到了一个模板类库,没公开。

    5 years ago

    怎么可以在ok模拟盘上跑。。。我用那个插件好像不行啊。。。

    5 years ago

    什么插件 ?

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