"OKEX वायदा अनुबंध हेजिंग रणनीति का सी ++ संस्करण" जो आपको हार्डकोर मात्रात्मक रणनीति के माध्यम से ले जाता है

लेखक:अच्छाई, बनाया गयाः 2019-08-29 16:05:07, अद्यतनः 2025-01-15 22:07:49

“C++ version of OKEX futures contract hedging strategy” that takes you through hardcore quantitative strategy

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

रणनीति का सिद्धांत

रणनीति कुछ हद तक हार्डकोर क्यों है क्योंकि रणनीति सी ++ में लिखी गई है और रणनीति पढ़ना थोड़ा अधिक कठिन है। लेकिन यह पाठकों को इस रणनीति डिजाइन और विचारों के सार को सीखने से नहीं रोकता है। रणनीति तर्क अपेक्षाकृत सरल है, कोड की लंबाई मध्यम है, केवल 500 पंक्तियाँ। बाजार डेटा अधिग्रहण के मामले में, अन्य रणनीतियों के विपरीत जो rest इंटरफ़ेस का उपयोग करते हैं। यह रणनीति एक्सचेंज बाजार उद्धरण स्वीकार करने के लिए websocket इंटरफ़ेस का उपयोग करती है।

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

  • पॉजिटिव स्प्रेड, शॉर्ट फोरवर्ड कॉन्ट्रैक्ट्स बेचना, लंबे हालिया कॉन्ट्रैक्ट्स खरीदना।
  • ऋणात्मक स्प्रेड, लंबी वायदा अनुबंध खरीदना, हाल के अनुबंधों को कम करना।

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

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

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

रणनीति कोड का विश्लेषण

पूरे कोड को देखते हुए, आप यह निष्कर्ष निकाल सकते हैं कि कोड मोटे तौर पर चार भागों में विभाजित है।

  1. मान परिभाषाओं को सूचीबद्ध करें, कुछ राज्य मानों को परिभाषित करें, और राज्यों को चिह्नित करने के लिए उपयोग करें। कुछ कार्यात्मक कार्य जो रणनीति से संबंधित नहीं हैं, जैसे कि यूआरएल एन्कोडिंग फ़ंक्शन, समय रूपांतरण फ़ंक्शन, आदि, का रणनीति तर्क से कोई संबंध नहीं है, केवल डेटा प्रसंस्करण के लिए।

  2. K-लाइन डेटा जनरेटर वर्गः यह रणनीति जनरेटर वर्ग वस्तु द्वारा उत्पन्न K-लाइन डेटा द्वारा संचालित होती है।

  3. हेजिंग वर्गः इस वर्ग के ऑब्जेक्ट विशिष्ट ट्रेडिंग लॉजिक, हेजिंग ऑपरेशन और रणनीति के प्रोसेसिंग विवरण कर सकते हैं।

  4. रणनीति का मुख्य कार्य, जो main फ़ंक्शन है। मुख्य फ़ंक्शन रणनीति का प्रवेश फ़ंक्शन है। मुख्य लूप इस फ़ंक्शन के अंदर निष्पादित किया जाता है। इसके अलावा, यह फ़ंक्शन एक महत्वपूर्ण ऑपरेशन भी करता है, अर्थात एक्सचेंज के वेबसॉकेट इंटरफ़ेस तक पहुंचना, और K-लाइन डेटा जनरेटर के रूप में पुश किए गए कच्चे टिक बाजार डेटा प्राप्त करना।

रणनीति कोड की समग्र समझ के माध्यम से, हम धीरे-धीरे रणनीति के विभिन्न पहलुओं को सीख सकते हैं, और फिर रणनीति के डिजाइन, विचारों और कौशल का अध्ययन कर सकते हैं।

  • अंकगणित मूल्य परिभाषा, अन्य कार्य कार्य
  1. सूचीबद्ध प्रकारStateबयान
enum State {                    // Enum type defines some states
    STATE_NA,                   // Abnormal state
    STATE_IDLE,                 // idle
    STATE_HOLD_LONG,            // holding long positions
    STATE_HOLD_SHORT,           // holding short positions
};

क्योंकि कोड में कुछ फ़ंक्शन एक राज्य वापस करते हैं, इन राज्यों को गणना प्रकार में परिभाषित किया जाता हैState.

यह देखते हुए किSTATE_NAकोड में दिखाई देता है असामान्य है, औरSTATE_IDLEनिष्क्रिय है, यानी ऑपरेशन की स्थिति को हेज किया जा सकता है।STATE_HOLD_LONGवह अवस्था है जिसमें सकारात्मक हेजिंग स्थिति रखी जाती है।STATE_HOLD_SHORTवह अवस्था है जिसमें ऋणात्मक हेजिंग स्थिति रखी जाती है।

  1. स्ट्रिंग प्रतिस्थापन, इस रणनीति में नहीं कहा जाता है, एक वैकल्पिक उपयोगिता कार्य है, मुख्य रूप से स्ट्रिंग्स से निपटने के लिए।
string replace(string s, const string from, const string& to)
  1. हेक्साडेसिमल वर्णों में परिवर्तित करने के लिए एक कार्यtoHex
inline unsigned char toHex(unsigned char x)
  1. यूआरएल एन्कोडेड फ़ंक्शंस को संभालना
std::string urlencode(const std::string& str)
  1. एक समय रूपांतरण फ़ंक्शन जो स्ट्रिंग प्रारूप में समय को टाइमस्टैम्प में परिवर्तित करता है.
uint64_t _Time(string &s)
  • के लाइन डेटा जनरेटर वर्ग
class BarFeeder { // K line data generator class
    public:
        BarFeeder(int period) : _period(period) { // constructor with argument "period" period, initialized in initialization list
            _rs.Valid = true; // Initialize the "Valid" property of the K-line data in the constructor body.
        }

        void feed(double price, chart *c=nullptr, int chartIdx=0) { // input data, "nullptr" null pointer type, "chartIdx" index default parameter is 0
            uint64_t epoch = uint64_t(Unix() / _period) * _period * 1000; // The second-level timestamp removes the incomplete time period (incomplete _period seconds) and is converted to a millisecond timestamp.
            bool newBar = false; // mark the tag variable of the new K line Bar
            if (_rs.size() == 0 || _rs[_rs.size()-1].Time < epoch) { // if the K line data is 0 in length. Or the last bar's timestamp is less than epoch (the last bar of the K line is more than the current most recent cycle timestamp)
                record r; // declare a K line bar structure
                r.Time = epoch; // construct the K line bar of the current cycle
                r.Open = r.High = r.Low = r.close = price; // Initialize the property
                _rs.push_back(r); // K line bar is pressed into the K line data structure
                if (_rs.size() > 2000) { // if the K-line data structure length exceeds 2000, the oldest data is removed.
                    _rs.erase(_rs.begin());
                }
                newBar = true; // tag
            } else { // In other cases, it is not the case of a new bar.
                record &r = _rs[_rs.size() - 1]; // Reference the data of the last bar in the data.
                r.High = max(r.High, price); // The highest price update operation for the referenced data.
                r.Low = min(r.Low, price); // The lowest price update operation for the referenced data.
                r.close = price; // Update the closing price of the referenced data.
            }
    
            auto bar = _rs[_rs.size()-1]; // Take the last column data and assign it to the bar variable
            json point = {bar.Time, bar.Open, bar.High, bar.Low, bar.close}; // construct a json type data
            if (c != nullptr) { // The chart object pointer is not equal to the null pointer, do the following.
               if (newBar) { // judge if the new Bar appears
                    c->add(chartIdx, point); // call the chart object member function add to insert data into the chart object (new k line bar)
                    c->reset(1000); // retain only 1000 bar of data
                } else {
                    c->add(chartIdx, point, -1); // Otherwise update (not new bar), this point (update this bar).
                }
            }
        }
        records & get() { // member function, method for getting K line data.
            Return _rs; // Returns the object's private variable _rs . (ie generated K-line data)
        }
    private:
        int _period;
        records _rs;
};

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

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

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

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

  • हेजिंग वर्ग
class Hedge { // Hedging class, the main logic of the strategy.
  public:
    Hedge() { // constructor
        ...
    };
    
    State getState(string &symbolA, depth &depthA, string &symbolB, depth &depthB) { // Get state, parameters: contract A name, contract A depth data, contract B name, contract B depth data
        
        ...
    }
    bool Loop(string &symbolA, depth &depthA, string &symbolB, depth &depthB, string extra="") { // Opening and closing position main logic
        
        ...
    }

  private:
    vector<double> _addArr; // Hedging adding position list
    string _state_desc[4] = {"NA", "IDLE", "LONG", "SHORT"}; // Status value Description
    int _countOpen = 0; // number of opening positions
    int _countcover = 0; // number of closing positions
    int _lastcache = 0; //
    int _hedgecount = 0; // number of hedging
    int _loopcount = 0; // loop count (cycle count)
    double _holdPrice = 0; // holding position price
    BarFeeder _feederA = BarFeeder(DPeriod); // A contract Quote K line generator
    BarFeeder _feederB = BarFeeder(DPeriod); // B contract Quote K line generator
    State _st = STATE_NA; // Hedging type Object Hedging position status
    string _cfgStr; // chart configuration string
    double _holdAmount = 0; // holding position amount
    bool _iscover = false; // the tag of whether to close the position
    bool _needcheckOrder = true; // Set whether to check the order
    chart _c = chart(""); // chart object and initialize
};

क्योंकि कोड अपेक्षाकृत लंबा है, कुछ भागों को छोड़ दिया गया है, यह मुख्य रूप से इस हेज वर्ग की संरचना दिखा रहा है, कंस्ट्रक्टर हेज फ़ंक्शन को छोड़ दिया गया है, मुख्य रूप से उद्देश्य के लिए ऑब्जेक्ट आरंभ। इसके बाद, हम दो मुख्य function फ़ंक्शन पेश करते हैं।

getState

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

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

लूप

रणनीति का व्यापारिक तर्क इस कार्य में समाहित है, जिसमेंgetStateइस चार्ट के लिए कुछ डेटा अपडेट ऑपरेशन भी हैं। चार्ट के लिए कुछ डेटा अपडेट ऑपरेशन भी हैं।

  • रणनीति का मुख्य कार्य
void main() {

    ...
    
    string realSymbolA = exchange.SetcontractType(symbolA)["instrument"]; // Get the A contract (this_week / next_week / quarter ), the real contract ID corresponding to the week, next week, and quarter of the OKEX futures contract.
    string realSymbolB = exchange.SetcontractType(symbolB)["instrument"]; // ...
    
    string qs = urlencode(json({{"op", "subscribe"}, {"args", {"futures/depth5:" + realSymbolA, "futures/depth5:" + realSymbolB}}}).dump()) ; // jSON encoding, url encoding for the parameters to be passed on the ws interface
    Log("try connect to websocket"); // Print the information of the connection WS interface.
    auto ws = Dial("wss://real.okex.com:10442/ws/v3|compress=gzip_raw&mode=recv&reconnect=true&payload="+qs); // call the FMZ API "Dial" function to acess the WS interface of OKEX Futures
    Log("connect to websocket sucess");
    
    depth depthA, depthB; // Declare two variables of the depth data structure to store the depth data of the A contract and the B contract
    auto filldepth = [](json &data, depth &d) { // construct the code for the depth data with the json data returned by the interface.
        d.Valid = true;
        d.Asks.clear();
        d.Asks.push_back({atof(string(data["asks"][0][0]).c_str()), atof(string(data["asks"][0][1]).c_str( ))});
        d.Bids.clear();
        d.Bids.push_back({atof(string(data["bids"][0][0]).c_str()), atof(string(data["bids"][0][1]).c_str( ))});
    };
    string timeA; // time string A
    string timeB; // time string B
    while (true) {
        auto buf = ws.read(); // Read the data pushed by the WS interface
        
        ...
        
}

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

एक बात ध्यान देने योग्य है कि ऊपर उल्लिखित टिक मार्केट वास्तव में सब्सक्रिप्शन ऑर्डर पतली गहराई डेटा इंटरफ़ेस है, जो प्रत्येक फ़ाइल के लिए ऑर्डर बुक डेटा है। हालांकि, रणनीति केवल डेटा की पहली फ़ाइल का उपयोग करती है, वास्तव में, यह लगभग टिक बाजार डेटा के समान है। रणनीति अन्य फ़ाइलों के डेटा का उपयोग नहीं करती है, न ही यह पहली फ़ाइल के ऑर्डर मान का उपयोग करती है।

वेबसॉकेट इंटरफेस के डेटा को कैसे सब्सक्राइब करता है और इसे कैसे सेट किया जाता है, इस पर अधिक बारीकी से नज़र डालें।

string qs = urlencode(json({{"op", "subscribe"}, {"args", {"futures/depth5:" + realSymbolA, "futures/depth5:" + realSymbolB}}}).dump());    
Log("try connect to websocket");                                                                                                            
auto ws = Dial("wss://real.okex.com:10442/ws/v3|compress=gzip_raw&mode=recv&reconnect=true&payload="+qs);     
Log("connect to websocket sucess");

सबसे पहले, सदस्यता संदेश के यूआरएल एन्कोडिंग json पैरामीटर सदस्यता इंटरफेस द्वारा पारित, यानी मूल्य कीpayloadफिर एक महत्वपूर्ण कदम एफएमजेड क्वांट मंचs एपीआई इंटरफ़ेस समारोह कॉल करने के लिए हैDialकार्य।Dialयहाँ हम कुछ सेटिंग्स करते हैं, वेबसॉकेट कनेक्शन नियंत्रण ऑब्जेक्ट ws बनाने के लिए स्वचालित पुनः कनेक्शन या डिस्कनेक्शन (सब्सक्राइब संदेश अभी भी मान का उपयोग करता हैqsस्ट्रिंग काpayloadपैरामीटर), इस समारोह को प्राप्त करने के लिए, आप पैरामीटर स्ट्रिंग में विन्यास जोड़ने की जरूरत हैDial function.

की शुरुआतDialकार्य पैरामीटर निम्नानुसार है:

wss://real.okex.com:10442/ws/v3

यह वेबसॉकेट इंटरफेस का पता है जिसे एक्सेस करने की आवश्यकता है, और इसे अलग किया गया है।


|Parameter name|description|
|-|-|
|compress|compress is compression mode, OKEX websocket interface uses gzip_raw this way, so it is set to gzip_raw|
|mode|Mode is mode, optional dual, send and recv three kind. Dual is bidirectional, sending compressed data and receiving compressed data. Send is to send compressed data. Recv receives the compressed data and decompresses it locally.|
|reconnect|Reconnect is set to reconnect, reconnect=true to enable reconnection, no default is not reconnected.|
|payload|The payload is a subscription message that needs to be sent when ws is reconnected.|

After this setting, even if the websocket connection is disconnected, FMZ Quant trading platform's underlying system of the docker system will automatically reconnect and get the latest market data in time.

Grab every price fluctuation and quickly capture the right hedge.

- Position control

Position control is controlled using a ratio of hedge positions similar to the “Fibonaci” series.

के लिए (int i = 0; i < AddMax + 1; i++) { // एक डेटा संरचना का निर्माण करें जो स्केलिंग की संख्या को नियंत्रित करता है, जो बोफिनाक अनुक्रम के अनुपात के समान है। यदि (_addArr.size() < 2) { // पहले दो जोड़े गए पदों को बदल दिया जाता हैः हेज की संख्या को दोगुना करें _addArr.push_back (((i+1)*OpenAmount); } _addArr.push_back ((_addArr[_addArr.size() -1] + _addArr[_addArr.size()-2]); // अंतिम दो जोड़ने की स्थिति एक साथ जोड़ी जाती है, और वर्तमान स्थिति मात्रा की गणना की जाती है और _addArr डेटा संरचना में संग्रहीत की जाती है। }


It can be seen that the number of additional positions added each time is the sum of the last two positions.

Such position control can realize the larger the difference, the relative increase of the arbitrage hedge, and the dispersion of the position, so as to grasp the small position of the small price fluctuation, and the large price fluctuation position is appropriately increased.

- closing position: stop loss and take profit

Fixed stop loss spread and take profit spread.

When the position difference reaches the take profit position and the stop loss position, the take profit and stop loss are carried out.

- The designing of entering the market and leaving the market

The period of the parameter ```NPeriod``` control provides some dynamic control over the opening and closing position of the strategy.

- Strategy chart

The strategy automatically generates a spread K-line chart to mark relevant transaction information.

c++ strategy custom chart drawing operation is also very simple. You can see that in the constructor of the hedge class, we use the written chart configuration string ```_cfgStr``` to configure the chart object ```_c```, ```_c``` is the private component of the hedge class. When the private member is initialized, the ```chart``` object constructed by the FMZ Quant platform custom chart API interface function is called.

_cfgStr = REOF( [{ विस्तार: { लेआउट: एकल, कोल: 6, ऊंचाई: 500px}, rangeSelector: {enabled: false}, tooltip: {xDateformat: %Y-%m-%d %H:%M:%S, %A}, plotOptions: {candlestick: {color: #d75442, upcolor: #6ba583}}, चार्ट:{प्रकार:लाइन}, title:{text:Spread Long}, xAxis:{title:{text:date}}, सीरीज़:[ {type:candlestick, name:Long Spread, data:[], id:dataseriesA}, {type:flags,data:[], onSeries: dataseriesA} ] }, { विस्तार: { लेआउट: एकल, कोल: 6, ऊंचाई: 500px}, rangeSelector: {enabled: false}, tooltip: {xDateformat: %Y-%m-%d %H:%M:%S, %A}, plotOptions: {candlestick: {color: #d75442, upcolor: #6ba583}}, चार्ट:{प्रकार:लाइन}, title:{text:Spread Short}, xAxis:{title:{text:date}}, सीरीज़:[ {type:candlestick, name:Long Spread, data:[], id:dataseriesA}, {type:flags,data:[], onSeries: dataseriesA} ] } ] ) ईओएफ; _c.update(_cfgStr); // चार्ट कॉन्फ़िगरेशन के साथ चार्ट ऑब्जेक्ट अपडेट करें _c.reset(); // चार्ट डेटा रीसेट करें。


call _c.update(_cfgStr); चार्ट ऑब्जेक्ट के लिए कॉन्फ़िगर करने के लिए _cfgStr का उपयोग करें.

call _c.reset(); चार्ट डेटा रीसेट करने के लिए.


When the strategy code needs to insert data into the chart, it also calls the member function of the ```_c``` object directly, or passes the reference of ```_c``` as a parameter, and then calls the object member function (method) of ```_c``` to update the chart data and insert operation.

E.g:

_c.add(chartIdx, {{x, UnixNano()/1000000}, {title, action}, {text, format(diff: %f, opPrice)}, {color, color}});


After placing the order, mark the K line chart.

As follows, when drawing a K line, a reference to the chart object ```_c``` is passed as a parameter when calling the member function ```feed``` of the ```BarFeeder``` class.

शून्य फ़ीड ((दोहरी कीमत, चार्ट *c=nullptr, int चार्टIdx=0)


That is, the formal parameter ```c``` of the ```feed``` function.

json point = {bar.Time, bar.Open, bar.High, bar.Low, bar.close}; // json प्रकार के डेटा का निर्माण करें यदि (c!= nullptr) { // चार्ट ऑब्जेक्ट पॉइंटर शून्य पॉइंटर के बराबर नहीं है, निम्न कार्य करें. यदि (newBar) { // नया बार दिखाई देता है अगर न्याय c->add(chartIdx, point); // चार्ट ऑब्जेक्ट सदस्य फ़ंक्शन add को चार्ट ऑब्जेक्ट में डेटा सम्मिलित करने के लिए कॉल करें (नया k लाइन बार) c->reset(1000); // केवल 1000 बार डेटा रखें } अन्य { c->add(chartIdx, बिंदु, -1); // अन्यथा अद्यतन (नई पट्टी नहीं), इस बिंदु (यह पट्टी अद्यतन). } }


Insert a new K-line Bar data into the chart by calling the ```add``` member function of the chart object ```_c```.

c->add ((chartIdx, बिंदु); `

बैकटेस्ट

“C++ version of OKEX futures contract hedging strategy” that takes you through hardcore quantitative strategy “C++ version of OKEX futures contract hedging strategy” that takes you through hardcore quantitative strategy “C++ version of OKEX futures contract hedging strategy” that takes you through hardcore quantitative strategy

यह रणनीति केवल सीखने और संचार के प्रयोजनों के लिए है। जब इसे वास्तविक बाजार में लागू किया जाए, तो कृपया इसे बाजार की वास्तविक स्थिति के अनुसार संशोधित और अनुकूलित करें।

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

FMZ क्वांट प्लेटफॉर्म में अधिक दिलचस्प रणनीतियाँ हैंःhttps://www.fmz.com


संबंधित सामग्री

अधिक जानकारी