Часть кода Javascript не работает в правильном порядке - PullRequest
1 голос
/ 14 апреля 2019

Я создаю торгового бота на Javascript (у меня не было опыта работы с этим языком). Как работает функция трейлинг-стопа:

  • Websocket получает текущую рыночную цену
  • "active" - ​​логическая переменная, если true, запустите код
  • Если цена увеличивается на%, отмените старый стоп-лосс и добавьте новый выше.

Проблема, которую я получаю, состоит в том, что код работает не в правильном порядке. Если вы посмотрите на картинку, я не понимаю, почему синее поле все еще выполняется, если active - false. И поскольку программа иногда запускается в неправильном порядке, веб-сокет останавливается или работает так, как не должен.

Output

Это мой код веб-сокета с трейлинг-стопом:

function binanceTrailingSLOrder(symbol, orderId, quantity, oldPrice, percentage, active) {

    const clean_trade = client.ws.trades([symbol], trade => { //run websocket
        var livePrice = parseFloat(binance_symbols[symbol]["close"]); //set new price to live price

        if (active == true) {
            binanceCheckOrderStatus(symbol, orderId).then(r => {
                switch (r.status) {
                    case "PENDING":
                        if (livePrice >= (oldPrice * ((100 + percentage) / 100)) && active == true) {
                            active = false;
                            binanceCancelOrder(symbol, orderId).then((r4) => { //Cancel previous SL
                                var newSL = livePrice * ((100 - percentage) / 100);
                                binanceStopOrder(symbol, 'SELL', r4.origQty, newSL, newSL).then((r5) => { //Set new SL
                                    orderId = r5.orderId; quantity = r5.origQty; oldPrice = r5.price;
                                    active = true;
                                }).catch((err) => {
                                    console.log(err);
                                });
                            });
                        }
                        break;
                    default:
                        break;
                }

            });
        }
    });

}

Проверка функции статуса заказа:

//Get specific order status
function binanceCheckOrderStatus(symbol, orderId) {
    if(!orderId){
        console.log("order Id not found");
        return false;
    } else {
        var client = loadBinanceKeys2();

        return client.getOrder({
            symbol: symbol,
            orderId: orderId,
            recvWindow: 1000000
        }).then((order) => {
            return order;
        }).catch((err) => {
            console.log(err);
        });
    }
}

1 Ответ

2 голосов
/ 14 апреля 2019

Javascript имеет асинхронный характер. Функция binanceCheckOrderStatus() возвращает обещание. Механизм выполнения вызовет эту функцию, а затем перейдет к следующей строке. Блок кода после .then(r => выполняется только после завершения binanceCheckOrderStatus getOrder(). Теперь в этот период времени активный мог стать ложным в других .then() запросах. Это может сбивать с толку новых разработчиков. Поскольку вы используете в своем коде много .then(), вы должны понимать, что часть .then() выполняется только после того, как функция .then() завершит выполнение. Таким образом, функция, занимающая меньше времени, выполнит свою часть .then() раньше других. Короче говоря, вы НЕ МОЖЕТЕ контролировать порядок в этом сценарии, если вы не знаете, сколько времени займет каждая функция, что, вероятно, невозможно подтвердить. Для преодоления этой проблемы вы должны использовать async / await . Или вам нужно изменить свою логику, чтобы она не зависела от обещаний глубокого уровня.

Я не очень уверен в том, чего вы пытаетесь достичь здесь, но вот идея о том, как вы можете решить проблему заказа. Это просто ссылочный код, я его не проверял. Просто идея о том, как вы можете держать свои потоки, чтобы убедиться, что ваш код работает в порядке, используя async / await .

async function binanceTrailingSLOrder(symbol, orderId, quantity, oldPrice, percentage, active) {

    const clean_trade = client.ws.trades([symbol], async trade => { //run websocket
        var livePrice = parseFloat(binance_symbols[symbol]["close"]); //set new price to live price

        if (active == true) {

            try {

            const order = await binanceCheckOrderStatus(symbol, orderId);

            if (!order) {
                throw new Error('order not found')
            }
                switch (order.status) {
                    case "PENDING":
                        if (livePrice >= (oldPrice * ((100 + percentage) / 100)) && active == true) {
                            active = false;

                            const r4 = await binanceCancelOrder(symbol, orderId);
                            if (r4) {
                                var newSL = livePrice * ((100 - percentage) / 100);
                                var r5 = binanceStopOrder(symbol, 'SELL', r4.origQty, newSL, newSL);

                                if (r5) {
                                    orderId = r5.orderId; quantity = r5.origQty; oldPrice = r5.price;
                                    active = true;
                                }
                            }
                        }
                        break;
                    default:
                        break;
                }
            }

            catch(error) {
                console.log('error found: ', error);
            }

        }
    });

}



async function binanceCheckOrderStatus(symbol, orderId) {
    if(!orderId){
        console.log("order Id not found");
        return false;
    } else {
        var client = loadBinanceKeys2();

        return new Promise((resolve, reject) => {
            client.getOrder({
                symbol: symbol,
                orderId: orderId,
                recvWindow: 1000000
            }).then((order) => {
                resolve(order);
            }).catch((err) => {
                reject(err);
            });
        });
    }
}
...