C++ 퓨처스 하이프레크루언스 스위트 코인 전략 OKEX 웹소켓 버전

저자:작은 꿈, 날짜: 2019-08-24 13:54:04
태그:C++울타리웹스코켓

C++ 퓨처스 하이프레크루언스 스위트 코인 전략 OKEX 웹소켓 버전

전략적 원칙

전략적 원리는 매우 간단하며, OKEX 계약 연장 헤딩, 포지션 제어 디자인 측면에서는, 격자 헤딩으로 설계되었다. 전략은 두 개의 계약, A 계약, B 계약을 정의합니다. 계약은 다른 계약 코드를 설정하여 헤지 할 수 있습니다. 예를 들어, A 계약은 분기 계약, B 계약은 주 계약 (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지금 시작하기 전에 이 오류를 보고하고, 순간 수십 페이지의 로그 /upload/asset/14bfcf6f9da5f49807e68.jpg

엘비스1213이 오류를 /upload/asset/14b9d3530ce1a60bde3ca.jpg에서 보고했지만 거래소는 OKEX 선물로 선택되었습니다.

가벼운 구름/upload/asset/5a8be467dae6c9a52b7d.jpg 꿈은 크고, 앞을 달리는 것이 좋고, 그 다음이 나오고, 어떻게 처리해야합니까? 감사합니다

와이즈이 전략은 EOS 선물에 지원합니까?

공군은 결코 노예가 될 수 없습니다.[json.exception.type_error.305] operator[]를 boolean과 함께 문자열 논증으로 사용할 수 없습니다. 이 문제를 어떻게 해결해야 할까요?

딱딱한exchange.SetContractType ((symbolA) 는 오류를 보고 bool 타입을 반환합니다.

작은 꿈첫 번째 오류는 Coin type wrong이며, 거래 쌍이 아닌지 확인하고, 화폐가 어디에 설정되어 있는지 잘못되었다. 두 번째 오류는 첫 번째 오류로 인해 빈번한 재시작으로 인해 거래소 인터페이스 액세스 빈도 제한을 초과하는 것으로 나타났습니다. 서버에 실행되는 로봇이 거래소를 방문하는 경우 빈도 제한을 초과하는 것이 쉽다는 점도 주목해야합니다.

작은 꿈코드, 당신은 디큐닝을 하고, ws 인터페이스read 이후의 데이터가 무엇인지 보아라. 문제를 찾아, 나는 테스트를 정상으로 한다.

알린이 서버는 거래 터미널에서 정상적으로 거래 할 수 있습니다.

작은 꿈인터넷에 연결이 안되는데도 데이터 전송이 안되는데도 네트워크 문제가 있다는 것을 알 수 있습니다.

알린K줄이 없습니다. 하나의 전략 그래프만 있습니다.

작은 꿈로봇이 실행될 때 페이지에 그래프가 나오나요? 그래프 K 라인이 나오면 정상이며 거래가 발생하지 않습니다. 그래프가 나오지 않으면 시장 문제를 나타냅니다. 확인하십시오.

작은 꿈만약 당신이 이 정책을 다시 복사한다면, 당신은 실행할 수 있고 테스트할 수 있습니다.

리 리산OKX 인터페이스가 바뀌지 않았다는 것을 알 수 있습니다.

작은 꿈이 정책은 재검토를 지원하지 않으며, 거래소 WS 인터페이스에 기반하기 때문에, 실시간으로 OKEX가 WS 인터페이스 포트가 변경되었는지 확인하려면 정책 코드에서 설정할 수 있습니다.

작은 꿈이 완전한 메시지는 JSON을 분석할 때 거래소ws 인터페이스에서 반환된 데이터의 이상으로 인해 발생했을 것으로 추정됩니다.

엘비스1213IP 문제가 해결되었습니다.

작은 꿈OKEX WS 인터페이스 주소는 변경된 것 같습니다. OKEX 문서에 가서 어떤 주소가 있는지 확인하려면 이제 입력하면 됩니다.

엘비스1213감사합니다.

작은 꿈이 전략은 주로 학습을 위해 사용되고, 실제 사용에 신중하며, 코드를 이해하고, 원칙을 이해하고, 자신의 거래 습관에 따라 최적화 변경을 권장합니다.

엘비스1213그리고 그 후에도, 저는 이 프로젝트가 성공적이라는 것을 깨달았습니다.

작은 꿈개인 관리자 서버를 사용하는 것이 좋습니다. 공용 서버는 연습, 테스트용입니다.

엘비스1213거래소는 OKEX 선물입니다. 서버와 관련이 있습니까? 저는 공공 서버 /upload/asset/14b2c038dcb23dfa93b8b.jpg를 선택했습니다.

작은 꿈거래소 객체를 구성해야 할 때, 현상품으로 선택하십시오. 재구성 테스트, 선택 할 때 선택: /upload/asset/178df7ad9e03924f4dda.png

가벼운 구름좋아요, 감사합니다, 저는 IP 테스트를 묶었습니다.

작은 꿈이 보고는 오류가 아니라 WS 인터페이스 데이터 이상, 정책이 인쇄한 이상 메시지입니다.

발명가 양자화호스팅을 업데이트하면 해결할 수 있습니다.

작은 꿈이 글은 오류 보고가 아니라, 예외가 포착된 후 인쇄된 메시지이고, 파란색 로그입니다. 이 문서는 다른 문장과 같은 문장과 같은 문장입니다. 또는 관리자가 더 오래되고 JSON이 문제를 처리합니다. 이 글은 다른 게시물에 의해 게시되었습니다.

작은 꿈오류 보고자료 스크린샷을 보거나 정보를 복사하고 붙여 보내십시오. 오류 전달 파라미터가 추정됩니다.