पिछले लेख में, हमने C++ भाषा, बुनियादी व्याकरण और रणनीति संरचना की शुरूआत से ट्रेडिंग रणनीति को लागू करने के आधार को समझाया था। इस लेख में, हम पिछले भाग को जारी रखेंगे और चरण-दर-चरण एक व्यवहार्य मात्रात्मक ट्रेडिंग रणनीति को लागू करेंगे।
तकनीकी विश्लेषण में सबसे अधिक उपयोग किए जाने वाले संकेतकों में से एक, केडीजे, को दुनिया भर के अधिकांश व्यापारियों द्वारा मान्यता दी गई थी। केडीजे
KDJ सांख्यिकीय सिद्धांत पर आधारित था, एक यादृच्छिक मूल्य (RSV) की गणना हाल के 9 K लाइन
गति की अवधारणा, शक्ति संकेतक और चलती औसत के लाभों को मिलाकर, हम सामान्य सीमा आंदोलन से शेयर मूल्य के परिवर्तन की डिग्री को मापते हैं। जब K मान D मान से अधिक होता है, तो यह इंगित करता है कि स्टॉक मूल्य वर्तमान में एक ऊपर की ओर प्रवृत्ति में है। इसलिए, जब K रेखा नीचे से ऊपर की ओर D रेखा को पार करती है, तो यह स्टॉक खरीदने का समय है। इसके विपरीत, जब K मूल्य D मूल्य से कम होता है, तो यह इंगित करता है कि शेयर बाजार वर्तमान में एक नीचे की ओर प्रवृत्ति में है। इसलिए, जब K रेखा ऊपर से नीचे की ओर D रेखा को पार करती है, तो यह स्टॉक बेचने का समय है।
केडीजे सूचक की गणना जटिल है। सबसे पहले यादृच्छिक मान (आरएसवी) की गणना की जाती है, और फिर के मान, डी मान और जे मान की गणना की जाती है। इसकी गणना विधि निम्नानुसार हैः
आरएसवी = (समापन मूल्य - एन अवधि सबसे कम मूल्य) / (एन चक्र उच्चतम मूल्य - एन चक्र सबसे कम मूल्य) * 100
K मान = N चक्रों का औसत RSV
डी मान = एन चक्रों का औसत K
J मान = 3 * K मान -2 * D मान
void main(){ // the program starts from this main function
while (true){ // enter the loop
auto ct = exchange.SetContractType(symblo); //set the contract type
auto r = exchange.GetRecords(); // get the K line array
auto arr = TA.KDJ(r, 9, 3, 3); // calculate the KDJ indicator
auto k = arr[0]arr[0].size() - 2]; // get the previous k line KDJ indicator K value
auto d = arr[1]arr[1].size() - 2]; // get the previous k line KDJ indicator D value
auto j = arr[2]arr[2].size() - 2]; // get the previous k line KDJ indicator J value
}
}
KDJ का उपयोग करने के कई तरीके हैं, जिनका उपयोग अकेले या अन्य संकेतकों के साथ मिलकर किया जा सकता है। इस लेख में हम इसका उपयोग सबसे सरल तरीके से करेंगे, जो हैंः यदि K मूल्य D मूल्य से अधिक है, तो हम मानते हैं कि क्रय शक्ति मजबूत हो रही है, बढ़ते बाजार की एक लहर बन गई है, और उद्घाटन लंबी स्थिति संकेत उत्पन्न होता है; यदि K मूल्य D मूल्य से कम है, तो हम मानते हैं कि बिक्री शक्ति मजबूत हो रही है, और एक गिरावट की प्रवृत्ति की लहर बनाई गई है, उद्घाटन छोटी स्थिति संकेत उत्पन्न होता है।
यदि स्थिति खोले जाने के बाद डी मूल्य ऊपर से नीचे की ओर बदल जाता है, तो हम मानते हैं कि क्रय शक्ति कमजोर हो रही है, या विक्रय शक्ति मजबूत हो रही है, और बंद लंबी स्थिति संकेत उत्पन्न होता है; यदि छोटी स्थिति खोली जाती है, तो डी मूल्य नीचे से ऊपर की ओर बदल जाता है, हम मानते हैं कि विक्रय शक्ति की ताकत कमजोर हो रही है, या कि क्रय शक्ति मजबूत हो रही है, और बंद छोटी स्थिति संकेत उत्पन्न होते हैं।
खुली लंबी स्थितिः यदि कोई स्थिति नहीं है, और K मान D मान से अधिक है
शॉर्ट पोजीशनः यदि कोई पोजीशन नहीं है और K मान D मान से कम है
बंद करना लंबी स्थितिः यदि लंबी स्थिति होल्डिंग है और D मान पारगम्य K रेखा के मूल्य D से कम है
बंद शॉर्ट पोजीशनः यदि शॉर्ट पोजीशन होल्ड है और डी मान पारदर्शी के लाइन के डी मूल्य से अधिक है
कोड के साथ एक रणनीति को लागू करने में पहला कदम पहले यह विचार करना है कि हमें किस डेटा की आवश्यकता है? किस एपीआई के माध्यम से प्राप्त करने के लिए? डेटा प्राप्त करने के बाद, ट्रेडिंग तर्क की गणना कैसे करें? अगला, ऑर्डर रखने का कौन सा तरीका है? अंत में, चलो इसे कदम से कदम लागू करते हैंः
तथाकथित रणनीति वास्तुकला पूरी रणनीति को डिजाइन करने का तरीका है। जैसा कि नीचे दिखाया गया है, वास्तुकला में दो कार्य शामिल हैंः एक मुख्य कार्य है, कार्यक्रम मुख्य कार्य से शुरू होता है, और इसका कार्य रणनीति तर्क के मूल से निपटना है। जैसे चीजेंः एक्सचेंज के साथ कनेक्शन ठीक है या नहीं, अनावश्यक लॉग जानकारी को फ़िल्टर करना, रणनीति तर्क कोर के निष्पादन समय अंतराल को नियंत्रित करना; और दूसरा एक ऑनटिक फ़ंक्शन है, इस फ़ंक्शन में, मुख्य रूप से रणनीति तर्क है, जिसमें शामिल हैंः कच्चे डेटा प्राप्त करें, डेटा की गणना करें, आदेश दें, और अधिक।
bool onTick(){ // onTick function
// strategy logic
}
void main(){ // program starts from here
while (true){ // enter the loop
if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if(!onTick()){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
sleep(1000); // pause for 1 second
}
}
}
उपरोक्त कोड एफएमजेड क्वांट प्लेटफॉर्म टूल्स द्वारा बनाया गया सी ++ रणनीति फ्रेमवर्क है। यह एक निश्चित कोडिंग प्रारूप है, सभी ट्रेडिंग लॉजिक लाइन 2 से शुरू होती है, और कहीं और कोई बदलाव नहीं किया जाता है। इसके अलावा, यदि आप एक अनुभवी हैं, तो आप अपनी आवश्यकता के अनुसार सुविधाओं को जोड़ या संशोधित कर सकते हैं।
आप ट्रेडिंग क्लास लाइब्रेरी को एक कार्यात्मक मॉड्यूल के रूप में सोच सकते हैं। ट्रेडिंग क्लास लाइब्रेरी का उपयोग करने का लाभ यह है कि यह आपको रणनीति तर्क लिखने पर ध्यान केंद्रित करने की अनुमति देता है। उदाहरण के लिए, जब हम ट्रेडिंग क्लास लाइब्रेरी का उपयोग करते हैं, तो स्थिति खोलने या बंद करने के लिए, हम सीधे ट्रेडिंग क्लास लाइब्रेरी में एपीआई इंटरफ़ेस का उपयोग कर सकते हैं; लेकिन अगर हम ट्रेडिंग क्लास लाइब्रेरी का उपयोग नहीं करते हैं, तो हमें स्थिति खोलने पर बाजार मूल्य प्राप्त करने की आवश्यकता है। निष्पादित ऑर्डर के मुद्दे और निकासी आदेशों के मुद्दे पर विचार करने की आवश्यकता है, और इसी तरह।
विभिन्न कच्चे डेटा ट्रेडिंग तर्क का एक महत्वपूर्ण हिस्सा है। हमें किस प्रकार के डेटा की आवश्यकता है? हमारी रणनीति ट्रेडिंग तर्क से, हमें पहले K- लाइन डेटा प्राप्त करने की आवश्यकता है। मूल K- लाइन डेटा के साथ, हम KDJ संकेतक की गणना कर सकते हैं, और अंत में आदेश देने के लिए K- मूल्य और D- मूल्य के बीच संबंध की तुलना कर सकते हैं। तो आइए इन डेटा को प्राप्त करें।
सबसे पहले, हम K-लाइन सरणी प्राप्त करने की जरूरत है, क्योंकि K-लाइन सरणी KDJ संकेतक की गणना करने के लिए इस्तेमाल किया जाएगा. निम्नानुसारः
double position = 0; // position status parameter, the default is 0
bool onTick(string symbol){ // onTick function, all strategy logic are in this function
auto ct = exchange.SetContractType(symbol); // set the contract type and trading variety
if(ct == false){ // if the setting contract type and trading variety is not successful
return false; // return false
}
auto r = exchange.GetRecords(); // get the k-line array
if(!r.Valid || r.size() < 10){ // if getting the k-line array or the number of k-line is less than 10
return false; // return false
}
}
void main(){ // program starts from here
while (true){ // enter the loop
if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if(!onTick("this_week")){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
sleep(1000); // pause for 1 second
}
}
}
जैसा कि ऊपर दिखाया गया हैः
पंक्ति 1: एक चर को परिभाषित करता है जिसका उपयोग स्थिति की स्थिति प्राप्त करने के लिए किया जाता है.
पंक्तियाँ 3 से 12: एक onTick फ़ंक्शन परिभाषित किया गया है, और यह फ़ंक्शन एक पैरामीटर के साथ ले जाता है। इस पैरामीटर को व्यापारिक विविधता में पारित किया जाना है, इस मामले में, साप्ताहिक के-लाइन का उपयोग करके।
पंक्तियाँ 14 से 24: एक मुख्य फ़ंक्शन को परिभाषित करें जो गैर-रणनीति तर्क को संभालता है। केवल एक चीज जिसे बदला जा सकता है वह है पंक्ति 20 पर अनुबंध कोड
चलो onTick फ़ंक्शन पर ध्यान केंद्रित करते हैं और देखते हैं कि यह K-लाइन डेटा कैसे प्राप्त करता हैः
पंक्तियाँ 4 से 7: अनुबंध प्रकार और व्यापारिक विविधता सेट करें, यदि अनुबंध प्रकार और व्यापारिक विविधता सेट करना सफल नहीं होता है, तो गलत लौटाएं
पंक्ति 8: एक के-लाइन सरणी प्राप्त करें, जो एक निश्चित प्रारूप है।
पंक्तियाँ 9 से 11 तक: K रेखा की लंबाई को फ़िल्टर करें, क्योंकि KDJ संकेतक की गणना करने के लिए हम जो पैरामीटर का उपयोग करते हैं वह 9 है। जब K रेखा की संख्या 9 से कम है, तो KDJ संकेतक की गणना करना असंभव है। तो यहां हम K रेखा की लंबाई को फ़िल्टर करना चाहते हैं। यदि K रेखा 10 से कम है, तो बस सीधे गलत लौटाएं और अगली K रेखा की प्रतीक्षा करते रहें।
इसके बाद, हमें KDJ संकेतक के K और D मानों की गणना करने की आवश्यकता है। सबसे पहले KDJ संकेतक की एक सरणी प्राप्त करना आवश्यक है, और इस सरणी से K मान और D मान प्राप्त करें। FMZ क्वांट प्लेटफॉर्म पर, KDJ की सरणी प्राप्त करना बहुत सरल है, बस KDJ के एपीआई को कॉल करें, कठिनाई K और D मानों का मूल्य प्राप्त करना है, क्योंकि KDJ सरणी एक दो आयामी सरणी है।
दो आयामी सरणी वास्तव में समझने में आसान है, जो कि सरणी की एक सरणी है, प्राप्त अनुक्रम हैंः पहले सरणी में निर्दिष्ट सरणी प्राप्त करें, और फिर निर्दिष्ट सरणी से निर्दिष्ट तत्व प्राप्त करें, जैसा कि नीचे दिखाया गया हैः
#include <iostream>
using namespace std;
int main(){
int hour [3][2] = {{100, 50}, {66, 88}, {10, 90}};
cout << hours[0][0]; // get the hours array first elements of first element, the result is 100
cout << hours[0][1]; // get the hours array first elements of second element, the result is 50
cout << hours[1][0]; // get the hours array second elements of first element, the result is 66
return(0);
}
जैसा कि नीचे दिखाया गया है, 12 वीं पंक्ति सीधे FMZ Quant के API का उपयोग KDJ संकेतकों की एक सरणी प्राप्त करने के लिए करती है, जो एक दो आयामी सरणी हैः arr = [[K मान, K मान, K मान...], [D मान, D मान, D मान...], [J मान, J मान, J मान...]]
पंक्ति 13 पूर्ववर्ती K पंक्ति का k मान प्राप्त करना है, K मान arr[0] है, फिर arr[0], arr[0].size() से उप-अंतिम तत्व प्राप्त करना है जिसका उपयोग arr[0], arr[0].size() - 2 की सरणी की लंबाई प्राप्त करने के लिए किया जा सकता है, यह सरणी का दूसरा अंतिम तत्व है, इसे एक साथ रखा गया हैः ऑटो k = arr [0] [arr [0].size () - 2 ]; पंक्ति 14 और 15 एक ही गणना हैं।
double position = 0; // position status parameter, the default is 0
bool onTick(string symbol){ // onTick function, all strategy logic are in this function
auto ct = exchange.SetContractType(symbol); // set the contract type and trading variety
if(ct == false){ // if the setting contract type and trading variety is not successful
return false; // return false
}
auto r = exchange.GetRecords(); // get the k-line array
if(!r.Valid || r.size() < 10){ // if getting the k-line array or the number of k-line is less than 10
return false; // return false
}
auto arr = TA.KDJ(r, 9, 3, 3); // calculate the KDJ indicator
auto k = arr[0][arr[0].size() - 2]; // get the K value of the previous K line
auto d = arr[1][arr[1].size() - 2]; // get the D value of the previous K line
auto dPre = arr[1][arr[1].size() - 3]; // get the D value of the second last of the K line
}
void main(){ // program starts from here
while (true){ // enter the loop
if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if(!onTick("this_week")){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
sleep(1000); // pause for 1 second
}
}
}
उपरोक्त डेटा के साथ, हम ट्रेडिंग लॉजिक और प्लेसिंग ऑर्डर भाग अब लिख सकते हैं। यह भी बहुत सरल है, सबसे अधिक इस्तेमाल किया जाता है
double position = 0; // position status parameter, the default is 0
bool onTick(string symbol){ // onTick function, all strategy logic are in this function
auto ct = exchange.SetContractType(symbol); // set the contract type and trading variety
if(ct == false){ // if the setting contract type and trading variety is not successful
return false; // return false
}
auto r = exchange.GetRecords(); // get the k-line array
if(!r.Valid || r.size() < 10){ // if getting the k-line array or the number of k-line is less than 10
return false; // return false
}
auto arr = TA.KDJ(r, 9, 3, 3); // calculate the KDJ indicator
auto k = arr[0][arr[0].size() - 2]; // get the K value of the previous K line
auto d = arr[1][arr[1].size() - 2]; // get the D value of the previous K line
auto dPre = arr[1][arr[1].size() - 3]; // get the D value of the second last of the K line
string action; // define a string variable action
// if currently holding long position, and the previous K line's D value is less than the second last k line's D value, close all position
// if currently holding short position, and the previous K line's D value is greater than the second last k line's D value, close all position
if((d < dPre && position > 0) || (d > dPre && position <0)){
action = "cover";
}else if (k > d && position <= 0){ // if the previous K line's K value is greater than the previous K line's D value, and there are no long positions
action = "buy"; // set the variable action to "buy"
}else if (k < d && position >= 0){ // if the previous K line's K value is less than the previous K line's D value, and there are no short positions
action = "sell"; // set the variable action to "sell"
}
if (action.size() > 0){ // if there are placing order instruction
position = ext::Trade(action, symbol, 1); // calling the C++ trading class library, placing orders according the direction of variable "action". and also renew the position status.
}
return true; // return true
}
}
void main(){ // program starts from here
while (true){ // enter the loop
if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if(!onTick("this_week")){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
sleep(1000); // pause for 1 second
}
}
}
उपरोक्त कोड में, पंक्तियाँ 19 से 28 ट्रेडिंग तर्क और आदेशों को रखने के लिए कोड हैं। हालांकि, इससे पहले, हमें पंक्ति 16 पर एक स्ट्रिंग चर " कार्रवाई " को परिभाषित करने की आवश्यकता है, जिसका उपयोग आदेश की कार्रवाई निर्धारित करने में मदद करने के लिए किया जाता है।
पंक्ति 19 से पंक्ति 21 तकः यदि वर्तमान में लंबी स्थिति हो रही है, और पिछली K पंक्ति
पंक्ति 21 से पंक्ति 25 तकः लंबी और छोटी स्थिति खोलने के लिए शर्तें हैं। जब शर्त सही है, तो
पंक्ति 26 से पंक्ति 28 तक प्लेसिंग ऑर्डर लॉजिक को निष्पादित कर रहे हैं। सबसे पहले, स्ट्रिंग चर
दो स्थानों पर ध्यान देने की आवश्यकता हैः
कोशिश करें (लेकिन जरूरी नहीं) रणनीति तर्क लिखने के रूप में वर्तमान के-लाइन स्थिति स्थापित है, तो अगले के-लाइन पर आदेश रखने. या पिछले के-लाइन स्थिति स्थापित है, वर्तमान के-लाइन पर आदेश रखने, इस तरह, बैकटेस्ट का परिणाम और वास्तविक बाजार प्रदर्शन बहुत अलग नहीं हैं. यह इस तरह लिखने के लिए ठीक नहीं है, लेकिन ध्यान दें कि क्या रणनीति तर्क सही है.
सामान्य तौर पर, बंद करने की स्थिति का तर्क खोलने की स्थिति के तर्क के सामने लिखना चाहिए। इसका उद्देश्य रणनीति तर्क को अपनी अपेक्षाओं को पूरा करने की कोशिश करना है। उदाहरण के लिए, यदि रणनीति तर्क सिर्फ उस स्थिति को पूरा करता है जहां इसे केवल एक स्थिति को बंद करने के बाद व्यापार की विपरीत दिशा करने की आवश्यकता होती है, तो इस तरह की स्थिति का नियम पहले स्थिति को बंद करना और फिर नई स्थिति खोलना है। यदि हम बंद करने की स्थिति तर्क को खोलने की स्थिति के तर्क के सामने लिखते हैं, तो यह इस नियम को पूरी तरह से पूरा करेगा।
ऊपर हमने सीखा कि कैसे केडीजे तकनीकी संकेतकों का विश्लेषण करें और इसे एक पूर्ण मात्रात्मक ट्रेडिंग रणनीति में परिवर्तित करें। जिसमें शामिल हैंः रणनीति परिचय, केडीजे संकेतकों की गणना विधि, रणनीति तर्क, ट्रेडिंग शर्तें, रणनीति कोड कार्यान्वयन, आदि। इस रणनीति मामले के माध्यम से, न केवल हम एफएमजेड क्वांट प्लेटफॉर्म पर सी ++ प्रोग्रामिंग विधि से परिचित हो जाते हैं, बल्कि विभिन्न रणनीतियों को भी इस खंड में मामलों के अनुसार अनुकूलित किया जा सकता है।
एक मात्रात्मक ट्रेडिंग रणनीति प्राप्त करने के लिए अपने स्वयं के व्यक्तिपरक ट्रेडिंग अनुभव या प्रणाली को सारांशित करना है, और फिर आवश्यक कच्चे डेटा को अलग से प्राप्त करना है, और रणनीति तर्क के लिए आवश्यक डेटा की गणना करना है, और अंत में ट्रेडिंग को महसूस करने के लिए प्लेसिंग ऑर्डर एपीआई को कॉल करना है। यह कहा जा सकता है कि अधिकांश सरल मात्रात्मक ट्रेडिंग रणनीतियों को इन चरणों के अनुसार लागू किया जाता है!
अब तक, इस श्रृंखला में रणनीति लेखन ट्यूटोरियल अंत में आ गया है, मेरा मानना है कि यदि आप चरण-दर-चरण ट्यूटोरियल का पालन करते हैं जो आपको यहां ले जाता है, तो आप बहुत कुछ हासिल करेंगे। किसी भी मामले में, मात्रात्मक व्यापार के बुनियादी पाठ्यक्रमों के दृष्टिकोण से, लंबी सड़क आधी से अधिक हो गई है। पिछले अध्याय में, हम आपको सिखाएंगे कि एफएमजेड क्वांट बैकटेस्टिंग ट्रेडिंग टूल का उपयोग कैसे करें, और बैकटेस्टिंग में गड्ढों से कैसे बचें और वास्तविक बाजार व्यापार के लिए अंतिम तैयारी करें। हालांकि यह सामग्री का एक छोटा सा हिस्सा है, यह मात्रात्मक व्यापार की दुनिया में प्रवेश करने में एक बड़ा कदम है!
एफएमजेड क्वांट प्लेटफॉर्म पर सी++ भाषा का उपयोग करके केडीजे सूचक एल्गोरिथ्म को लागू करने का प्रयास करें।
सीसीआई सूचक रणनीति बनाने के लिए इस खंड में ज्ञान का उपयोग करने का प्रयास करें।