Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   Обработка массива JSON (https://javascript.ru/forum/node-js-io-js/84166-obrabotka-massiva-json.html)

рони 24.06.2022 20:10

Redline,
медитируйте ...)))
<body>
    <script>
        let json = [{
                "symbol": "ORANGE",
                "id": 479640841,
                "side": "SELL",
                "price": "10",
                "qty": "2",
                "time": 1633371930706
            },
            {
                "symbol": "ORANGE",
                "id": 479640941,
                "side": "SELL",
                "price": "10",
                "qty": "1",
                "time": 1633371930899
            },
            {
                "symbol": "ORANGE",
                "id": 479640952,
                "side": "BUY",
                "price": "20",
                "qty": "3",
                "time": 1633371940488
            },
            {
                "symbol": "APPLE",
                "id": 193964871,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956055821
            },
            {
                "symbol": "APPLE",
                "id": 193964907,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956058086
            },
            {
                "symbol": "APPLE",
                "id": 193964908,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956058086
            },
            {
                "symbol": "APPLE",
                "id": 193965481,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956074364
            },
            {
                "symbol": "APPLE",
                "id": 193967061,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956209504
            },
            {
                "symbol": "APPLE",
                "id": 193967211,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956222593
            },
            {
                "symbol": "APPLE",
                "id": 193968864,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956403438
            },
            {
                "symbol": "APPLE",
                "id": 193969405,
                "side": "SELL",
                "price": "20",
                "qty": "70",
                "time": 1633956450685
            }
        ];

        let obj = json.reduce((ob, {
            symbol,
            id,
            side,
            price,
            qty,
            time
        }) => {
            side = side === "BUY" ? "LONG" : "SHORT";
            if(!ob[symbol]) ob[symbol] = {
                symbol,
                id,
                side,
                open: 0,
                profit: 0,
                volume: 0,
                openTime: time
            };

            ob[symbol].closedTime = time;

            let period = ob[symbol].side;
            price *= qty;
            if (period === side) {
                ob[symbol].open += +qty;
                ob[symbol].volume += +qty;
                ob[symbol].profit += price;
            } else {
                if (side === "LONG") ob[symbol].profit -= price;
                else ob[symbol].profit = price - ob[symbol].profit;
                ob[symbol].open -= qty;
            }

            return ob

        }, {});

        document.write(`<pre>${JSON.stringify(obj,'',1)}</pre>`, )
    </script>
</body>

Redline 24.06.2022 21:03

Еще забыл дополнить. Конструктор не будет знать заранее какой symbol он будет принимать. Он должен просто брать первый попавшийся symbol, и записывать все аналогичные символы, пока open не будет равен 0.
Если на пути попадается другой символ, то это уже начало новой сделки

Redline 24.06.2022 21:12

Благодарю, выглядит отлично:thanks:

Redline 24.06.2022 22:45

При добавлении нового элемента APPLE код работает с уже имеющимся в массиве APPLE, а не создает новый. Нужно научить код присваивать уникальный идентификатор к каждому объекту правильно понимаю?

В примере ниже я добавил еще одну сделку 10 BUY и 10 SELL

<body>
    <script>
        let json = [{
                "symbol": "ORANGE",
                "id": 479640841,
                "side": "SELL",
                "price": "10",
                "qty": "2",
                "time": 1633371930706
            },
            {
                "symbol": "ORANGE",
                "id": 479640941,
                "side": "SELL",
                "price": "10",
                "qty": "1",
                "time": 1633371930899
            },
            {
                "symbol": "ORANGE",
                "id": 479640952,
                "side": "BUY",
                "price": "20",
                "qty": "3",
                "time": 1633371940488
            },
            {
                "symbol": "APPLE",
                "id": 193964871,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956055821
            },
            {
                "symbol": "APPLE",
                "id": 193964907,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956058086
            },
            {
                "symbol": "APPLE",
                "id": 193964908,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956058086
            },
            {
                "symbol": "APPLE",
                "id": 193965481,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956074364
            },
            {
                "symbol": "APPLE",
                "id": 193967061,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956209504
            },
            {
                "symbol": "APPLE",
                "id": 193967211,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956222593
            },
            {
                "symbol": "APPLE",
                "id": 193968864,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956403438
            },
            {
                "symbol": "APPLE",
                "id": 193969405,
                "side": "SELL",
                "price": "20",
                "qty": "70",
                "time": 1633956450685
            },
            {
                "symbol": "APPLE",
                "id": 193968888,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956403438
            },
            {
                "symbol": "APPLE",
                "id": 193969444,
                "side": "SELL",
                "price": "20",
                "qty": "10",
                "time": 1633956450685
            }
        ];

        let obj = json.reduce((ob, {
            symbol,
            id,
            side,
            price,
            qty,
            time
        }) => {
            side = side === "BUY" ? "LONG" : "SHORT";
            if(!ob[symbol]) ob[symbol] = {
                symbol,
                id,
                side,
                open: 0,
                profit: 0,
                volume: 0,
                openTime: time
            };

            ob[symbol].closedTime = time;

            let period = ob[symbol].side;
            price *= qty;
            if (period === side) {
                ob[symbol].open += +qty;
                ob[symbol].volume += +qty;
                ob[symbol].profit += price;
            } else {
                if (side === "LONG") ob[symbol].profit -= price;
                else ob[symbol].profit = price - ob[symbol].profit;
                ob[symbol].open -= qty;
            }

            return ob

        }, {});

        document.write(`<pre>${JSON.stringify(obj,'',1)}</pre>`, )
    </script>
</body>

рони 24.06.2022 23:17

Redline,
Цитата:

Сообщение от Redline
Нужно научить код присваивать уникальный идентификатор к каждому объекту правильно понимаю?

условия известны только вам, формализовать их и максимально учесть все нюансы ваша задача.

<body>
    <script>
        let json = [{
                "symbol": "ORANGE",
                "id": 479640841,
                "side": "SELL",
                "price": "10",
                "qty": "2",
                "time": 1633371930706
            },
            {
                "symbol": "ORANGE",
                "id": 479640941,
                "side": "SELL",
                "price": "10",
                "qty": "1",
                "time": 1633371930899
            },
            {
                "symbol": "ORANGE",
                "id": 479640952,
                "side": "BUY",
                "price": "20",
                "qty": "3",
                "time": 1633371940488
            },
            {
                "symbol": "APPLE",
                "id": 193964871,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956055821
            },
            {
                "symbol": "APPLE",
                "id": 193964907,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956058086
            },
            {
                "symbol": "APPLE",
                "id": 193964908,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956058086
            },
            {
                "symbol": "APPLE",
                "id": 193965481,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956074364
            },
            {
                "symbol": "APPLE",
                "id": 193967061,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956209504
            },
            {
                "symbol": "APPLE",
                "id": 193967211,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956222593
            },
            {
                "symbol": "APPLE",
                "id": 193968864,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956403438
            },
            {
                "symbol": "APPLE",
                "id": 193969405,
                "side": "SELL",
                "price": "20",
                "qty": "70",
                "time": 1633956450685
            },
            {
                "symbol": "APPLE",
                "id": 193968888,
                "side": "BUY",
                "price": "15",
                "qty": "10",
                "time": 1633956403438
            },
            {
                "symbol": "APPLE",
                "id": 193969444,
                "side": "SELL",
                "price": "20",
                "qty": "10",
                "time": 1633956450685
            }
        ];

        let arr = json.reduce((ar, {
            symbol,
            id,
            side,
            price,
            qty,
            time
        }) => {
            side = side === "BUY" ? "LONG" : "SHORT";
            let e = ar.at(-1);
            if(!e || !e.open) {
            e = {
                symbol,
                id,
                side,
                open: 0,
                profit: 0,
                volume: 0,
                openTime: time
            };
            ar.push(e);
            };

            e.closedTime = time;

            let period = e.side;
            price *= qty;
            if (period === side) {
                e.open += +qty;
                e.volume += +qty;
                e.profit += price;
            } else {
                if (side === "LONG") e.profit -= price;
                else e.profit = price - e.profit;
                e.open -= qty;
            }

            return ar

        }, []);

        document.write(`<pre>${JSON.stringify(arr,'',1)}</pre>`, )
    </script>
</body>

Redline 24.06.2022 23:25

Благодарю вас еще раз. Да, в нюансах я ошибся :-?

Redline 30.06.2022 12:57

Вложений: 2
Доработал код, появилась проблема с большими числами. JS неправильно обрабатывает числа, я это помню. Код будет работать с большими массивами. Как добавить точность коду?

там где volume 0,0999999 должно быть 0,1 а второй массив не должен вообще появляться

рони 30.06.2022 13:22

Redline,
Округление/Неточные вычисления

alert(0.0999999.toFixed(1));

Redline 02.07.2022 02:01

Вложений: 2
добавил tofixed, но на 6 и 10 итерации прибавления никакой реакции. Будто он не видит этот метод

рони 02.07.2022 07:54

Redline,
сделайте округление когда уже массив сформирован
ordersBook = ordersBook.map(ordersBookItem => {
ordersBookItem.open = +ordersBookItem.open.toFixed(1); //  округляет неточности
ordersBookItem.volume = +ordersBookItem.volume.toFixed(1);
ordersBookItem.profitOpen = +ordersBookItem.profitOpen.toFixed(1);
ordersBookItem.profitClosed = +ordersBookItem.profitClosed.toFixed(1);
ordersBookItem.profit = +ordersBookItem.profit.toFixed(1);
return ordersBookItem;
});


Часовой пояс GMT +3, время: 22:53.