Skip to content

Commit

Permalink
Merge pull request #2160 from zeitgeistpm/tr-amm2-volume-issues
Browse files Browse the repository at this point in the history
Amm2 visual issues
  • Loading branch information
Robiquet authored Jan 11, 2024
2 parents 902bd5e + e034e00 commit 2d1c030
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 123 deletions.
4 changes: 3 additions & 1 deletion components/front-page/LatestTrades.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ const LatestTrades = ({
),
outcome: trade.outcomeName,
trade: trade.type === "buy" ? "Buy" : "Sell",
cost: formatNumberLocalized(trade.cost.div(ZTG).toNumber()),
cost: `${formatNumberLocalized(trade.cost.div(ZTG).toNumber())} ${
trade.costSymbol
}`,
price: formatNumberLocalized(trade.outcomePrice.toNumber()),
time: `${moment.duration(now.diff(trade.time)).humanize()} ago`,
};
Expand Down
37 changes: 31 additions & 6 deletions lib/gql/get-network-stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import { parseAssetIdString } from "lib/util/parse-asset-id";
import { getBaseAssetHistoricalPrices, lookupPrice } from "./historical-prices";
import {
PoolOrderByInput,
NeoPoolOrderByInput,
HistoricalSwapOrderByInput,
} from "@zeitgeistpm/indexer";

export const getNetworkStats = async (sdk: Sdk<FullContext>) => {
const [marketCountBN, basePrices, pools, historicalSwaps] = await Promise.all(
[
const [marketCountBN, basePrices, pools, neoPools, historicalSwaps] =
await Promise.all([
sdk.api.query.marketCommons.marketCounter(),
getBaseAssetHistoricalPrices(),
fetchAllPages(async (pageNumber, limit) => {
Expand All @@ -21,6 +22,14 @@ export const getNetworkStats = async (sdk: Sdk<FullContext>) => {
});
return pools;
}),
fetchAllPages(async (pageNumber, limit) => {
const { neoPools } = await sdk.indexer.neoPools({
limit: limit,
offset: pageNumber * limit,
order: NeoPoolOrderByInput.IdAsc,
});
return neoPools;
}),
fetchAllPages(async (pageNumber, limit) => {
const { historicalSwaps } = await sdk.indexer.historicalSwaps({
limit: limit,
Expand All @@ -29,10 +38,23 @@ export const getNetworkStats = async (sdk: Sdk<FullContext>) => {
});
return historicalSwaps;
}),
],
);
]);

const totalPoolVolumeUsd = pools.reduce<Decimal>((total, pool) => {
const poolCreationBaseAssetPrice = lookupPrice(
basePrices,
parseAssetIdString(pool.baseAsset) as BaseAssetId,
new Date(pool.createdAt).getTime(),
);

const volumeUsd = new Decimal(pool.volume).mul(
poolCreationBaseAssetPrice ?? 0,
);

return total.plus(volumeUsd);
}, new Decimal(0));

const totalVolumeUsd = pools.reduce<Decimal>((total, pool) => {
const totalNeopoolVolumeUsd = pools.reduce<Decimal>((total, pool) => {
const poolCreationBaseAssetPrice = lookupPrice(
basePrices,
parseAssetIdString(pool.baseAsset) as BaseAssetId,
Expand All @@ -54,6 +76,9 @@ export const getNetworkStats = async (sdk: Sdk<FullContext>) => {
return {
marketCount: marketCountBN.toNumber(),
tradersCount,
volumeUsd: totalVolumeUsd.div(ZTG).toNumber(),
volumeUsd: totalNeopoolVolumeUsd
.plus(totalPoolVolumeUsd)
.div(ZTG)
.toNumber(),
};
};
202 changes: 86 additions & 116 deletions lib/gql/trending-markets.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { PoolOrderByInput, PoolStatus } from "@zeitgeistpm/indexer";
import {
MarketOrderByInput,
MarketStatus,
ScoringRule,
} from "@zeitgeistpm/indexer";
import {
BaseAssetId,
FullContext,
IOForeignAssetId,
ScalarRangeType,
Sdk,
} from "@zeitgeistpm/sdk";
import { ZeitgeistPrimitivesMarketMarketCreation } from "@polkadot/types/lookup";
import { isNotNull } from "@zeitgeistpm/utility/dist/null";
import { IndexedMarketCardData } from "components/markets/market-card/index";
import Decimal from "decimal.js";
import { gql, GraphQLClient } from "graphql-request";
import { GraphQLClient, gql } from "graphql-request";
import { DAY_SECONDS, ZTG } from "lib/constants";
import { hiddenMarketIds } from "lib/constants/markets";
import {
Expand All @@ -21,17 +24,11 @@ import { getCurrentPrediction } from "lib/util/assets";
import { fetchAllPages } from "lib/util/fetch-all-pages";
import { parseAssetIdString } from "lib/util/parse-asset-id";
import { marketMetaFilter } from "./constants";
import { isNotNull } from "@zeitgeistpm/utility/dist/null";

const poolChangesQuery = gql`
query PoolChanges($start: DateTime, $end: DateTime) {
historicalPools(
where: {
timestamp_gt: $start
volume_gt: "0"
event_contains: "Swap"
timestamp_lt: $end
}
where: { timestamp_gt: $start, volume_gt: "0", timestamp_lt: $end }
orderBy: id_DESC
) {
poolId
Expand Down Expand Up @@ -111,107 +108,74 @@ const getTrendingMarkets = async (
end: now,
});

const pools = await fetchAllPages(async (pageNumber, limit) => {
const { pools } = await sdk.indexer.pools({
const markets = await fetchAllPages(async (pageNumber, limit) => {
const { markets } = await sdk.indexer.markets({
limit: limit,
offset: pageNumber * limit,
where: { status_eq: PoolStatus.Active },
order: PoolOrderByInput.IdAsc,
order: MarketOrderByInput.IdDesc,
where: {
status_eq: MarketStatus.Active,
scoringRule_eq: ScoringRule.Lmsr,
},
});
return pools;
return markets;
});

const basePrices = await getBaseAssetPrices(sdk);

const trendingPoolIds = calcTrendingPools(historicalPools, basePrices, pools);

const trendingMarkets = await Promise.all(
trendingPoolIds.map(async (poolId) => {
const marketsRes = await client.request<{
markets: {
marketId: number;
img: string;
question: string;
creation: ZeitgeistPrimitivesMarketMarketCreation["type"];
marketType: { [key: string]: string };
categories: { color: string; name: string }[];
outcomeAssets: string[];
baseAsset: string;
creator: string;
pool: {
volume: string;
};
tags: [];
status: string;
scalarType: ScalarRangeType;
period: { end: string };
}[];
}>(marketQuery, {
poolId: Number(poolId),
});

const market = marketsRes.markets[0];

if (!market) {
console.log("No market");
return null;
}

const assetsRes = await client.request<{
assets: {
pool: { poolId: number };
price: number;
assetId: string;
}[];
}>(assetsQuery, {
poolId: Number(poolId),
});

const assets = assetsRes.assets;

const prediction = getCurrentPrediction(assets, market);
const trendingMarketIds = calcTrendingMarkets(
historicalPools,
basePrices,
markets,
);

if (!market.categories) {
console.log("No categories for market", market.marketId);
return null;
}
const tm = trendingMarketIds.map((marketId) => {
const market = markets.find(
(market) => market.marketId === Number(marketId),
);

const marketCategories: MarketOutcomes = market.categories.map(
(category, index) => {
const asset = assets[index];
const marketCategory: MarketOutcome = {
...category,
assetId: market.outcomeAssets[index],
price: asset.price,
};
if (!market || !market.categories) return;
const marketCategories: MarketOutcomes = market.categories.map(
(category, index) => {
const asset = market.assets[index];

return marketCategory;
},
);
const marketCategory: MarketOutcome = {
name: category.name ?? "",
assetId: market.outcomeAssets[index],
price: asset.price,
};

const trendingMarket: IndexedMarketCardData = {
marketId: market.marketId,
question: market.question,
creation: market.creation,
img: market.img,
prediction: prediction,
creator: market.creator,
volume: Number(new Decimal(market.pool.volume).div(ZTG).toFixed(0)),
baseAsset: market.baseAsset,
outcomes: marketCategories,
pool: market.pool ?? null,
marketType: market.marketType,
tags: market.tags,
status: market.status,
scalarType: market.scalarType,
endDate: market.period.end,
};
return marketCategory;
},
);

return trendingMarket;
}),
);
const prediction = getCurrentPrediction(market.assets, market);

const trendingMarket: IndexedMarketCardData = {
marketId: market.marketId,
question: market.question ?? "",
creation: market.creation,
img: market.img ?? "",
prediction: prediction,
creator: market.creator,
volume: Number(
new Decimal(market.neoPool?.volume ?? 0).div(ZTG).toFixed(0),
),
baseAsset: market.baseAsset,
outcomes: marketCategories,
pool: market.pool ?? null,
neoPool: market.neoPool,
marketType: market.marketType as any,
tags: market.tags?.filter(isNotNull),
status: market.status,
scalarType: (market.scalarType ?? null) as "number" | "date" | null,
endDate: market.period.end,
};

return trendingMarket;
});

return trendingMarkets.filter(isNotNull);
return tm.filter(isNotNull);
};

const lookupPrice = (
Expand All @@ -223,46 +187,52 @@ const lookupPrice = (
: basePrices["ztg"];
};

const calcTrendingPools = (
const calcTrendingMarkets = (
transactions: {
poolId: number;
dVolume: string;
}[],
basePrices: ForeignAssetPrices,
pools: { poolId: number; baseAsset: string; status: string }[],
markets: { marketId: number; baseAsset: string }[],
) => {
const poolVolumes: { [key: string]: Decimal } = {};
const maxPools = 8;
const marketVolumes: { [key: string]: Decimal } = {};
const maxMarkets = 8;

// find total volume for each pool
// find total volume for each market
transactions.forEach((transaction) => {
const volume = poolVolumes[transaction.poolId];
if (volume) {
poolVolumes[transaction.poolId] = volume.plus(transaction.dVolume);
} else {
poolVolumes[transaction.poolId] = new Decimal(transaction.dVolume);
//for lsmr poolId === marketId
const marketId = transaction.poolId;

if (markets.some((market) => market.marketId === marketId)) {
const volume = marketVolumes[transaction.poolId];
if (volume) {
// for amm2 marketId === poolId
marketVolumes[transaction.poolId] = volume.plus(transaction.dVolume);
} else {
marketVolumes[transaction.poolId] = new Decimal(transaction.dVolume);
}
}
});

for (let poolId in poolVolumes) {
const base = pools.find((pool) => pool.poolId === Number(poolId))
for (let marketId in marketVolumes) {
const base = markets.find((market) => market.marketId === Number(marketId))
?.baseAsset;

const value = lookupPrice(
basePrices,
parseAssetIdString(base) as BaseAssetId,
);

poolVolumes[poolId] = poolVolumes[poolId].mul(value ?? 0);
marketVolumes[marketId] = marketVolumes[marketId].mul(value ?? 0);
}

const poolIdsByVolumeDesc = Object.keys(poolVolumes).sort((a, b) => {
const aVol = poolVolumes[a];
const bVol = poolVolumes[b];
const marketIdsByVolumeDesc = Object.keys(marketVolumes).sort((a, b) => {
const aVol = marketVolumes[a];
const bVol = marketVolumes[b];
return bVol.minus(aVol).toNumber();
});

return poolIdsByVolumeDesc.splice(0, maxPools);
return marketIdsByVolumeDesc.splice(0, maxMarkets);
};

export default getTrendingMarkets;
Loading

0 comments on commit 2d1c030

Please sign in to comment.