4
ध्यान केंद्रित करना
1271
समर्थक

ट्रेडिंग रणनीति विकसित करने के अनुभव के बारे में बात करना

में बनाया: 2019-08-06 17:15:13, को अपडेट: 2023-10-20 20:06:49
comments   4
hits   3416

ट्रेडिंग रणनीति विकसित करने के अनुभव के बारे में बात करना

ट्रेडिंग रणनीति विकसित करने के अनुभव के बारे में बात करना

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

  • ## डेटा अधिग्रहण और प्रसंस्करण

आमतौर पर, रणनीति तर्क के आधार पर, बाजार डेटा प्राप्त करने के लिए निम्नलिखित विभिन्न इंटरफेस का उपयोग करना संभव है, क्योंकि रणनीति का ट्रेडिंग तर्क आमतौर पर बाजार डेटा द्वारा संचालित होता है (बेशक, कुछ रणनीतियाँ हैं जो बाजार को नहीं देखती हैं (जैसे निश्चित निवेश रणनीतियाँ)।

  • GetTicker: वास्तविक समय टिक जानकारी प्राप्त करें। इसका उपयोग आमतौर पर वर्तमान नवीनतम मूल्य, खरीद मूल्य और बिक्री मूल्य को शीघ्रता से प्राप्त करने के लिए किया जाता है।

  • GetDepth: ऑर्डर बुक गहराई उद्धरण प्राप्त करें। इसका उपयोग आमतौर पर प्रत्येक स्तर की कीमत और ऑर्डर के आकार को प्राप्त करने के लिए किया जाता है। हेजिंग रणनीतियों, मार्केट मेकिंग रणनीतियों आदि के लिए उपयोग किया जाता है।

  • GetTrade: बाजार में नवीनतम लेनदेन रिकॉर्ड प्राप्त करें। इसका उपयोग आम तौर पर अल्प अवधि में बाजार व्यवहार का विश्लेषण करने और बाजार में सूक्ष्म परिवर्तनों का विश्लेषण करने के लिए किया जाता है। आमतौर पर उच्च आवृत्ति रणनीतियों और एल्गोरिथम रणनीतियों में उपयोग किया जाता है।

  • GetRecords: बाजार K-लाइन डेटा प्राप्त करें। अक्सर प्रवृत्ति अनुसरण रणनीतियों में उपयोग किया जाता है। संकेतकों की गणना करने के लिए उपयोग किया जाता है।

  • दोष सहिष्णुता

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

    var depth = exchange.GetDepth()
    
    
    // depth.Asks[0].Price < depth.Bids[0].Price      卖一价格低于了买一价格,这种情况不可能存在于盘面上,
    //                                                因为卖出的价格低于买入的价格,必定已经成交了。
    // depth.Bids[n].Amount = 0                       订单薄买入列表第n档,订单量为0
    // depth.Asks[m].Price = 0                        订单薄卖出列表第m档,订单价格为0
    

    या exchange.GetDepth() सीधे शून्य मान लौटाता है।

    ऐसी कई विचित्र स्थितियाँ हैं। इसलिए, इन पूर्वानुमानित समस्याओं के लिए संगत प्रसंस्करण किया जाना चाहिए, और इस प्रकार के प्रसंस्करण समाधान को दोष-सहिष्णु प्रसंस्करण कहा जाता है।

    सामान्य दोष-सहिष्णुता दृष्टिकोण डेटा को त्यागना और उसे पुनः प्राप्त करना है।

    उदाहरण के लिए:

    function main () {
        while (true) {
            onTick()
            Sleep(500)
        }
    }
    
    
    function GetTicker () {
        while (true) {
            var ticker = exchange.GetTicker()
            if (ticker.Sell > ticker.Buy) {       // 以 检测卖一价格是不是小于买一价这个错误的容错处理为例,
                                                  // 排除这个错误,当前函数返回 ticker 。
                return ticker
            }
            Sleep(500)
        }
    }
    
    
    function onTick () {
        var ticker = GetTicker()                  // 确保获取到的 ticker 不会存在 卖一价格小于买一价格这种数据错误的情况。
        // ...  具体的策略逻辑
    }
    

    अन्य संभावित दोष-सहिष्णु प्रक्रियाओं को भी इसी प्रकार से संभाला जा सकता है। डिजाइन सिद्धांत यह है कि रणनीति तर्क को चलाने के लिए कभी भी गलत डेटा का उपयोग नहीं किया जाना चाहिए।

  • के-लाइन डेटा का उपयोग

    के-लाइन डाटा अधिग्रहण, कॉल:

    var r = exchange.GetRecords()
    

    प्राप्त K-लाइन डेटा एक सरणी है, जैसे कि यह:

    [
        {"Time":1562068800000,"Open":10000.7,"High":10208.9,"Low":9942.4,"Close":10058.8,"Volume":6281.887000000001},
        {"Time":1562072400000,"Open":10058.6,"High":10154.4,"Low":9914.5,"Close":9990.7,"Volume":4322.099},
        ...
        {"Time":1562079600000,"Open":10535.1,"High":10654.6,"Low":10383.6,"Close":10630.7,"Volume":5163.484000000004}
    ]
    

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

    उदाहरण के लिए, जब हम मूविंग एवरेज इंडिकेटर की गणना करते हैं, तो हम पास किए गए K-लाइन डेटा की विभिन्न अवधियों के आधार पर, संबंधित अवधि के मूविंग एवरेज की गणना करते हैं। उदाहरण के लिए, यदि दैनिक K-लाइन डेटा पास किया जाता है (एक K-लाइन बार एक दिन का प्रतिनिधित्व करता है), तो गणना किया गया संकेतक दैनिक मूविंग एवरेज है। इसी तरह, यदि K-लाइन डेटा को मूविंग एवरेज इंडिकेटर फ़ंक्शन में पास किया जाता है यदि 1 घंटे की अवधि है, तो गणना किया गया सूचक 1 घंटे का चलती औसत है।

    आमतौर पर जब हम संकेतकों की गणना करते हैं, तो हम अक्सर एक समस्या को अनदेखा कर देते हैं। अगर मैं 5-दिवसीय मूविंग एवरेज संकेतक की गणना करना चाहता हूं, तो हम पहले दैनिक K-लाइन डेटा तैयार करते हैं:

    var r = exchange.GetRecords(PERIOD_D1)  // 给GetRecords 函数传入参数 PERIOD_D1就是指定获取日K线,
                                            // 具体函数使用可以参看:https://www.fmz.com/api#GetRecords
    

    दैनिक K-लाइन डेटा के साथ, हम मूविंग एवरेज इंडिकेटर की गणना कर सकते हैं। यदि हम 5-दिवसीय मूविंग एवरेज की गणना करना चाहते हैं, तो हमें इंडिकेटर फ़ंक्शन के इंडिकेटर पैरामीटर को 5 पर सेट करना होगा।

    var ma = TA.MA(r, 5)        // TA.MA() 就是指标函数,用来计算均线指标,第一个参数设置刚才获取的日K线数据r,
                                // 第二个参数设置5,计算出来的就是5日均线,其它指标函数同理。
    

    हमने एक संभावित समस्या को नजरअंदाज कर दिया है। क्या होगा यदि आर-डे के-लाइन डेटा में के-लाइन बार की संख्या 5 से कम है? क्या हम एक वैध 5-दिवसीय मूविंग एवरेज इंडिकेटर की गणना कर सकते हैं? इसका उत्तर निश्चित रूप से ‘नहीं’ है। क्योंकि मूविंग एवरेज इंडिकेटर का कार्य एक निश्चित संख्या में के-लाइन बार के समापन मूल्यों का औसत ज्ञात करना है।

    ट्रेडिंग रणनीति विकसित करने के अनुभव के बारे में बात करना

    इसलिए, संकेतक डेटा की गणना करने के लिए K-लाइन डेटा और संकेतक फ़ंक्शन का उपयोग करने से पहले, यह निर्धारित करना आवश्यक है कि K-लाइन डेटा में K-लाइन कॉलम की संख्या संकेतक गणना (संकेतक पैरामीटर) के लिए शर्तों को पूरा करती है या नहीं।

    इसलिए, 5-दिवसीय मूविंग एवरेज की गणना करने से पहले, निर्णय लेना आवश्यक है। पूरा कोड इस प्रकार है:

    function CalcMA () {
        var r = _C(exchange.GetRecords, PERIOD_D1)     // _C() 是容错函数,目的就是避免 r 为 null , 具体可以查询文档:https://www.fmz.com/api#_C
        if (r.length > 5) {
            return TA.MA(r, 5)                         // 用均线指标函数 TA.MA 计算出均线数据,做为函数返回值,返回。
        }
    
    
        return false 
    }
    
    
    function main () {
        var ma = CalcMA()
        Log(ma)
    }
    

    ट्रेडिंग रणनीति विकसित करने के अनुभव के बारे में बात करना

    बैकटेस्टिंग से पता चलता है: [null,null,null,null,4228.7,4402.9400000000005, … ]

    यह देखा जा सकता है कि गणना किए गए 5-दिवसीय चलती औसत संकेतकों में से पहले चार शून्य हैं, क्योंकि के-लाइन स्तंभों की संख्या 5 से कम है और औसत की गणना नहीं की जा सकती है। 5वीं कैंडलस्टिक से इसकी गणना की जा सकती है।

  • के-लाइन अपडेट का मूल्यांकन करने के लिए सुझाव

    जब हम कुछ रणनीतियाँ लिखते हैं, तो अक्सर ऐसा परिदृश्य होता है कि हमें प्रत्येक K-लाइन चक्र पूरा होने पर कुछ ऑपरेशनों को संसाधित करने या कुछ लॉग प्रिंट करने की आवश्यकता होती है। हम यह कार्यक्षमता कैसे प्राप्त करें? शुरुआती लोगों के लिए जिनके पास प्रोग्रामिंग का कोई अनुभव नहीं है, वे शायद यह नहीं सोच पा रहे होंगे कि इससे निपटने के लिए किस तंत्र का उपयोग किया जाए। यहाँ हम आपको सीधे कुछ टिप्स देंगे।

    हम यह निर्धारित कर सकते हैं कि K-लाइन कॉलम चक्र K-लाइन डेटा में समय विशेषता से शुरू करके पूरा हो गया है। हर बार जब हम K-लाइन डेटा प्राप्त करते हैं, तो हम अंतिम K-लाइन कॉलम के डेटा में समय विशेषता का निर्धारण करते हैं इस K-लाइन डेटा का। क्या यह विशेषता मान बदल गया है। यदि यह बदल गया है, तो इसका मतलब है कि एक नया K-लाइन कॉलम उत्पन्न हुआ है (यह साबित करते हुए कि नए उत्पन्न K-लाइन कॉलम का पिछला K-लाइन कॉलम चक्र बदल गया है यदि यह नहीं बदला है, तो इसका मतलब है कि कोई नया कैंडलस्टिक उत्पन्न नहीं हुआ है (वर्तमान अंतिम कैंडलस्टिक चक्र अभी तक पूरा नहीं हुआ है)।

    इसलिए हमें कैंडलस्टिक डेटा के अंतिम कैंडलस्टिक कॉलम का समय रिकॉर्ड करने के लिए एक चर की आवश्यकता है।

    var r = exchange.GetRecords()
    var lastTime = r[r.length - 1].Time       // lastTime 用来记录最后一根K线柱的时间。
    

    व्यावहारिक अनुप्रयोगों में, संरचना आमतौर पर इस प्रकार होती है:

    function main () {
        var lastTime = 0
        while (true) {
            var r = _C(exchange.GetRecords)
            if (r[r.length - 1].Time != lastTime) {
                Log("新K线柱产生")
                lastTime = r[r.length - 1].Time      // 一定要更新 lastTime ,这个至关重要。
    
    
                // ... 其它处理逻辑
                // ...
            }
    
    
            Sleep(500)
        }
    }
    

    ट्रेडिंग रणनीति विकसित करने के अनुभव के बारे में बात करना

    यह देखा जा सकता है कि बैकटेस्ट में, K-लाइन अवधि दिन पर सेट की जाती है (exchange.GetRecords फ़ंक्शन को पैरामीटर निर्दिष्ट किए बिना कॉल किया जाता है, और बैकटेस्ट के अनुसार सेट की गई K-लाइन अवधि डिफ़ॉल्ट पैरामीटर है)। जब भी कोई जब नया K-लाइन कॉलम प्रकट होता है, तो उसे A लॉग मुद्रित किया जाता है।

  • संख्यात्मक गणना

    • ### एक्सचेंज इंटरफ़ेस तक पहुंचने में लगने वाले समय की गणना करें

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

    function main () {
        while (true) {
            var beginTime = new Date().getTime()
            var ticker = exchange.GetTicker()
            var endTime = new Date().getTime()
    
    
            LogStatus(_D(), "GetTicker() 函数耗时:", endTime - beginTime, "毫秒")
            Sleep(1000)
        } 
    }
    

    सरल शब्दों में कहें तो, GetTicker फ़ंक्शन को कॉल करने के बाद दर्ज किए गए टाइमस्टैम्प को कॉल से पहले के टाइमस्टैम्प से घटाया जाता है ताकि बीते मिलीसेकंड की संख्या की गणना की जा सके, अर्थात GetTicker फ़ंक्शन को निष्पादित करने और परिणाम वापस करने में लगने वाला समय।

    • ### मानों पर ऊपरी और निचली सीमाएँ निर्धारित करने के लिए Math.min / Math.max का उपयोग करें

    यदि आप संख्यात्मक ऊपरी सीमा चाहते हैं, तो आप आमतौर पर सीमा निर्धारित करने के लिए Math.min का उपयोग करते हैं

    उदाहरण के लिए, विक्रय आदेश देते समय, आदेश राशि खाते में मौजूद सिक्कों की संख्या से अधिक नहीं होनी चाहिए। क्योंकि यदि यह खाते में उपलब्ध सिक्कों की संख्या से अधिक है, तो ऑर्डर देते समय एक त्रुटि की सूचना दी जाएगी।

    आमतौर पर इस तरह नियंत्रित किया जाता है: उदाहरण के लिए, आप 0.2 सिक्कों के लिए विक्रय आदेश देने की योजना बनाते हैं।

    var planAmount = 0.2
    var account = _C(exchange.GetAccount)
    var amount = Math.min(account.Stocks, planAmount)
    

    इससे यह सुनिश्चित होता है कि दिए जाने वाले ऑर्डर की राशि, खाते में उपलब्ध सिक्कों की संख्या से अधिक न हो।

    इसी प्रकार, Math.max का उपयोग किसी मान की निचली सीमा सुनिश्चित करने के लिए किया जाता है। यह आमतौर पर किस तरह के परिदृश्यों पर लागू होता है? आम तौर पर, एक्सचेंजों में कुछ ट्रेडिंग जोड़ों के लिए न्यूनतम ऑर्डर मात्रा सीमा होती है। यदि ऑर्डर मात्रा इस न्यूनतम ऑर्डर मात्रा से कम है, तो ऑर्डर अस्वीकार कर दिया जाएगा। इस तरह से आदेश असफल हो जायेगा. मान लें कि BTC के लिए न्यूनतम ऑर्डर मात्रा आमतौर पर 0.01 है। कभी-कभी ट्रेडिंग रणनीति यह गणना कर सकती है कि ऑर्डर मात्रा 0.01 से कम है, इसलिए हम न्यूनतम ऑर्डर मात्रा सुनिश्चित करने के लिए Math.max का उपयोग कर सकते हैं।

    • ### आदेश मात्रा और मूल्य परिशुद्धता नियंत्रण

    इस्तेमाल किया जा सकता है_परिशुद्धता को नियंत्रित करने के लिए N() फ़ंक्शन या SetPrecision फ़ंक्शन।

    SetPrecision() फ़ंक्शन को केवल एक बार सेट करने की आवश्यकता है, और सिस्टम स्वचालित रूप से ऑर्डर मात्रा और मूल्य मानों में अतिरिक्त दशमलव स्थानों को काट देगा।

    _N() फ़ंक्शन का उपयोग किसी मान को दशमलव स्थानों की एक निश्चित संख्या तक छोटा करने के लिए किया जाता है (सटीकता नियंत्रण)

    उदाहरण के लिए:

    var pi = _N(3.141592653, 2)
    Log(pi)
    

    पाई का मान 2 दशमलव स्थानों तक काटा गया है, जो है: 3.14

    विवरण के लिए API दस्तावेज़ देखें.

  • कुछ तर्क सेटिंग्स

    • ### समय निर्धारण: एक निश्चित समय अवधि में कुछ कार्य निष्पादित करना

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

    उदाहरण के लिए, इसका उपयोग निश्चित निवेश रणनीतियों में किया जाता है।

    var lastActTime = 0
    var waitTime = 1000 * 60 * 60 * 12   // 一天的毫秒数
    function main () {
        while (true) {
            var nowTime = new Date().getTime()
            if (nowTime - lastActTime > waitTime) {
                Log("执行定投")
                // ... 具体的定投操作,买入操作。
    
    
                lastActTime = nowTime
            }
    
    
            Sleep(500)
        }
    }
    

    यह एक सरल उदाहरण है.

    • ### रणनीतियों के लिए स्वचालित पुनर्प्राप्ति तंत्र डिजाइन करना

    आविष्कारक के क्वांटाइज्ड _G() फ़ंक्शन और एक्ज़िट सेव फ़ंक्शन का उपयोग करके, प्रगति से बाहर निकलने और उसे सहेजने तथा स्थिति को स्वचालित रूप से बहाल करने के लिए पुनः आरंभ करने के लिए एक रणनीति तैयार करना बहुत सुविधाजनक है।

    var hold = {
        price : 0, 
        amount : 0,
    }
    
    
    function main () {
        if (_G("hold")) {
            var ret = _G("hold")
            hold.price = ret.price
            hold.amount = ret.amount
            Log("恢复 hold:", hold)
        }
    
    
        var count = 1
        while (true) {
            // ... 策略逻辑
            // ... 策略运行中,可能开仓,交易,把开仓的持仓价格赋值给 hold.price ,开仓的数量赋值给 hold.amount,用以记录持仓信息。
    
    
            hold.price = count++     // 模拟一些数值
            hold.amount = count/10   // 模拟一些数值
    
    
            Sleep(500)
        }
    }
    
    
    function onexit () {    // 点击机器人上的停止按钮,会触发执行这个函数,执行完毕机器人停止。
        _G("hold", hold)
        Log("保存 hold:", JSON.stringify(hold))
    }
    

    ट्रेडिंग रणनीति विकसित करने के अनुभव के बारे में बात करना

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

ऊपर बताई गई रणनीतियाँ विकसित करने के लिए कुछ सुझाव हैं। मुझे उम्मीद है कि ये शुरुआती लोगों और रणनीति डेवलपर्स के लिए मददगार होंगे! सुधार का सबसे तेज़ तरीका अभ्यास है! मैं आप सभी के निरन्तर लाभ की कामना करता हूँ।