C++ ফরোয়ার্ড হাই ফ্রিকোয়েন্সি স্যুট কয়েন কৌশল OKEX ওয়েবসকেট সংস্করণ

লেখক:ছোট্ট স্বপ্ন, তারিখ: ২০১৯-০৮-২৪ ১৩ঃ৪৪ঃ০৪
ট্যাগঃসি++হেজওয়েবসকোকেট

C++ ফরোয়ার্ড হাই ফ্রিকোয়েন্সি স্যুট কয়েন কৌশল OKEX ওয়েবসকেট সংস্করণ

কৌশলগত নীতি

কৌশলগত নীতিটি খুব সহজ, ওকেএক্স চুক্তির দীর্ঘমেয়াদী হেজিং, পজিশন নিয়ন্ত্রণের নকশার দিক থেকে, বিপরীত মূল্য গ্রিড হেজিং হিসাবে ডিজাইন করা হয়েছে। কৌশল দুটি চুক্তির সংজ্ঞা দেয়, A চুক্তি, B চুক্তি। চুক্তিগুলি বিভিন্ন চুক্তি কোড সেট করতে পারে, হেজিং করতে পারে। উদাহরণস্বরূপ, কন্ট্রাক্ট A কে কোয়ার্টারাল কন্ট্রাক্ট এবং কন্ট্রাক্ট B কে সাপ্তাহিক কন্ট্রাক্ট হিসাবে সেট করুন (এছাড়াও A কে নিকটবর্তী সময়ের কন্ট্রাক্ট এবং B কে দীর্ঘমেয়াদী কন্ট্রাক্ট হিসাবে সেট করা যেতে পারে, অন্য সংজ্ঞাটি বিপরীত) । হেজিং অপারেশনগুলিকে খালি A চুক্তি ((কোয়ার্টার) এবং একাধিক B চুক্তি ((সমতুল্য) হিসাবে বিভক্ত করা হয়। একাধিক এ চুক্তি, বি চুক্তি (সমতুল্য পণ্য ভবিষ্যতের মধ্যে সাম্প্রতিক সময়কাল, কত দীর্ঘমেয়াদী, বিপরীত)

  • ডিজাইন বৈশিষ্ট্য

    • কোড ভাষা কৌশলগতভাবে কোডটি C++ ভাষায় লেখা হয়, যার দ্রুত গতির পারফরম্যান্স সুবিধা রয়েছে।

    • এই ভিডিওটি ভিডিওতে দেখা যাচ্ছে। মার্কেট ড্রাইভটি ওকেএক্স ওয়েবসকেট ব্যবহার করে, ইন্টারফেসটি এক্সচেঞ্জের কাছে মার্কেট প্রেরণ করে, সর্বশেষতম মার্কেটগুলি আরও সময়মতো পাওয়া যায়, মার্কেট ডেটা কম পরিমাণে ব্যবহার করে, এবং রিয়েল টাইম টিক ডেটা। টিক ডেটার জন্য, কৌশলটি একটি বিশেষ কে-লাইন জেনারেটর তৈরি করেছে যা প্রাপ্ত টিক ডেটার গণনার পরে চুক্তির পার্থক্যের জন্য কে-লাইন সংশ্লেষণ করতে ব্যবহৃত হয়। কৌশলগত হেজিং অপারেশনের ওপেন পজিশন, পলিশিং উভয়ই এই কে-লাইন জেনারেটর শ্রেণীর বস্তু দ্বারা উত্পন্ন ডেটা দ্বারা চালিত হয়।

    • অবস্থান নিয়ন্ত্রণ পজিশন কন্ট্রোল হেকিং পজিশন অনুপাতের সাথে কাজ করে, যা "পফিন্যাচ" সংখ্যার মতো। ক্রমবর্ধমান ব্যবধানের সাথে, সুইচিং হেজিংয়ের পরিমাণ তুলনামূলকভাবে বৃদ্ধি পায়, পজিশনের উপর বিচ্ছিন্নতা করা হয়, যার ফলে ছোট ব্যবধানের অস্থিরতা ছোট পজিশনগুলি ধরে রাখে, বড় ব্যবধানের অস্থিরতা পজিশনগুলি যথাযথভাবে বৃদ্ধি পায়।

    • স্থিতিস্থাপকতাঃ ক্ষতি বন্ধ ফিক্সড স্টপ-ড্রপ, স্টপ-ড্রপ। হোল্ডিংয়ের পার্থক্যটি পিক পজিশনে পৌঁছানোর পরে, স্টপ লস পজিশনে স্টপ লস হয়।

    • বাজারে আসা, বের হওয়া, চক্রের নকশা প্যারামিটার এনপিরিওড নিয়ন্ত্রিত চক্র কৌশলটির ওপেন পজিশনের উপর একটি নির্দিষ্ট গতিশীল নিয়ন্ত্রণ করে।

    • পজিশন ব্যালেন্সিং সিস্টেম, অর্ডার সনাক্তকরণ সিস্টেম এই কৌশলটি একটি নির্দিষ্ট পর্যায়ক্রমিক পরীক্ষা এবং ভারসাম্য সিস্টেম দ্বারা পরিচালিত হয়। অর্ডার সনাক্তকরণ সিস্টেম।

    • কৌশলগত সম্প্রসারণ কৌশলগত কোড ডিজাইন কম সংযোজিত, যা পণ্যের ভবিষ্যতের জন্য হেজিংয়ের জন্য প্রসারিত করা যেতে পারে, বা আরও অনুকূলিতকরণ, সংশোধন করা যেতে পারে।

    • কৌশল চার্ট কৌশলটি স্বয়ংক্রিয়ভাবে 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 পার্সেল ত্রুটি দেখায়

এলভিস১২১৩/upload/asset/14bc485151de321c0a6a1.jpg কিছুক্ষণ ধরে চলছিল, হঠাৎ আবার সমস্যা হয়েছে।

এলভিস১২১৩সমস্যাময়ী ঈশ্বর আমাকে সাহায্য করুন, আমি এখনই এই ত্রুটিটি রিপোর্ট করতে চাই, এবং কয়েক ডজন পৃষ্ঠার লগ /upload/asset/14bfcf6f9da5f49807e68.jpg

এলভিস১২১৩আমি এই ত্রুটিটি /upload/asset/14b9d3530ce1a60bde3ca.jpg এ রিপোর্ট করেছি, কিন্তু এক্সচেঞ্জটি OKEX ফিউচারগুলি বেছে নিয়েছে।

হালকা মেঘ/upload/asset/5a8be467dae6c9a52b7d.jpg স্বপ্ন বড়, সামনে দৌড়ানো ভাল, এবং তারপর এটি বেরিয়ে আসে, কিভাবে এটি মোকাবেলা করবেন? ধন্যবাদ

উইজকিবিএই কৌশলটি কি ইওএস ফিউচারকে সমর্থন করে?

এয়ার ফোর্স কখনো দাসত্ব করবে না।[json.exception.type_error.305] cannot use operator [] with a string argument with boolean, [json.exception.type_error.305] [json.exception.type_error.305] [json.exception.type_error.305] [json.exception.type_error.305] [json.exception.type_error.305] ] [json.exception.type_error.305] [json.exception.type_error.305] [json.exception.type_error.305] [json.exception.type_error.305] ] [json.exception.type_error.305] [json.exception.type_error.305] ] [json.exception.type_error.305] [json.exception.type_error.305] [json.exception.type_error.305] ] [json.exception.exception.exception.exception.exception.exception.exception.exception. এটি কীভাবে সমাধান করা যায়?

কঠিনexchange.SetContractType ((symbolA) ফাংশনটি একটি ভুল রিটার্ন করে, এটি একটি bool টাইপ প্রদান করে।

ছোট্ট স্বপ্নপ্রথম ত্রুটি রিপোর্ট করা হয় Coin type wrong, যাচাই করা হয় কিনা লেনদেনের জোড়া, মুদ্রা কোন জায়গায় সেট করা ভুল হয়. দ্বিতীয় ত্রুটি প্রথম ত্রুটি কারণে, ঘন ঘন পুনরায় চেষ্টা, এক্সচেঞ্জ ইন্টারফেস অ্যাক্সেস ফ্রিকোয়েন্সি সীমা অতিক্রম করে। একটি সার্ভারে চলমান বট যদি একটি এক্সচেঞ্জ অ্যাক্সেস করা হয়, এটি ফ্রিকোয়েন্সি সীমা অতিক্রম করা সহজ।

ছোট্ট স্বপ্নকোড, আপনি ডিবাগ করুন, দেখুন ws ইন্টারফেসread এর পরে ডেটা কি। সমস্যা খুঁজুন, আমি পরীক্ষা করছি ভাল।

অ্যালিনসার্ভারের সমস্যা কি? কিন্তু সার্ভারটি ওকেএক্সে ট্রেডিং টার্মিনালে কাজ করে।

ছোট্ট স্বপ্নএটি নেটওয়ার্কের সমস্যাকে ব্যাখ্যা করে। বিনিময় কেন্দ্রে সংযোগ নেই। কোনও ডেটা প্রেরণ নেই।

অ্যালিনকোন K লাইন নেই শুধুমাত্র একটি কৌশল চার্ট /upload/asset/ba842a27a3766766bf54.png

ছোট্ট স্বপ্নরোবট চালানোর সময়, পৃষ্ঠায় চার্টটি কি প্রদর্শিত হয়? চার্ট K লাইনটি স্বাভাবিক, এটি কোনও লেনদেনের সূত্রপাত করে না, যদি চার্টটি না হয় তবে এটি বাজারের সমস্যা দেখায়, এটি পরীক্ষা করুন।

ছোট্ট স্বপ্নআপনি যদি এই কৌশলটি পুনরায় কপি করেন তবে আপনি এটি চালাতে পারেন এবং পরীক্ষা করতে পারেন।

লি হাসানওকেএক্স ইন্টারফেস পরিবর্তন হয়নি।

ছোট্ট স্বপ্নএই নীতিটি পুনরায় পরীক্ষা সমর্থন করে না, কারণ এটি এক্সচেঞ্জের ডাব্লুএস ইন্টারফেসের উপর ভিত্তি করে, বাস্তব সময়ে দেখতে হবে যে ওকেএক্স ডাব্লুএস ইন্টারফেসের পোর্ট পরিবর্তন হয়েছে কিনা।

ছোট্ট স্বপ্নএই সম্পূর্ণ বার্তাটি প্রকাশিত হয়েছে, যা সম্ভবত JSON বিশ্লেষণের সময় এক্সচেঞ্জের WS ইন্টারফেসের ফিরে আসা ডেটা ব্যতিক্রমের কারণে।

এলভিস১২১৩আইপি সমস্যা সমাধান হয়েছে।

ছোট্ট স্বপ্নOKEX WS ইন্টারফেস ঠিকানা পরিবর্তিত হয়েছে বলে মনে হচ্ছে, OKEX ডকুমেন্টেশনে গিয়ে দেখুন, এখন ঠিকানাটি কী। এটি পূরণ করা যেতে পারে, নীতিতে ডায়াল ফাংশনটি পূরণ করা ঠিকানা।

এলভিস১২১৩ধন্যবাদ।

ছোট্ট স্বপ্নএই কৌশলটি মূলত শেখার জন্য ব্যবহৃত হয়, বাস্তব ব্যবহারের জন্য সতর্কতা অবলম্বন করে, কোডটি বুঝতে, নীতিগুলি বুঝতে এবং নিজের ট্রেডিং অভ্যাস অনুসারে অনুকূলিতকরণের জন্য সংশোধন করার পরামর্শ দেওয়া হয়।

এলভিস১২১৩ধন্যবাদ ঈশ্বর, এটি সফলভাবে বাস্তবায়ন করা হয়েছে!

ছোট্ট স্বপ্নব্যক্তিগত হোস্ট সার্ভার ব্যবহার করার পরামর্শ দেওয়া হচ্ছে। পাবলিক সার্ভার শুধুমাত্র অনুশীলন এবং পরীক্ষার জন্য।

এলভিস১২১৩এক্সচেঞ্জটি OKEX ফিউচার নির্বাচন করেছে কি সার্ভারের সাথে সম্পর্কিত, আমি পাবলিক সার্ভার /upload/asset/14b2c038dcb23dfa93b8b.jpg নির্বাচন করেছি

ছোট্ট স্বপ্নএক্সচেঞ্জ অবজেক্ট কনফিগার করার সময়, এটিকে স্থির করুন। পুনরায় কনফিগার করার চেষ্টা করুন, নির্বাচন করার সময় নির্বাচন করুনঃ /upload/asset/178df7ad9e03924f4dda.png

হালকা মেঘভাল, থ্যাংকু ডগ, আমি আমার আইপি লিঙ্ক পরীক্ষা করেছি।

ছোট্ট স্বপ্নএটি কোনও ত্রুটি নয়, এটি একটি ডাব্লুএস ইন্টারফেস ডেটা অস্বাভাবিকতা, নীতিটি মুদ্রণ করে এমন একটি অস্বাভাবিক বার্তা।

উদ্ভাবক পরিমাণহোস্ট আপডেট সমাধান করবে

ছোট্ট স্বপ্নএটি একটি ভুল রিপোর্ট নয়, এটি একটি ব্যতিক্রম ধরা পরে একটি প্রিন্ট করা বার্তা, একটি নীল লগ। যদি প্রয়োজন না হয় তাহলে কোড থেকে এই লাইনটি মুছে ফেলা যেতে পারে। অথবা হোস্টটি পুরোনো, এবং JSON এই সমস্যাটি নিয়ে কাজ করছে। আপনি আপনার হোস্ট আপডেট করতে পারেন।

ছোট্ট স্বপ্নত্রুটি রিপোর্ট করুন স্ক্রিনশট দেখুন, অথবা তথ্য কপি এবং পেস্ট করুন।