C++ वायदा उच्च आवृत्ति सूट सिक्का रणनीति OKEX वेबसॉकेट संस्करण

लेखक:छोटे सपने, दिनांकः 2019-08-24 13:54:04
टैगःसी++हेजवेबस्कोकेट

C++ वायदा उच्च आवृत्ति सूट सिक्का रणनीति OKEX वेबसॉकेट संस्करण

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

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

  • डिजाइन विशेषताएं

    • कोड भाषा C++ भाषा का उपयोग करके कोड लिखने की रणनीति है, जिसमें तेज गति का प्रदर्शन लाभ है।

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

    • स्थिति नियंत्रण स्थिति नियंत्रण "पोफिनैच" संख्याओं के समान हेजिंग स्थिति अनुपात का उपयोग करके नियंत्रित किया जाता है। यह संभव है कि एक बड़ा अंतर, एक अपेक्षाकृत बढ़ी हुई सूट लाभ हेजिंग, एक छोटे से अंतर के साथ एक छोटे से स्थान को पकड़ने के लिए, एक बड़ा अंतर के साथ एक बड़ा स्थान को पकड़ने के लिए पदों पर फैला हुआ है।

    • पक्की स्थितिः घाटे में वृद्धि एक निश्चित स्टॉप-ड्रॉप, एक स्टॉप-लॉस, एक स्टॉप-ड्रॉप। जब तक स्टॉक की कीमत बढ़ जाती है, तब तक स्टॉप-लॉस की स्थिति में स्टॉप-लॉस किया जाता है।

    • बाजार में प्रवेश, बाजार से बाहर निकलना, चक्र डिजाइन पैरामीटर NPeriod द्वारा नियंत्रित चक्र रणनीति के लिए शुरुआती स्थिति पर कुछ गतिशील नियंत्रण करता है।

    • स्थिति संतुलन प्रणाली, ऑर्डर डिटेक्शन सिस्टम इस रणनीति के लिए एक विशेष समय-समय पर परीक्षण और संतुलन प्रणाली है। ऑर्डर डिटेक्शन सिस्टम।

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

    • रणनीतिक चार्ट रणनीति स्वचालित रूप से अंतर के लिए K-लाइन चार्ट उत्पन्न करती है, जो संबंधित लेनदेन की जानकारी को चिह्नित करती है।

  • पुनरीक्षण

    img

    img

    img


/*backtest
start: 2019-07-22 00:00:00
end: 2019-08-21 00:00:00
period: 1m
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD","stocks":0.1,"fee":[0.02,0.05]}]
args: [["InstrumentB","quarter"],["NPeriod",200],["LeavePeriod",100],["AddMax",3],["StopLoss",20],["StopWin",50],["OpenAmount",2]]
*/

enum State {
    STATE_NA,
    STATE_IDLE,
    STATE_HOLD_LONG,
    STATE_HOLD_SHORT,
};

string replace(string s, const string from, const string& to) {
    if(!from.empty())
        for(size_t pos = 0; (pos = s.find(from, pos)) != std::string::npos; pos += to.size())
            s.replace(pos, from.size(), to);
    return s;
}

class BarFeeder {
    public:
        BarFeeder(int period) : _period(period) {
            _rs.Valid = true;
        }

        void feed(double price, Chart *c=nullptr, int chartIdx=0) {
            uint64_t epoch = uint64_t(Unix() / _period) * _period * 1000;
            bool newBar = false;
            if (_rs.size() == 0 || _rs[_rs.size()-1].Time < epoch) {
                Record r;
                r.Time = epoch;
                r.Open = r.High = r.Low = r.Close = price;
                _rs.push_back(r);
                if (_rs.size() > 2000) {
                    _rs.erase(_rs.begin());
                }
                newBar = true;
            } else {
                Record &r = _rs[_rs.size() - 1];
                r.High = max(r.High, price);
                r.Low = min(r.Low, price);
                r.Close = price;
            }
    
            auto bar = _rs[_rs.size()-1];
            json point = {bar.Time, bar.Open, bar.High, bar.Low, bar.Close};
            if (c != nullptr) {
               if (newBar) {
                    c->add(chartIdx, point);
                    c->reset(1000);
                } else {
                    c->add(chartIdx, point, -1);
                } 
            }
        }
        Records & get() {
            return _rs;
        }
    private:
        int _period;
        Records _rs;
};

class Hedge {
  public:
    Hedge() {
        _isCover = true;
        _needCheckOrder = true;
        _st = STATE_NA;
        for (int i = 0; i < AddMax + 1; i++) {
            if (_addArr.size() < 2) {
                _addArr.push_back((i+1)*OpenAmount);
            }
            _addArr.push_back(_addArr[_addArr.size()-1] + _addArr[_addArr.size()-2]);
        }

        _cfgStr = R"EOF(
        [{
        "extension": { "layout": "single", "col": 6, "height": "500px"},
        "rangeSelector": {"enabled": false},
        "tooltip": {"xDateFormat": "%Y-%m-%d %H:%M:%S, %A"},
        "plotOptions": {"candlestick": {"color": "#d75442", "upColor": "#6ba583"}},
        "chart":{"type":"line"},
        "title":{"text":"Spread Long"},
        "xAxis":{"title":{"text":"Date"}},
        "series":[
            {"type":"candlestick", "name":"Long Spread","data":[], "id":"dataseriesA"},
            {"type":"flags","data":[], "onSeries": "dataseriesA"}
            ]
        },
        {
        "extension": { "layout": "single", "col": 6, "height": "500px"},
        "rangeSelector": {"enabled": false},
        "tooltip": {"xDateFormat": "%Y-%m-%d %H:%M:%S, %A"},
        "plotOptions": {"candlestick": {"color": "#d75442", "upColor": "#6ba583"}},
        "chart":{"type":"line"},
        "title":{"text":"Spread Short"},
        "xAxis":{"title":{"text":"Date"}},
        "series":[
            {"type":"candlestick", "name":"Long Spread","data":[], "id":"dataseriesA"},
            {"type":"flags","data":[], "onSeries": "dataseriesA"}
            ]
        }
        ]
        )EOF";
        _c.update(_cfgStr);
        _c.reset();
    };
    
    State getState(string &symbolA, Depth &depthA, string &symbolB, Depth &depthB) {
        
        if (!_needCheckOrder && _st != STATE_NA) {
            return _st;
        }

        //Log("sync orders");
        auto orders = exchange.GetOrders();
        if (!orders.Valid) {
            return STATE_NA;
        }

        if (orders.size() > 0) {
            for (auto &order : orders) {
                exchange.CancelOrder(order.Id);
            }
            return STATE_NA;
        }
        
        Sleep(500);
        
        //Log("sync positions");
        
        auto positions = exchange.GetPosition();
        if (!positions.Valid) {
            return STATE_NA;
        }
        
        // cache orders and positions;
        _needCheckOrder = false;
        
        if (positions.size() == 0) {
            //Log("Position is empty");
            return STATE_IDLE;
        }

        
        State st[2] = {STATE_IDLE, STATE_IDLE};
        double holdAmount[2] = {0, 0};
        double holdPrice[2] = {};
        for (auto &pos : positions) {
            int idx = -1;
            if (pos.ContractType == symbolA) {
                idx = 0;
            } else if (pos.ContractType == symbolB) {
                idx = 1;
            }
            if (idx >= 0) {
                holdPrice[idx] = pos.Price;
                holdAmount[idx] += pos.Amount;
                st[idx] = pos.Type == PD_LONG || pos.Type == PD_LONG_YD ? STATE_HOLD_LONG : STATE_HOLD_SHORT;
            }
        }

        if (holdAmount[0] > holdAmount[1]) {
            st[1] = STATE_IDLE;
        } else if (holdAmount[0] < holdAmount[1]) {
            st[0] = STATE_IDLE;
        }

        if (st[0] != STATE_IDLE && st[1] != STATE_IDLE) {
            // update
            _holdPrice = _N(holdPrice[1] - holdPrice[0], 4);
            _holdAmount = holdAmount[0];
            return st[0];
        } else if (st[0] == STATE_IDLE && st[1] == STATE_IDLE) {
            return STATE_IDLE;
        } else {
            double amount = abs(holdAmount[0] - holdAmount[1]);
            auto idx_fat = st[0] == STATE_IDLE ? 1 : 0;
            if (_isCover) {
                exchange.SetContractType(st[0] == STATE_IDLE ? symbolB : symbolA);
                if (st[idx_fat] == STATE_HOLD_LONG) {
                    exchange.SetDirection("closebuy");
                    exchange.Sell((st[0] == STATE_IDLE ? depthB.Bids[0].Price: depthA.Bids[0].Price)-SlidePrice, amount);
                } else {
                    exchange.SetDirection("closesell");
                    exchange.Buy((st[0] == STATE_IDLE ? depthB.Asks[0].Price : depthA.Asks[0].Price)+SlidePrice, amount);
                }
            } else {
                exchange.SetContractType(st[0] == STATE_IDLE ? symbolA : symbolB);
                if (st[idx_fat] == STATE_HOLD_LONG) {
                    exchange.SetDirection("sell");
                    exchange.Sell((st[0] == STATE_IDLE ? depthA.Bids[0].Price : depthB.Bids[0].Price)-SlidePrice, amount);
                } else {
                    exchange.SetDirection("buy");
                    exchange.Buy((st[0] == STATE_IDLE ? depthA.Asks[0].Price : depthB.Asks[0].Price)+SlidePrice, amount);
                }
            }
            
            _needCheckOrder = true;
            
            return STATE_NA;
        }
        Log(positions);
        Panic("WTF");
    }
    bool Loop(string &symbolA, Depth &depthA, string &symbolB, Depth &depthB, string extra="") {
        
        _loopCount++;
        auto diffLong = _N(depthB.Bids[0].Price - depthA.Asks[0].Price, 4);
        auto diffShort = _N(depthB.Asks[0].Price - depthA.Bids[0].Price, 4);
        
       _feederA.feed(diffLong, &_c, 0);
       _feederB.feed(diffShort, &_c, 2);
        
        auto barsA = _feederA.get();
        auto barsB = _feederB.get();

        if (barsA.size() < max(LeavePeriod, NPeriod) + 2) {
            LogStatus(_D(), "Calc His", barsA.size());
            return true;
        }
        
        bool expired = false;
        auto seconds = Unix();
        if (seconds - _lastCache > 600) {
            _needCheckOrder = true;
            expired = true;
        }
        
        State st = getState(symbolA, depthA, symbolB, depthB);
        if (st == STATE_NA) {
            return true;
        }
        if (st == STATE_IDLE) {
            _holdPrice = 0;
        }
        // cache st
        _st = st;
        if (expired) {
            _lastCache = seconds;
        }
        
        if (Unix() - seconds > 5) {
            Log("skip this tick");
            return true;
        }
        

        LogStatus(_D(), "State: ", _state_desc[st], "Hold:", _holdPrice, "Long:", diffLong, "Short:", diffShort, "Loop:", _loopCount, extra);

        if (st == STATE_IDLE && _isCover) {
            auto account = exchange.GetAccount();
            if (account.Valid) {
                double profit = _N(exchange.GetName() == "Futures_OKCoin" ? account.Stocks + account.FrozenStocks : account.Balance + account.FrozenBalance, 8);
                LogProfit(profit, _hedgeCount > 0 ? format("Net: %f @", profit) : "");
            }
            _isCover = false;
            return true;
        }
        auto ratio = abs(diffLong - diffShort);
        bool condOpenLong = (st == STATE_IDLE || st == STATE_HOLD_LONG) && (diffLong - _countOpen * max(1.0, _holdPrice * 0.1)) > TA.Highest(barsA.High(), NPeriod) && _countOpen < AddMax;
        bool condOpenShort = (st == STATE_IDLE || st == STATE_HOLD_SHORT) && (diffShort + _countOpen * max(1.0, _holdPrice * 0.1)) < TA.Lowest(barsB.Low(), NPeriod) && _countOpen < AddMax;
        bool condCoverLong = false;
        bool condCoverShort = false;
        bool isLeave = false;
        bool isStopLoss = false;
        bool isStopWin = false;
        if (st == STATE_HOLD_LONG) {
            auto leavePrice = (diffShort + _countCover + ratio);
            isLeave = leavePrice < TA.Lowest(barsB.Low(), LeavePeriod);
            if (!isLeave) {
                isStopLoss = diffShort - _holdPrice >= StopLoss;
                if (!isStopLoss) {
                    isStopWin = _holdPrice - diffShort >= StopWin;
                    if (isStopWin) {
                        Log("Stop Win", "HOLD:", _holdPrice, "SHORT:", diffShort);
                    }
                } else {
                    Log("StopLoss", "HOLD:", _holdPrice, "SHORT:", diffShort);
                }
            } else {
                Log("Leave normally", "LeavePrice:", leavePrice);
            }
            condCoverLong = isLeave || isStopLoss || isStopWin;
        } else if (st == STATE_HOLD_SHORT) {
            auto leavePrice = (diffLong - _countCover - ratio);
            isLeave = leavePrice > TA.Highest(barsA.High(), NPeriod);
            if (!isLeave) {
                isStopLoss = _holdPrice - diffLong >= StopLoss;
                if (!isStopLoss) {
                    isStopWin = diffLong - _holdPrice >= StopWin;
                    if (isStopWin) {
                        Log("Stop Win", "HOLD:", _holdPrice, "LONG:", diffLong);
                    }
                } else {
                    Log("StopLoss", "HOLD:", _holdPrice, "LONG:", diffLong);
                }
            } else {
                Log("Leave normally", "LeavePrice:", leavePrice);
            }
            condCoverShort = isLeave || isStopLoss || isStopWin;
        }
        
        string action, color;
        double opPrice;
        int chartIdx = 0;
        if (condOpenLong) {
            // Must Increase
            if (_countOpen > 0 && diffLong <= _holdPrice) {
                return STATE_IDLE;
            }
            
            _isCover = false;
            _countOpen++;
            _countCover = 0;
            _holdPrice = diffLong;
            auto amount = _addArr[_countOpen];

            if (_countOpen > 0) {
                Log("Add Position Long", _countOpen);
            }
            exchange.SetContractType(symbolB);
            exchange.SetDirection("sell");
            exchange.Sell(depthB.Bids[0].Price-SlidePrice, amount);

            exchange.SetContractType(symbolA);
            exchange.SetDirection("buy");
            exchange.Buy(depthA.Asks[0].Price+SlidePrice, amount);
            action = "L";
            color = "blue";
            opPrice = diffLong;
            chartIdx = 1;
        } else if (condOpenShort) {
            // Must Decrease
            if (_countOpen > 0 && diffShort >= _holdPrice) {
                return STATE_IDLE;
            }
            
            _isCover = false;
            _countOpen++;
            _countCover = 0;
            _holdPrice = diffShort;
            auto amount = _addArr[_countOpen];

            if (_countOpen > 0) {
                Log("Add Position Short", _countOpen);
            }
            exchange.SetContractType(symbolA);
            exchange.SetDirection("sell");
            exchange.Sell(depthA.Bids[0].Price-SlidePrice, amount);

            exchange.SetContractType(symbolB);
            exchange.SetDirection("buy");
            exchange.Buy(depthB.Asks[0].Price+SlidePrice, amount);
            
            action = "S";
            color = "red";
            opPrice = diffShort;
            chartIdx = 3;
        } else if (condCoverLong) {
            _isCover = true;
            _countOpen = 0;
            _countCover++;
            _hedgeCount++;
            if (_countCover > 0) {
                Log("Cover Position Long", _countCover);
            }
            exchange.SetContractType(symbolB);
            exchange.SetDirection("closesell");
            exchange.Buy(depthB.Asks[0].Price+SlidePrice, _holdAmount);

            exchange.SetContractType(symbolA);
            exchange.SetDirection("closebuy");
            exchange.Sell(depthA.Bids[0].Price-SlidePrice, _holdAmount);
            
           action = "CL";
           color = "blue";
           opPrice = diffShort;
            
           chartIdx = 3;
        } else if (condCoverShort) {
            _hedgeCount++;
            _isCover = true;
            _countOpen = 0;
            _countCover++;
            if (_countCover > 0) {
                Log("Cover Position Short", _countCover);
            }
            exchange.SetContractType(symbolA);
            exchange.SetDirection("closesell");
            exchange.Buy(depthA.Asks[0].Price+SlidePrice, _holdAmount);

            exchange.SetContractType(symbolB);
            exchange.SetDirection("closebuy");
            exchange.Sell(depthB.Bids[0].Price-SlidePrice, _holdAmount);
            action = "CS";
            color = "blue";
            opPrice = diffLong;
            chartIdx = 1;
        } else {
            return true;
        }
        _needCheckOrder = true;
            
        _c.add(chartIdx, {{"x", UnixNano()/1000000}, {"title", action},  {"text", format("diff: %f", opPrice)}, {"color", color}});
        Log(st, "Long:", diffLong, "Short:", diffShort, "Hold:", _holdPrice);
        return true;
    }

  private:
    
    vector<double> _addArr;
    string _state_desc[4] = {"NA", "IDLE", "LONG", "SHORT"};
    int _countOpen = 0;
    int _countCover = 0;
    int _lastCache = 0;
    int _hedgeCount = 0;
    int _loopCount = 0;
    double _holdPrice = 0;
    BarFeeder _feederA = BarFeeder(DPeriod);
    BarFeeder _feederB = BarFeeder(DPeriod);
    State _st = STATE_NA;
    string _cfgStr;
    double _holdAmount = 0;
    bool _isCover = false;
    bool _needCheckOrder = true;
    Chart _c = Chart("{}");
    
};

inline unsigned char toHex(unsigned char x) { 
    return  x > 9 ? x + 55 : x + 48; 
}

std::string urlencode(const std::string& str) {
    std::string strTemp = "";
    size_t length = str.length();
    for (size_t i = 0; i < length; i++)
    {
        if (isalnum((unsigned char)str[i]) || 
            (str[i] == '-') ||
            (str[i] == '_') || 
            (str[i] == '.') || 
            (str[i] == '~'))
            strTemp += str[i];
        else if (str[i] == ' ')
            strTemp += "+";
        else
        {
            strTemp += '%';
            strTemp += toHex((unsigned char)str[i] >> 4);
            strTemp += toHex((unsigned char)str[i] % 16);
        }
    }
    return strTemp;
}

uint64_t _Time(string &s) {
    tm t_init;
    t_init.tm_year  = 70;
    t_init.tm_mon   = 0;
    t_init.tm_mday  = 1;
    t_init.tm_hour  = 0;
    t_init.tm_min   = 0;
    t_init.tm_sec   = 0;
    
    tm t;
    int year, month, day, hour, minute, second, ms;
    sscanf(s.c_str(), "%d-%d-%dT%d:%d:%d.%dZ", &year, &month, &day, &hour, &minute, &second, &ms);
    t.tm_year  = year - 1900;
    t.tm_mon   = month - 1;
    t.tm_mday  = day;
    t.tm_hour  = hour;
    t.tm_min   = minute;
    t.tm_sec   = second;
    t.tm_isdst = 0;

    return uint64_t(mktime(&t))*1000+ms-uint64_t(mktime(&t_init))*1000;
}

void main() {
    // exchange.IO("base", "https://www.okex.me");   // 测试
    if (IsSetProxy) {
        exchange.SetProxy(Proxy);
    }
    
    LogReset();
    LogProfitReset();
    SetErrorFilter("ready|timeout|500");
    Log("Init OK");
    
    string symbolA = InstrumentA;
    string symbolB = InstrumentB;
    Hedge h;
    
    if (IsVirtual()) {
        while (true) {
            exchange.SetContractType(symbolA);
            auto depthA = exchange.GetDepth();
            if (depthA.Valid) {
                exchange.SetContractType(symbolB);
                auto depthB = exchange.GetDepth();
                if (depthB.Valid) {
                    h.Loop(symbolA, depthA, symbolB, depthB);
                }
            }
        }
        return;
    }
    if (exchange.GetName() != "Futures_OKCoin") {
        Panic("only support Futures_OKCoin");
    }
    string realSymbolA = exchange.SetContractType(symbolA)["instrument"];
    string realSymbolB = exchange.SetContractType(symbolB)["instrument"];

    string qs = urlencode(json({{"op", "subscribe"}, {"args", {"futures/depth5:" + realSymbolA, "futures/depth5:" + realSymbolB}}}).dump());
    Log("try connect to websocket");
    // wss://real.OKEx.com:8443/ws/v3
    auto ws = Dial("wss://real.okex.com:8443/ws/v3|compress=gzip_raw&mode=recv&reconnect=true&payload="+qs);
    // auto ws = Dial("wss://real.okex.me:8443/ws/v3|compress=gzip_raw&mode=recv&reconnect=true&payload="+qs);
    Log("connect to websocket success");
    
    Depth depthA, depthB;
    auto fillDepth = [](json &data, Depth &d) {
        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;
    string timeB;
    while (true) {
        auto buf = ws.read();

        // Log("buf:", buf);   // 测试
        
        json obj;
        try {
            obj = json::parse(buf);
        } catch (json::parse_error& e) {
            Log(buf);
            Log(e.what());
            continue;
        }
        if (obj["data"].size() == 0) {
            continue;
        }
        auto data = obj["data"][0];
        string ins = data["instrument_id"];
        if (ins == realSymbolA) {
            fillDepth(data, depthA);
            timeA = data["timestamp"];
        } else if (ins == realSymbolB) {
            fillDepth(data, depthB);
            timeB = data["timestamp"];
        }
        
        if (depthA.Valid && depthB.Valid) {
            auto diffA = uint64_t(UnixNano()/1000000)-_Time(timeA);
            auto diffB = uint64_t(UnixNano()/1000000)-_Time(timeB);

            if (diffA > MaxDelay || diffB > MaxDelay) {
                continue;
            }
            h.Loop(symbolA, depthA, symbolB, depthB, format("market delay (ms): %d, %d", diffA, diffB));
        }
    }
}





संबंधित

अधिक

छोटाऔर आप सोच रहे होंगे, क्या यह वास्तव में एक रनिंग बॉल है, यह चित्र में दिखाया गया है, लेकिन यह एक रनिंग बॉल है और यह बाहर कूद रहा है? Exchange_GetOrders: 429: {"error_message:"Too Many Requests","code":30014,"error_code":"30014","message:"Too Many Requests"} Exchange_GetOrders: 400: {"error_message":"Coin type wrong","code":30031,"error_code":"30031","message":"Coin type wrong"} इसका कारण क्या है?

अलिन/upload/asset/bb5df259b6a8148b1f65.png सपना बड़ा, कल दोपहर से रात तक नहीं चला, रात से फिर से चला और अब तक नहीं चला क्या आप सीधे वास्तविक डिस्क पर जा सकते हैं? 0.0

ली हास्यपुनः परीक्षण डिस्क में json परिमार्जन त्रुटि है

elvis1213/upload/asset/14bc485151de321c0a6a1.jpg कुछ समय के लिए चला और अचानक फिर से समस्याएं

elvis1213समस्या भगवान मेरी मदद करो, अब मैं शुरू करने के लिए इस त्रुटि की रिपोर्ट, और क्षण भर में दर्जनों पृष्ठों के लॉग / अपलोड/संपत्ति / 14bfcf6f9da5f49807e68.jpg

elvis1213यह त्रुटि /upload/asset/14b9d3530ce1a60bde3ca.jpg पर रिपोर्ट की गई थी, लेकिन एक्सचेंज ने ओकेएक्स फ्यूचर्स का चयन किया था।

हल्के बादल/upload/asset/5a8be467dae6c9a52b7d.jpg सपना बड़ा, आगे दौड़ना अच्छा है, और फिर यह बाहर आता है, मैं इसके साथ क्या करूँगा? धन्यवाद

विज़्ज़्सीबीक्या यह रणनीति ईओएस वायदा का समर्थन करती है?

वायुसेना कभी गुलाम नहीं होगी[json.exception.type_error.305] cannot use operator [] with a string argument with boolean, [json.exception.type_error.305] boolean के साथ एक स्ट्रिंग तर्क के साथ ऑपरेटर [] का उपयोग नहीं कर सकता, यह कैसे ठीक किया जा सकता है

कठोरexchange.SetContractType ((symbolA) यह फ़ंक्शन एक त्रुटि देता है, जो कि bool प्रकार देता है.

छोटे सपनेपहली त्रुटि Coin type wrong है, यह जांचने के लिए कि क्या लेन-देन जोड़ी है, मुद्रा कहां गलत है। दूसरी त्रुटि पहली त्रुटि के कारण है, जिसके कारण बार-बार पुनः प्रयास, एक्सचेंज इंटरफ़ेस तक पहुंच की आवृत्ति सीमा से अधिक है। एक सर्वर पर चलने वाले रोबोट को एक एक्सचेंज तक पहुंचने के लिए आवृत्ति सीमा से अधिक होने की संभावना है, इस पर भी ध्यान दें।

छोटे सपनेकोड, आप डीबग करते हैं और देखते हैं कि ws इंटरफेस read के बाद डेटा क्या है. समस्या खोजें, मेरा परीक्षण ठीक है.

अलिनक्या यह सर्वर की समस्या है? लेकिन यह सर्वर ट्रेडिंग टर्मिनल पर ठीक से OKEX पर ट्रेड कर सकता है।

छोटे सपनेयह नेटवर्क की समस्या को दर्शाता है. कोई एक्सचेंज कनेक्शन नहीं है. कोई डेटा नहीं भेजा गया है.

अलिनकोई K पंक्ति नहीं केवल एक रणनीति चार्ट /upload/asset/ba842a27a3766766bf54.png

छोटे सपनेजब रोबोट चलाता है, तो क्या पृष्ठ पर चार्ट आता है? चार्ट K लाइन बाहर आती है, यह सामान्य है, कोई लेनदेन नहीं होता है, यदि चार्ट नहीं आता है, तो बाजार की समस्या का वर्णन करें, जांचें।

छोटे सपनेयदि आप इस नीति को बदलते हैं, तो आप इसे फिर से दोहरा सकते हैं, इसे चला सकते हैं, परीक्षण कर सकते हैं।

ली हास्ययह OKX इंटरफ़ेस नहीं बदल रहा है.

छोटे सपनेयह नीति पुनः परीक्षण का समर्थन नहीं करती है, क्योंकि यह एक्सचेंज WS इंटरफ़ेस पर आधारित है, और वास्तविक समय में यह देखने के लिए कि क्या ओकेएक्स ने WS इंटरफ़ेस पोर्ट को बदल दिया है, इसे नीति कोड में सेट किया जा सकता है।

छोटे सपनेयह पूरी जानकारी, जो कि JSON को हल करने के दौरान Exchangews इंटरफ़ेस द्वारा लौटाए गए डेटा की असामान्यता के कारण है।

elvis1213आईपी समस्या हल हो गई है

छोटे सपनेOKEX WS इंटरफ़ेस का पता बदल गया है, OKEX दस्तावेज़ पर जाएं और देखें कि अब क्या पता है। इसे भरने के लिए, नीति में डायल फ़ंक्शन को भरने का पता है।

elvis1213धन्यवाद।

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

elvis1213भगवान का शुक्र है, यह सफलतापूर्वक तैनात किया गया है!

छोटे सपनेनिजी होस्ट सर्वर का उपयोग करने की सलाह दी जाती है; सार्वजनिक सर्वर केवल अभ्यास और परीक्षण के लिए हैं।

elvis1213एक्सचेंज ने ओकेएक्स फ्यूचर्स को चुना क्या यह सर्वर से संबंधित है, मैंने सार्वजनिक सर्वर /upload/asset/14b2c038dcb23dfa93b8b.jpg को चुना

छोटे सपनेएक्सचेंज ऑब्जेक्ट को कॉन्फ़िगर करने के लिए चुनें। पुनः कॉन्फ़िगर करें परीक्षण, चुनते समय चुनेंः /upload/asset/178df7ad9e03924f4dda.png

हल्के बादलठीक है, शुक्रिया डैडी, मैंने आईपी को बांड किया है।

छोटे सपनेयह एक त्रुटि रिपोर्ट नहीं है, यह एक असामान्य WS इंटरफ़ेस डेटा है, एक असामान्य संदेश जो नीति द्वारा मुद्रित किया गया है।

आविष्कारक मात्राअद्यतन होस्टिंग हल कर सकते हैं

छोटे सपनेयह कोई गलती रिपोर्टिंग नहीं है, यह एक अपवाद को पकड़ने के बाद एक नीले रंग के लॉग के रूप में छपी हुई जानकारी है। यदि आवश्यक न हो तो इस पंक्ति को कोड से हटाया जा सकता है। या शायद होस्ट पुराने हैं, और JSON इस समस्या का समाधान करता है। अब आप अपने होस्ट को अपडेट कर सकते हैं।

छोटे सपनेत्रुटि सूचना स्क्रीनशॉट देखें, या जानकारी को कॉपी और पेस्ट करें। अनुमानित त्रुटि पैरामीटर है।