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

लेखक:अच्छाई, बनाया गयाः 2019-09-05 11:49:31, अद्यतन किया गयाः 2023-11-07 20:48:06

img

इस लेख का उद्देश्य रणनीति विकास में कुछ अनुभव का वर्णन करना है, साथ ही कुछ युक्तियां, जो पाठकों को व्यापार रणनीति विकास के प्रमुख बिंदु को जल्दी से समझने की अनुमति देंगी।

जब आप किसी रणनीति के डिजाइन में इसी तरह के विवरणों का सामना करते हैं, तो आप तुरंत एक उचित समाधान के साथ आ सकते हैं।

हम एफएमजेड क्वांट प्लेटफॉर्म का उपयोग व्याख्या, परीक्षण और अभ्यास के लिए एक उदाहरण के रूप में करते हैं।

रणनीति प्रोग्रामिंग भाषा हम जावास्क्रिप्ट का उपयोग करेंगे

ट्रेडिंग लक्ष्य के लिए, हम ब्लॉकचेन परिसंपत्ति बाजार (बीटीसी, ईटीएच, आदि) को अपना उद्देश्य मानते हैं

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

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

  • GetTicker: वास्तविक समय में टिक उद्धरण प्राप्त करें. आम तौर पर वर्तमान नवीनतम मूल्य को जल्दी से प्राप्त करने के लिए उपयोग किया जाता है, खरीदने की 1 कीमत, बेचने की 1 कीमत।

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

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

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

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

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

उदाहरण के लिए, कुछ बाज़ार इंटरफेस निष्पादित नहीं किए गए डेटा वापस करते हैंः

var depth = exchange.GetDepth()

// depth.Asks[0].Price < depth.Bids[0].Price "Selling 1" price is lower than "buying 1" price, this situation cannot exist on the market.
// Because the selling price is lower than the buying price, the order must have been executed.
// depth.Bids[n].Amount = 0 Order book buying list "nth" layer, order quantity is 0
// depth.Asks[m].Price = 0 Order book selling list "mth" layer, the order price is 0

या सीधे exchange.GetDepth() एक शून्य मान देता है.

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

त्रुटियों से निपटने का सामान्य तरीका डेटा को फेंकना और फिर से प्राप्त करना है।

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

function main () {
     while (true) {
         onTick()
         Sleep(500)
     }
}

function GetTicker () {
     while (true) {
         var ticker = exchange.GetTicker()
         if (ticker.Sell > ticker.Buy) { // Take the example of fault-tolerant processing that detects whether the "Selling 1" price is less than the "Buying 1" price.
                                               // Exclude this error, the current function returns "ticker".
             Return ticker
         }
         Sleep(500)
     }
}

function onTick () {
     var ticker = GetTicker() // Make sure the "ticker" you get doesn't exist the situation that "Selling 1" price is less than the "Buying 1" price.
     // ... specific strategy logic
}

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

डिजाइन का सिद्धांत यह है कि आप कभी भी गलत तर्क का उपयोग रणनीति तर्क को चलाने के लिए नहीं कर सकते।

के-लाइन डेटा का प्रयोग

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

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-लाइन डेटा का उपयोग चलती औसत, MACD आदि जैसे संकेतकों की गणना करने के लिए किया जाता है।

के-लाइन डेटा एक पैरामीटर (कच्चे माल डेटा) के रूप में पारित किया जाता है, और फिर संकेतक पैरामीटर संकेतक डेटा के कार्य की गणना करने के लिए सेट कर रहे हैं, जिसे हम संकेतक समारोह कहते हैं।

एफएमजेड क्वांट मात्रात्मक ट्रेडिंग प्लेटफॉर्म पर बहुत सारे संकेतक कार्य हैं।

उदाहरण के लिए, हम चलती औसत सूचक की गणना करते हैं। पारित K-लाइन डेटा के चक्र के अनुसार, हम संबंधित चक्र के चलती औसत की गणना करते हैं।

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

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

var r = exchange.GetRecords(PERIOD_D1) // Pass parameters to the "GetRecords" function "PERIOD_D1" specifies the day K line to be acquired.
                                       // Specific function using method can be seen at: https://www.fmz.com/api#GetRecords

दैनिक के-लाइन डेटा के साथ, हम चलती औसत संकेतक की गणना कर सकते हैं. अगर हम 5 दिन चलती औसत की गणना करना चाहते हैं, तो हमें संकेतक समारोह के संकेतक पैरामीटर को 5 पर सेट करना होगा.

var ma = TA.MA(r, 5) // "TA.MA()" is the indicator function used to calculate the moving average indicator. The first parameter sets the daily K-line data r just obtained.
                             // The second parameter is set to 5. The calculated 5-day moving average is the same as the other indicators.

हमने एक संभावित समस्या को नजरअंदाज कर दिया है. यदि के-लाइन डेटा में के लाइन बार की संख्या 5 से कम है, तो हम एक वैध 5-दिवसीय चलती औसत की गणना करने के लिए क्या कर सकते हैं?

जवाब यह है कि आप कुछ नहीं कर सकते।

क्योंकि चलती औसत सूचक एक निश्चित संख्या के के-लाइन बारों के समापन मूल्य का औसत है।

img

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

तो 5 दिन के चलती औसत की गणना करने से पहले, आप पहले यह जाँच करने के लिए है. पूरा कोड इस प्रकार हैः

function CalcMA () {
     var r = _C(exchange.GetRecords, PERIOD_D1) // _C() is a fault-tolerant function, the purpose is to avoid r being null, you can get more information at: https://www.fmz.com/api#_C
     if (r.length > 5) {
         Return TA.MA(r, 5) // Calculate the moving average data with the moving average indicator function "TA.MA", return it as a function return value.
     }

     Return false
}

function main () {
     var ma = CalcMA()
     Log(ma)
}

img

बैकटेस्ट प्रदर्शनः

[null,null,null,null,4228.7,4402.9400000000005, ... ]

आप 5 दिन के चलती औसत सूचक की गणना देख सकते हैं. पहले चार शून्य हैं, क्योंकि K-लाइन बार की संख्या 5 से कम है, और औसत की गणना नहीं की जा सकती है. जब आप 5 वें K-लाइन बार तक पहुँचते हैं, तो आप इसकी गणना कर सकते हैं.

के-लाइन अद्यतनों का आकलन करने के लिए युक्तियाँ

जब हम रणनीति लिखते हैं, तो अक्सर ऐसी स्थिति होती है, जैसे कि रणनीति को प्रत्येक के-लाइन चक्र पूरा होने पर कुछ संचालन संसाधित करने की आवश्यकता होती है, या कुछ लॉग प्रिंट करते हैं।

हम ऐसे कार्यों को कैसे लागू करते हैं? शुरुआती लोगों के लिए जिनके पास प्रोग्रामिंग का कोई अनुभव नहीं है, यह एक कष्टप्रद समस्या हो सकती है। यहां हम आपको समाधान देते हैं।

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

तो हम एक चर की जरूरत है K-लाइन डेटा के अंतिम K-लाइन पट्टी के समय को रिकॉर्ड करने के लिए.

var r = exchange.GetRecords()
var lastTime = r[r.length - 1].Time // "lastTime" used to record the last K-line bar time.

व्यवहार में, यह आमतौर पर मामला हैः

function main () {
     var lastTime = 0
     while (true) {
         var r = _C(exchange.GetRecords)
         if (r[r.length - 1].Time != lastTime) {
             Log ("New K-line bar generated")
             lastTime = r[r.length - 1].Time // Be sure to update "lastTime", this is crucial.

             // ... other processing logic
             // ...
         }

         Sleep(500)
     }
}

img

आप देख सकते हैं कि बैकटेस्ट में, के लाइन चक्र दैनिक पर सेट है (पैरामीटर निर्दिष्ट नहीं है जबexchange.GetRecordsfunction बुलाया जाता है, और backtest के अनुसार सेट किया गया K लाइन चक्र डिफ़ॉल्ट पैरामीटर है) जब भी नया K-लाइन बार दिखाई देता है, यह एक लॉग प्रिंट करता है.

संख्यात्मक मूल्य की गणना

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

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

function main () {
     while (true) {
         var beginTime = new Date().getTime()
         var ticker = exchange.GetTicker()
         var endTime = new Date().getTime()

         LogStatus(_D(), "GetTicker() function time-consuming:", endTime - beginTime, "millisecond")
         Sleep(1000)
     }
}

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

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

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

हम इसे इस तरह नियंत्रित करते हैंः

उदाहरण के लिए, हम 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 function.

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

.._N()कार्य एक निश्चित मूल्य के लिए दशमलव बिंदु काटना (सटीक नियंत्रण) करना है।

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

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

पाय का मान दशमलव स्थान से काट दिया जाता है, और 2 दशमलव स्थान आरक्षित होते हैं, जो हैः 3.14

विवरण के लिए एपीआई प्रलेखन देखें.

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

  • समय, कुछ कार्यों को एक निश्चित अवधि के लिए करना

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

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

var lastActTime = 0
var waitTime = 1000 * 60 * 60 * 12 // number of milliseconds a day
function main () {
     while (true) {
         var nowTime = new Date().getTime()
         if (nowTime - lastActTime > waitTime) {
             Log ("Execution Fixed")
             // ... specific fixed investment operation, buying operation.


             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("restore hold:", hold)
     }

     var count = 1
     while (true) {
         // ... strategy logic
         // ... In the strategy operation, it is possible that when opening a position, then assign the position price of the open position to "hold.price", and the amount of open positions is assigned to "hold.amount" to record the position information.

         hold.price = count++ // simulate some values
         hold.amount = count/10 // Simulate some values

         Sleep(500)
     }
}

function onexit () { // Click the stop button on the robot to trigger the execution of this function. After the execution, the robot stops.
     _G("hold", hold)
     Log("save hold:", JSON.stringify(hold))
}

img

यह देखा जा सकता है किholdऑब्जेक्ट रोबोट बंद कर दिया है हर बार सहेजा जाता है. और जब हर बार डेटा फिर से शुरू किया जाता है, डेटा पढ़ा जाता है और मान केholdरुकने से पहले की स्थिति में लौटा दिया जाता है।

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

इसके अतिरिक्त, आप पुनर्स्थापित करने के लिए कुछ अन्य शर्तें भी निर्धारित कर सकते हैं।

ये ट्रेडिंग रणनीतियों को विकसित करने के लिए कुछ सुझाव हैं, और मुझे आशा है कि यह शुरुआती लोगों की मदद कर सकता है!

व्यावहारिक अभ्यास प्रशिक्षण स्वयं को सुधारने का सबसे तेज़ तरीका है! मैं आप सभी को शुभकामनाएं देता हूँ।


संबंधित

अधिक