Merge branch 'dev' into staging
This commit is contained in:
commit
1adf191e37
2 changed files with 141 additions and 12 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import getAssetStatsRes from '@/interfaces/responses/stats/getAssetStatsRes';
|
||||
import getTotalStatsRes from '@/interfaces/responses/stats/getTotalStatsRes';
|
||||
import Currency from '@/schemes/Currency';
|
||||
import Order from '@/schemes/Order';
|
||||
import Pair from '@/schemes/Pair';
|
||||
|
|
@ -7,6 +8,14 @@ import Decimal from 'decimal.js';
|
|||
import { Request, Response } from 'express';
|
||||
import { Op } from 'sequelize';
|
||||
|
||||
interface OrderWithBuyOrders extends Order {
|
||||
buy_orders: Transaction[];
|
||||
}
|
||||
|
||||
interface PairWithFirstCurrency extends Pair {
|
||||
first_currency: Currency;
|
||||
}
|
||||
|
||||
class StatsController {
|
||||
async getAssetStats(req: Request, res: Response) {
|
||||
try {
|
||||
|
|
@ -51,11 +60,9 @@ class StatsController {
|
|||
market_cap: currentSupply.mul(pair.rate || 0).toString(),
|
||||
};
|
||||
|
||||
interface OrderWithBuyOrders extends Order {
|
||||
buy_orders?: Transaction[];
|
||||
}
|
||||
|
||||
if (
|
||||
from_timestamp &&
|
||||
from_timestamp &&
|
||||
typeof from_timestamp_parsed === 'number' &&
|
||||
typeof to_timestamp_parsed === 'number'
|
||||
) {
|
||||
|
|
@ -72,19 +79,25 @@ class StatsController {
|
|||
model: Transaction,
|
||||
as: 'buy_orders',
|
||||
attributes: ['amount'],
|
||||
required: false,
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
order: [['timestamp', 'ASC']],
|
||||
})) as OrderWithBuyOrders[];
|
||||
|
||||
const filteredOrders = ordersWithTransactions.filter((order) => order.buy_orders && order.buy_orders.length > 0);
|
||||
const filteredOrders = ordersWithTransactions.filter(
|
||||
(order) => order.buy_orders && order.buy_orders.length > 0,
|
||||
);
|
||||
|
||||
const volumeZano = filteredOrders.reduce((acc, order) => (
|
||||
order?.buy_orders?.reduce((innerAcc, tx) => innerAcc.add(
|
||||
new Decimal(tx.amount).mul(new Decimal(order.price)),
|
||||
), acc) || acc
|
||||
), new Decimal(0));
|
||||
const volumeZano = filteredOrders.reduce(
|
||||
(acc, order) =>
|
||||
order?.buy_orders?.reduce(
|
||||
(innerAcc, tx) =>
|
||||
innerAcc.add(new Decimal(tx.amount).mul(new Decimal(order.price))),
|
||||
acc,
|
||||
) || acc,
|
||||
new Decimal(0),
|
||||
);
|
||||
|
||||
const firstPrice = new Decimal(filteredOrders[0]?.price || 0);
|
||||
const lastPrice = new Decimal(filteredOrders.at(-1)?.price || 0);
|
||||
|
|
@ -111,7 +124,105 @@ class StatsController {
|
|||
|
||||
async getTotalStats(req: Request, res: Response) {
|
||||
try {
|
||||
// soon
|
||||
const { from_timestamp, to_timestamp } = req.query;
|
||||
|
||||
const from_timestamp_parsed = parseInt(from_timestamp as string, 10);
|
||||
const to_timestamp_parsed = parseInt(to_timestamp as string, 10);
|
||||
|
||||
const response: getTotalStatsRes = {
|
||||
largest_tvl: {
|
||||
asset_id: 'soon',
|
||||
tvl: 'soon',
|
||||
},
|
||||
total_tvl: 'soon',
|
||||
};
|
||||
|
||||
if (
|
||||
from_timestamp &&
|
||||
from_timestamp &&
|
||||
typeof from_timestamp_parsed === 'number' &&
|
||||
typeof to_timestamp_parsed === 'number'
|
||||
) {
|
||||
const ordersWithTransactions = (await Order.findAll({
|
||||
where: {
|
||||
timestamp: {
|
||||
[Op.between]: [from_timestamp_parsed, to_timestamp_parsed],
|
||||
},
|
||||
},
|
||||
attributes: ['id', 'price', 'pair_id'],
|
||||
include: [
|
||||
{
|
||||
model: Transaction,
|
||||
as: 'buy_orders',
|
||||
attributes: ['amount'],
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
order: [['timestamp', 'ASC']],
|
||||
})) as OrderWithBuyOrders[];
|
||||
|
||||
const involvedPairs = [
|
||||
...new Set(ordersWithTransactions.map((order) => order.pair_id)),
|
||||
];
|
||||
|
||||
const pairVolumes = ordersWithTransactions.reduce(
|
||||
(acc, order) => {
|
||||
const orderVolume = order.buy_orders.reduce(
|
||||
(sum, t) => sum + Number(order.price) * Number(t.amount),
|
||||
0,
|
||||
);
|
||||
|
||||
acc[order.pair_id] = (acc[order.pair_id] || 0) + orderVolume;
|
||||
return acc;
|
||||
},
|
||||
{} as Record<number, number>,
|
||||
);
|
||||
|
||||
const entries = Object.entries(pairVolumes);
|
||||
|
||||
let maxPairId = Number(entries[0][0]); // берём первый элемент как старт
|
||||
let maxVolume = entries[0][1];
|
||||
|
||||
for (const [pairId, volume] of entries) {
|
||||
if (volume > maxVolume) {
|
||||
maxVolume = volume;
|
||||
maxPairId = Number(pairId);
|
||||
}
|
||||
}
|
||||
|
||||
const biggestPair = (await Pair.findByPk(maxPairId, {
|
||||
attributes: [],
|
||||
include: [
|
||||
{
|
||||
model: Currency,
|
||||
as: 'first_currency',
|
||||
attributes: ['asset_id'],
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
})) as PairWithFirstCurrency;
|
||||
|
||||
const totalVolume = Object.values(pairVolumes).reduce(
|
||||
(sum, volume) => sum + volume,
|
||||
0,
|
||||
);
|
||||
|
||||
const period_data = {
|
||||
active_tokens: involvedPairs.length.toString(),
|
||||
most_traded: {
|
||||
asset_id: biggestPair.first_currency.asset_id,
|
||||
volume: maxVolume.toString(),
|
||||
},
|
||||
total_volume: totalVolume.toString(),
|
||||
};
|
||||
|
||||
response.period_data = period_data;
|
||||
}
|
||||
|
||||
return res.status(200).send({
|
||||
success: true,
|
||||
data: response,
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(500).send({ success: false, data: 'Unhandled error' });
|
||||
|
|
|
|||
18
src/interfaces/responses/stats/getTotalStatsRes.ts
Normal file
18
src/interfaces/responses/stats/getTotalStatsRes.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
interface getTotalStatsRes {
|
||||
largest_tvl: {
|
||||
asset_id: string;
|
||||
tvl: string;
|
||||
};
|
||||
total_tvl: string;
|
||||
|
||||
period_data?: {
|
||||
active_tokens: string;
|
||||
most_traded: {
|
||||
asset_id: string;
|
||||
volume: string;
|
||||
};
|
||||
total_volume: string;
|
||||
};
|
||||
}
|
||||
|
||||
export default getTotalStatsRes;
|
||||
Loading…
Add table
Reference in a new issue