Type/to search
8
Follow
1364
Followers
क्रिप्टोकरेंसी फ्यूचर्स के लिए मार्टिंगेल रणनीति डिजाइन
Discussions
Created 2021-07-02 14:35:34  Updated 2023-09-21 21:09:56
 22
 6556

img

क्रिप्टोकरेंसी फ्यूचर्स के लिए मार्टिंगेल रणनीति डिजाइन

हाल ही में, FMZ आधिकारिक समूह में मार्टिंगेल रणनीतियों पर कई चर्चाएँ हुई हैं, लेकिन प्लेटफ़ॉर्म पर डिजिटल मुद्रा अनुबंधों के लिए कई मार्टिंगेल रणनीतियाँ नहीं हैं। इसलिए, मैंने क्रिप्टोकरेंसी फ्यूचर्स के लिए एक सरल मार्टिंगेल रणनीति तैयार करने का यह अवसर लिया। इसे मार्टिन जैसी रणनीति क्यों कहा जाता है? क्योंकि मार्टिन रणनीति के संभावित जोखिम वास्तव में छोटे नहीं हैं, इसलिए इसे पूरी तरह से मार्टिन रणनीति के अनुसार डिज़ाइन नहीं किया गया है। हालाँकि, इस प्रकार की रणनीति में अभी भी काफी जोखिम है, और मार्टिंगेल रणनीति पैरामीटर सेटिंग्स जोखिमों से निकटता से संबंधित हैं, और जोखिमों को नजरअंदाज नहीं किया जाना चाहिए।

यह लेख मुख्य रूप से मार्टिन प्रकार की रणनीतियों के डिजाइन को समझाता है और उनसे सीखता है। रणनीति का विचार अपने आप में बहुत स्पष्ट है। FMZ के उपयोगकर्ता के रूप में, हम रणनीति डिजाइन पर अधिक विचार करते हैं।

कुल इक्विटी प्राप्त करें

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

इसलिए, हम विभिन्न एक्सचेंजों के अनुसार इस डेटा को प्राप्त करने के लिए फ़ंक्शन डिज़ाइन करते हैं:

// OKEX V5 获取总权益 function getTotalEquity_OKEX_V5() { 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 getTotalEquity_Binance() { var totalEquity = null var ret = exchange.GetAccount() if (ret) { try { totalEquity = parseFloat(ret.Info.totalWalletBalance) } catch(e) { Log("获取账户总权益失败!") return null } } return totalEquity }

कोड मेंtotalEquityयह वह सम्पूर्ण इक्विटी है जिसकी हमें आवश्यकता है। फिर हम कॉलिंग प्रविष्टि के रूप में एक फ़ंक्शन लिखते हैं और एक्सचेंज नाम के अनुसार संबंधित फ़ंक्शन को कॉल करते हैं।

function getTotalEquity() { var exName = exchange.GetName() if (exName == "Futures_OKCoin") { return getTotalEquity_OKEX_V5() } else if (exName == "Futures_Binance") { return getTotalEquity_Binance() } else { throw "不支持该交易所" } }

कुछ सहायक फ़ंक्शन डिज़ाइन करें

मुख्य फ़ंक्शन और मुख्य तर्क को डिज़ाइन करने से पहले। हमें अभी भी कुछ तैयारी करने और कुछ सहायक कार्यों को डिजाइन करने की आवश्यकता है।

  • सभी मौजूदा लंबित ऑर्डर रद्द करें

    function cancelAll() { while (1) { var orders = _C(exchange.GetOrders) if (orders.length == 0) { break } for (var i = 0 ; i < orders.length ; i++) { exchange.CancelOrder(orders[i].Id, orders[i]) Sleep(500) } Sleep(500) } }

    मेरा मानना ​​है कि जो लोग अक्सर FMZ रणनीति स्क्वायर पर रणनीति उदाहरण कोड देखते हैं, वे इस फ़ंक्शन से बहुत परिचित हैं। कई रणनीतियों ने समान डिज़ाइन का उपयोग किया है। इसका कार्य लंबित आदेशों की वर्तमान सूची प्राप्त करना और फिर उन्हें एक-एक करके रद्द करना है।

  • वायदा ऑर्डर ऑपरेशन

    function trade(distance, price, amount) { var tradeFunc = null if (distance == "buy") { tradeFunc = exchange.Buy } else if (distance == "sell") { tradeFunc = exchange.Sell } else if (distance == "closebuy") { tradeFunc = exchange.Sell } else { tradeFunc = exchange.Buy } exchange.SetDirection(distance) return tradeFunc(price, amount) } function openLong(price, amount) { return trade("buy", price, amount) } function openShort(price, amount) { return trade("sell", price, amount) } function coverLong(price, amount) { return trade("closebuy", price, amount) } function coverShort(price, amount) { return trade("closesell", price, amount) }

    वायदा कारोबार में चार दिशाएं हैं: लंबी स्थिति खोलना (ओपनलॉन्ग), छोटी स्थिति खोलना (ओपनशॉर्ट), लंबी स्थिति बंद करना (कवरलॉन्ग), और छोटी स्थिति बंद करना (कवरशॉर्ट)। इसलिए हमने इन परिचालनों के अनुरूप चार ऑर्डर फ़ंक्शन डिज़ाइन किए। यदि आप केवल ऑर्डर देने पर विचार करते हैं, तो कई आवश्यक कारक हैं: दिशा, ऑर्डर मूल्य और ऑर्डर मात्रा।
    इसलिए हमने एक कार्यक्रम भी तैयार किया जिसका नाम है:tradeसंभालने का कार्य方向(distance)下单价格(price)下单量(amount)सभी कार्य स्पष्ट हैं।
    लंबी स्थिति खोलने (ओपनलॉन्ग), छोटी स्थिति खोलने (ओपनशॉर्ट), लंबी स्थिति बंद करने (कवरलॉन्ग) और छोटी स्थिति बंद करने (कवरशॉर्ट) के फ़ंक्शन कॉल अंततः किसके द्वारा निष्पादित किए जाते हैंtradeयह फ़ंक्शन वास्तविक कार्य करता है, जो कि स्थापित दिशा, मूल्य और मात्रा के अनुसार वायदा एक्सचेंज पर ऑर्डर देना है।

मुख्य समारोह

रणनीति बहुत सरल है। वर्तमान मूल्य को आधार रेखा के रूप में उपयोग करें और वर्तमान मूल्य से ऊपर और नीचे एक निश्चित दूरी पर बिक्री आदेश (शॉर्ट) और खरीद आदेश (लॉन्ग) रखें। एक बार एक पक्ष निष्पादित होने के बाद, सभी शेष आदेश रद्द कर दिए जाएंगे, और फिर स्थिति मूल्य के आधार पर एक निश्चित दूरी पर एक नया समापन आदेश रखा जाएगा, और अद्यतन वर्तमान मूल्य पर एक वृद्धि आदेश रखा जाएगा, लेकिन वृद्धि आदेश ऑर्डर की मात्रा दोगुनी न करें।

  • प्रारंभिक कार्य
    क्योंकि हमें ऑर्डर देने की आवश्यकता है, इसलिए हमें ऑर्डर आईडी रिकॉर्ड करने के लिए दो वैश्विक चर की आवश्यकता है।

    var buyOrderId = null var sellOrderId = null

    फिर OKEX_V5 सिमुलेशन डिस्क का उपयोग करने का विकल्प रणनीति इंटरफ़ेस मापदंडों में डिज़ाइन किया गया है, इसलिए कोड में कुछ प्रसंस्करण करने की आवश्यकता है:

    var exName = exchange.GetName() // 切换OKEX V5模拟盘 if (isSimulate && exName == "Futures_OKCoin") { exchange.IO("simulate", true) }

    इंटरफ़ेस पैरामीटर में सभी जानकारी को रीसेट करने का विकल्प भी शामिल है, इसलिए कोड में संगत प्रसंस्करण भी होना चाहिए:

    if (isReset) { _G(null) LogReset(1) LogProfitReset() LogVacuum() Log("重置所有数据", "#FF0000") }

    हम केवल शाश्वत अनुबंध ही चलाते हैं, इसलिए इसे यहां हार्ड-कोड किया गया है तथा केवल शाश्वत अनुबंधों पर ही सेट किया गया है।

    exchange.SetContractType("swap")

    फिर हमें ऑर्डर की कीमतों और ऑर्डर की मात्रा की सटीकता पर भी विचार करना होगा। यदि सटीकता ठीक से सेट नहीं की गई है, तो रणनीति गणना प्रक्रिया के दौरान सटीकता खो जाएगी। यदि डेटा में कई दशमलव स्थान हैं, तो ऑर्डर को आसानी से हटाया जा सकता है। एक्सचेंज इंटरफ़ेस द्वारा अस्वीकृत कर दिया गया।

    exchange.SetPrecision(pricePrecision, amountPrecision) Log("设置精度", pricePrecision, amountPrecision)

    सरल डेटा पुनर्प्राप्ति फ़ंक्शन

    if (totalEq == -1 && !IsVirtual()) { var recoverTotalEq = _G("totalEq") if (!recoverTotalEq) { var currTotalEq = getTotalEquity() if (currTotalEq) { totalEq = currTotalEq _G("totalEq", currTotalEq) } else { throw "获取初始权益失败" } } else { totalEq = recoverTotalEq } }

    यदि आप रणनीति चलाते समय प्रारंभिक कुल खाता इक्विटी निर्दिष्ट करना चाहते हैं, तो आप पैरामीटर सेट कर सकते हैंtotalEqयदि यह पैरामीटर -1 पर सेट है, तो रणनीति संग्रहीत कुल इक्विटी डेटा को पढ़ेगी। यदि कोई संग्रहीत कुल इक्विटी डेटा नहीं है, तो वर्तमान पढ़ी गई कुल इक्विटी को रणनीति चल रही प्रगति की प्रारंभिक कुल इक्विटी के रूप में उपयोग किया जाएगा। यदि कुल यदि आप पैसा कमाते हैं, लेकिन आपकी कुल इक्विटी कम है, तो इसका मतलब है कि आपने पैसा खो दिया है। यदि कुल इक्विटी डेटा पढ़ा जाता है, तो इस डेटा का उपयोग करके चलना जारी रखें।

  • मुख्य तर्क
    प्रारंभिक कार्य पूरा होने के बाद, हम अंततः रणनीति के मुख्य तर्क पर पहुँच गए। स्पष्टीकरण की सुविधा के लिए, मैंने स्पष्टीकरण सीधे कोड टिप्पणियों में लिखा।

    while (1) { // 策略主要逻辑设计为一个死循环 var ticker = _C(exchange.GetTicker) // 首先读取当前行情信息,主要用到最新成交价 var pos = _C(exchange.GetPosition) // 读取当前持仓数据 if (pos.length > 1) { // 判断持仓数据,由于这个策略的逻辑,是不太可能同时出现多空持仓的,所以发现同时出现多空持仓就抛出错误 Log(pos) throw "同时有多空持仓" // 抛出错误,让策略停止 } // 根据状态而定 if (pos.length == 0) { // 根据持仓状态做出不同操作,pos.length == 0是当没有持仓时 // 未持仓了,统计一次收益 if (!IsVirtual()) { var currTotalEq = getTotalEquity() if (currTotalEq) { LogProfit(currTotalEq - totalEq, "当前总权益:", currTotalEq) } } buyOrderId = openLong(ticker.Last - targetProfit, amount) // 挂开多仓的买单 sellOrderId = openShort(ticker.Last + targetProfit, amount) // 挂开空仓的卖单 } else if (pos[0].Type == PD_LONG) { // 有多头持仓,挂单位置、数量有所不同 var n = 1 var price = ticker.Last buyOrderId = openLong(price - targetProfit * n, amount) sellOrderId = coverLong(pos[0].Price + targetProfit, pos[0].Amount) } else if (pos[0].Type == PD_SHORT) { // 有空头持仓,挂单位置、数量有所不同 var n = 1 var price = ticker.Last buyOrderId = coverShort(pos[0].Price - targetProfit, pos[0].Amount) sellOrderId = openShort(price + targetProfit * n, amount) } if (!sellOrderId || !buyOrderId) { // 如果有一边挂单失败就取消所有挂单,重来 cancelAll() buyOrderId = null sellOrderId = null continue } while (1) { // 挂单完成,开始监控订单 var isFindBuyId = false var isFindSellId = false var orders = _C(exchange.GetOrders) for (var i = 0 ; i < orders.length ; i++) { if (buyOrderId == orders[i].Id) { isFindBuyId = true } if (sellOrderId == orders[i].Id) { isFindSellId = true } } if (!isFindSellId && !isFindBuyId) { // 检测到买卖单都成交了 cancelAll() break } else if (!isFindBuyId) { // 检测到买单成交 Log("买单成交") cancelAll() break } else if (!isFindSellId) { // 检测到卖单成交 Log("卖单成交") cancelAll() break } LogStatus(_D()) Sleep(3000) } Sleep(500) }

संपूर्ण तर्क और डिजाइन समझाया गया है।

बैकटेस्टिंग

रणनीति को 19 मई को बाजार की स्थिति का अनुभव करने दें।

img

img

यह देखा जा सकता है कि मार्टिंगेल रणनीति में अभी भी कुछ जोखिम हैं।

आप वास्तविक ट्रेडिंग के लिए OKEX V5 डेमो आज़मा सकते हैं।

img

रणनीति पता: https://www.fmz.com/strategy/294957

रणनीतियाँ मुख्य रूप से सीखने के लिए उपयोग की जाती हैं, इसलिए वास्तविक धन का उपयोग सावधानी से करें ~!

Related Recommendations
Comment
All comments (20)

    梦大,想要請問這句
    if (!isFindSellId && !isFindBuyId) { // 检测到买卖单都成交了
    偵測訂單時,若快速上下插針同時成交了買賣單,那是否會拋出錯誤?

    4 years ago

    不会抛出错误。依然会取消所有挂单,跳出当前循环,然后继续挂单逻辑。瞬间都成交了就相当于吃到价差利润了。

    4 years ago

    另外就是合约的模式是全仓还是逐仓怎么设定?目前是啥模式呢

    5 years ago

    一般要用全仓吧。

    5 years ago

    杠杆可以在交易所具体设置,根据自身风险偏好。

    5 years ago

    既然开的是合约,为啥没有合约倍数的设定呢?买卖都是多少倍的呢

    5 years ago

    谢谢梦大,我终于能从头到尾看懂了,
    然后学会了挂单监控了,然后写了一个双边的马丁。两天时间,写了580行。。。。。
    谢谢梦大[抱拳]

    5 years ago

    云总 666!

    5 years ago

    img
    false true 交换下?

    5 years ago

    那这个变量名叫 isFindBuyId 就不合适了吧。 应该叫isNotFindBuyId了。

    5 years ago

    如果

    5 years ago

    所有者权益合计

    5 years ago

    需要止损吗

    5 years ago

    这策略没设计止损。。所以跑出来的曲线可以看到是一路往上的。

    5 years ago

    马丁,回测下了,归0

    5 years ago

    哈哈,马丁的归宿。
    本篇主要是教学策略设计,不用太在意收益。

    5 years ago

    开单数量那里没看懂呢= =,那个n永远都等于1

    5 years ago

    那个N是为了做之后的改动用的,比如想n倍距离加仓,暂时可以定1。

    5 years ago

    策略是多空双开吗?还是单开的

    5 years ago

    单开的。

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