وسائل لوڈ ہو رہے ہیں... لوڈنگ...

C++ فیوچر ہائی فریکوئنسی سوٹ کرنسی کی حکمت عملی OKEX ویب ساکٹ ورژن

مصنف:ایجاد کاروں کی مقدار - خواب، تاریخ: 2019-08-24 13:54:04
ٹیگز:C++ہیجویبسکوکیٹ

C++ فیوچر ہائی فریکوئنسی سوٹ کرنسی کی حکمت عملی OKEX ویب ساکٹ ورژن

حکمت عملی کے اصول

حکمت عملی کا اصول بہت آسان ہے ، اوکیکس معاہدے کے دوران ہیجنگ ، پوزیشن کنٹرول ڈیزائن کے لحاظ سے ، فرق گرڈ ہیجنگ کے لئے ڈیزائن کیا گیا ہے۔ حکمت عملی دو معاہدوں کی وضاحت کرتی ہے ، معاہدہ A ، معاہدہ B ؛ معاہدے کو مختلف معاہدے کے کوڈ کے ساتھ سیٹ کیا جاسکتا ہے ، اور ہیجنگ کی جاسکتی ہے۔ مثال کے طور پر، A معاہدہ کو سہ ماہی کے معاہدے کے طور پر مقرر کریں، اور B معاہدہ ہفتے کے معاہدے کے طور پر مقرر کریں (یہ بھی A کے طور پر مختصر مدت کے معاہدے کے طور پر مقرر کیا جا سکتا ہے، اور B طویل مدتی معاہدے کے طور پر مقرر کیا جا سکتا ہے، دوسری تعریفیں الٹ ہیں). ہیجنگ آپریشن کو خالی اے معاہدے (تاریخ) ، اور کثیر بی معاہدے (جیسے کہ اجناس کے مستقبل میں طویل مدتی سود کے لئے خالی طویل مدتی معاہدے ، اور زیادہ حالیہ معاہدے) میں تقسیم کیا گیا ہے۔ ایک سے زیادہ اے معاہدے کرنا ، بی معاہدہ کرنا (جیسے کموڈٹی فیوچر میں مختصر مدت ، طویل مدتی ، ریورس سیٹ کرنا)

  • ڈیزائن کی خصوصیات

    • کوڈ زبان اسٹریٹجک کوڈ C ++ زبان میں لکھا جاتا ہے ، جس میں تیز رفتار کارکردگی کے فوائد ہیں۔

    • ایک اور صارف نے لکھا: مارکیٹوں کو OKEX ویب ساکٹ کے ذریعہ چلایا جاتا ہے جس میں ایک انٹرفیس ہے جو ایکسچینج کو مارکیٹوں کو آگے بڑھانے کے لئے موصول ہوتا ہے ، مارکیٹوں کی تازہ ترین معلومات کو بروقت حاصل کیا جاتا ہے ، مارکیٹ کے اعداد و شمار کو کم مقدار میں استعمال کیا جاتا ہے ، ریئل ٹائم ٹِک ڈیٹا ، مارکیٹ کے ردعمل کی رفتار میں کافی اضافہ ہوا ہے۔ ٹک ڈیٹا کے لئے ، حکمت عملی نے خصوصی طور پر ایک 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 تجزیہ میں غلطیاں دکھاتی ہیں

ایلوس1213/upload/asset/14bc485151de321c0a6a1.jpg کچھ دیر چلتا رہا پھر اچانک ایک مسئلہ ہوا

ایلوس1213مشکل خدا میری مدد کریں، اب شروع کرنے کے لئے اس غلطی کی اطلاع دیں، اور فوری طور پر دسیوں صفحات کے لاگ ان / اپ لوڈ/asset/14bfcf6f9da5f49807e68.jpg

ایلوس1213یہ غلطی /upload/asset/14b9d3530ce1a60bde3ca.jpg میں رپورٹ کی گئی تھی ، لیکن تبادلے نے OKEX مستقبل کا انتخاب کیا ہے۔

ہلکے بادل/upload/asset/5a8be467dae6c9a52b7d.jpg خواب بڑا ہے، آگے دوڑنا اچھا ہے، اور پھر یہ باہر آتا ہے، کیا کروں؟ شکریہ

وائیز سی بیکیا یہ حکمت عملی EOS فیوچر کو سپورٹ کرتی ہے؟

فضائیہ کبھی غلام نہیں ہوگی[json.exception.type_error.305] cannot use operator [] with a string argument with boolean، [json.exception.type_error.305] کو بولین کے ساتھ ایک تار دلیل کے ساتھ آپریٹر [] استعمال نہیں کر سکتا، اس کو کیسے حل کیا جائے؟

سختexchange.SetContractType ((symbolA) اس فنکشن میں ایک خرابی ہے، جس کی واپسی کی قسم bool ہے۔ براہ کرم اس کو کیسے حل کریں؟

ایجاد کاروں کی مقدار - خوابپہلی غلطی Coin type wrong ہے ، چیک کریں کہ آیا ٹرانزیکشن جوڑی ہے ، کرنسی کہاں غلط سیٹ ہے۔ دوسری غلطی پہلی غلطی کی وجہ سے ہے ، جس کی وجہ سے بار بار دوبارہ کوشش کی جاتی ہے ، اور تبادلے کے انٹرفیس تک رسائی کی تعدد کی حد سے زیادہ ہوتی ہے۔ ایک سرور پر چلنے والا روبوٹ اگر ایک ہی تبادلے تک رسائی حاصل کرتا ہے تو ، اس کی تعدد کی حد سے تجاوز کرنا آسان ہے ، اس پر بھی توجہ دی جائے گی۔

ایجاد کاروں کی مقدار - خوابکوڈ، آپ کو ڈیبگ، دیکھیں کہ کیا ڈیٹا ہے جب آپ کے انٹرفیس کو پڑھا جاتا ہے۔ مسئلہ تلاش کریں، میں نے ٹیسٹ کیا ہے۔

ایلنکیا یہ سرور کا مسئلہ ہے؟ لیکن یہ سرور ٹرانزیکشن ٹرمینل پر کام کر سکتا ہے اور اوکیکس پر کام کر سکتا ہے۔

ایجاد کاروں کی مقدار - خواباس سے پتہ چلتا ہے کہ نیٹ ورک کا مسئلہ ہے۔ تبادلوں سے منسلک نہیں ہے۔ ڈیٹا کو آگے نہیں بڑھایا جاتا ہے۔

ایلنکوئی K لائن صرف ایک حکمت عملی گراف /upload/asset/ba842a27a3766766bf54.png

ایجاد کاروں کی مقدار - خوابجب روبوٹ چل رہا ہے تو ، کیا صفحے پر گراف سامنے آیا ہے؟ گراف K لائن باہر آتی ہے تو یہ معمول کی بات ہے ، تجارت کو متحرک نہیں کرتی ہے ، اگر گراف نہیں آتا ہے تو ، مارکیٹ کے مسئلے کی نشاندہی کرتے ہوئے ، چیک کریں۔

ایجاد کاروں کی مقدار - خواباگر آپ نے اپنی پالیسی کو تبدیل کر دیا ہے تو ، آپ اس کی نقل دوبارہ کرسکتے ہیں ، اسے چلائیں ، اسے آزمائیں۔

لی مسکراہٹآپ نے دیکھا کہ اوکیکس کے انٹرفیس میں کوئی تبدیلی نہیں آئی۔

ایجاد کاروں کی مقدار - خوابیہ حکمت عملی دوبارہ جانچ کی حمایت نہیں کرتی ہے کیونکہ یہ ایکسچینج کے WS انٹرفیس پر مبنی ہے ، اور حقیقی وقت میں یہ دیکھنے کے لئے کہ آیا OKEX نے WS انٹرفیس پورٹ کو تبدیل کیا ہے ، اسے حکمت عملی کے کوڈ میں ترتیب دیا جاسکتا ہے۔

ایجاد کاروں کی مقدار - خواباس مکمل پیغام کو جاری کیا گیا ہے، جو کہ JSON کو تجزیہ کرتے وقت ایکسچینج کے Ws انٹرفیس کی طرف سے واپس آنے والے اعداد و شمار کی خرابی کی وجہ سے ہونا چاہئے تھا۔

ایلوس1213آئی پی مسئلہ حل ہو گیا ہے

ایجاد کاروں کی مقدار - خوابOKEX WS انٹرفیس ایڈریس کو تبدیل کر دیا گیا ہے، OKEX دستاویزات پر جائیں اور دیکھیں کہ اب کیا پتہ ہے.

ایلوس1213شکریہ

ایجاد کاروں کی مقدار - خوابیہ حکمت عملی بنیادی طور پر سیکھنے کے لئے استعمال کی جاتی ہے ، عملی طور پر احتیاط سے ، کوڈ کو سمجھنے ، اصولوں کو سمجھنے اور اپنی تجارتی عادات کے مطابق اصلاحات کو بہتر بنانے کی تجویز ہے۔

ایلوس1213شکر ہے کہ یہ کام کامیاب رہا ہے!

ایجاد کاروں کی مقدار - خوابیہ مشورہ دیا جاتا ہے کہ نجی میزبان سرور استعمال کریں۔ عوامی سرور صرف مشق اور جانچ کے لئے ہے۔

ایلوس1213تبادلے کا انتخاب OKEX فیوچر ہے کیا یہ سرور سے متعلق ہے؟ میں نے عوامی سرور /upload/asset/14b2c038dcb23dfa93b8b.jpg کو منتخب کیا

ایجاد کاروں کی مقدار - خوابجب آپ کسی ایکسچینج آبجیکٹ کی تشکیل کرنا چاہتے ہیں تو ، اسے فوری طور پر منتخب کریں۔ دوبارہ ترتیب دیں ، آزمائشی آزمائشی کریں ، جب منتخب کریں: /upload/asset/178df7ad9e03924f4dda.png

ہلکے بادلاچھا، شکریہ ڈارلنگ، میں نے آئی پی کو پابند کیا ہے۔

ایجاد کاروں کی مقدار - خوابیہ ایک غلطی کی اطلاع نہیں ہے، یہ ایک غیر معمولی ڈیٹا ہے جو کہ WS انٹرفیس پر ہے، غیر معمولی پیغام جو کہ پالیسی پرنٹ کرتی ہے۔

ایجاد کنندہ کوانٹائزیشناپ ڈیٹ ہوسٹنگ اس مسئلے کو حل کرے گی

ایجاد کاروں کی مقدار - خوابیہ کوئی غلطی کی اطلاع نہیں ہے، یہ ایک غیر معمولی گرفتاری کے بعد ایک پرنٹ شدہ پیغام ہے، ایک نیلے رنگ کا نوشتہ۔ اگر ضرورت نہ ہو تو آپ کوڈ میں اس لائن کی پیداوار کو ہٹا سکتے ہیں۔ یا پھر یہ ہوسٹر زیادہ پرانا ہے اور JSON اس مسئلے کو سنبھال رہا ہے۔ اس کے بعد آپ اپنے میزبان کو اپ ڈیٹ کر سکتے ہیں۔

ایجاد کاروں کی مقدار - خوابغلطی کی اطلاع دیں اسکرین شاٹ کو دیکھیں ، یا معلومات کو کاپی اور پیسٹ کریں ؛ یہ اندازہ لگایا گیا ہے کہ غلطی کا پیرامیٹر ہے۔