Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mexc watchOrders bug #23231

Open
little-bit-time opened this issue Jul 26, 2024 · 4 comments
Open

mexc watchOrders bug #23231

little-bit-time opened this issue Jul 26, 2024 · 4 comments
Assignees

Comments

@little-bit-time
Copy link

Operating System

debian

Programming Languages

JavaScript

CCXT Version

4.3.68

Description

Hi, help me fix the error.

while (true) {
   const orders = await exchange.watchOrders();
}

I have 3 spot orders on mexc. I change the price via a web browser. I receive two messages. The first one is about order cancellation, and the second one is about creating an order with a new price. But in watchOrders() I only see the first message about order exchange.

After analyzing, I found out.

  1. in "handleOrder(client, message)" all messages (about cancellation and creating a new one with a new price) come and are sent "client.resolve(orders, messageHash);"
  2. in /base/ws/Client.js in the line "if ((messageHash !== undefined) && (messageHash in this.futures))" in the first message everything is processed correctly, but in the second message this.futures is empty and does not allow sending data.

Tell me how to fix it? I suspect that the code is to blame. listenKey is constantly updated, although if you look at the logic of this.authenticate, it should remember and reuse.

   async watchSpotPrivate(channel, messageHash, params = {}) {
        this.checkRequiredCredentials();
        const listenKey = await this.authenticate(channel);

        const url = this.urls['api']['ws']['spot']   '?listenKey='   listenKey;
        const request = {
            'method': 'SUBSCRIPTION',
            'params': [channel],
        };

        const res = await this.watch(url, messageHash, this.extend(request, params), channel);

        return res;
    }

Code

  

@little-bit-time
Copy link
Author

const exchangeSpotWS = new ccxt.pro.mexc({
    apiKey: 'xxx',
    secret: 'xxx',
    options: {
        defaultType: 'spot',
        listenKey: '9b99995bf38fba58d8axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxf328523da8f'
    }
});

If you register listenKey, everything works fine.

@little-bit-time
Copy link
Author

The error occurs because I run 2 private methods at the same time. And this check is passed 2 times => listenKey is received 2 times. Now I will try to delay the launch of watchOrders and some other private method, it should solve my problem.

async authenticate(subscriptionHash, params = {}) {
        let listenKey = this.safeString(this.options, 'listenKey');
        if (listenKey !== undefined) {
            return listenKey;
        }

@little-bit-time
Copy link
Author

I created a temporary fix for the authenticate method by adding listenKeyProcess. If a listenKey is being obtained, any new requests for it are delayed. Perhaps someone can implement a more elegant solution.

    async authenticate(subscriptionHash, params = {}) {

        let listenKeyProcess = this.safeBool(this.options, 'listenKeyProcess', false);
        //console.log("listenKeyProcess: "   listenKeyProcess);
        let listenKey;

        // we only need one listenKey since ccxt shares connections
        if (listenKeyProcess) {

            for (let attempt = 0; attempt < 20; attempt  ) {

                //console.log("get OLD listenKey: "   attempt);

                listenKey = this.safeString(this.options, 'listenKey');
                if (listenKey !== undefined) {

                    //console.log("return OLD listenKey: "   listenKey);

                    return listenKey;
                }
                // Задержка 200 мс перед следующей попыткой
                await new Promise(resolve => setTimeout(resolve, 1000));
            }

        } else {

            listenKey = this.safeString(this.options, 'listenKey');
            if (listenKey !== undefined) {
                return listenKey;
            }

        }

        this.options['listenKeyProcess'] = true;

        //console.log("run get listenKey");

        const response = await this.spotPrivatePostUserDataStream(params);
        //
        //    {
        //        "listenKey": "pqia91ma19a5s61cv6a81va65sdf19v8a65a1a5s61cv6a81va65sdf19v8a65a1"
        //    }
        //
        listenKey = this.safeString(response, 'listenKey');
        this.options['listenKey'] = listenKey;

        //console.log("success get listenKey: "   listenKey);

        this.options['listenKeyProcess'] = false;

        const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 1200000);
        this.delay(listenKeyRefreshRate, this.keepAliveListenKey, listenKey, params);
        return listenKey;
    }

@sc0Vu sc0Vu self-assigned this Aug 16, 2024
@sc0Vu
Copy link
Contributor

sc0Vu commented Aug 16, 2024

@little-bit-time Can you paste code that we can reproduce this locally (please remove any sensitive information)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants