Skip to content

Commit

Permalink
Derive the %Diff reference price from a less noisy metric (#168)
Browse files Browse the repository at this point in the history
Changes the %Diff reference price to use the median unit price of the last 7 days
of sales. This will make it based on the actual selling price and less vulnerable to
high-priced listings shifting the value to an unrealistic amount.

This aims to make the %Diff more useful for sellers and purchasers by communicating
something about what the useful selling prices are, rather than whatever the current
arbitrary listing prices are.
  • Loading branch information
karashiiro authored Dec 7, 2024
1 parent d9958a7 commit 09594bb
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 73 deletions.
1 change: 1 addition & 0 deletions components/Market/MarketAverages/MarketAverages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default function MarketAverages({
</div>
</div>
<div>
{/* TODO: Why is this useful? Maybe it should just be removed. */}
<h5>
<Trans>Avg. Total</Trans>
</h5>
Expand Down
63 changes: 30 additions & 33 deletions components/Market/MarketDataCenter/MarketDataCenter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ import MarketHistoryGraph from '../MarketHistoryGraph/MarketHistoryGraph';
import MarketStackSizeHistogram from '../MarketStackSizeHistogram/MarketStackSizeHistogram';
import { useDataCenterMarket } from '../../../hooks/market';
import MarketWorld from '../MarketWorld/MarketWorld';
import { MarketV2 } from '../../../types/universalis/MarketV2';
import { calculateReferencePrice, Quality } from '../utils';

interface MarketDataCenterProps {
item: Item;
dc: DataCenter;
market: any;
market: MarketV2;
lang: Language;
open: boolean;
}
Expand All @@ -26,56 +28,51 @@ function entriesToShow(entries: {}[]) {
}

export default function MarketDataCenter({ item, dc, market, lang, open }: MarketDataCenterProps) {
const hqListings = market.listings?.filter((listing: any) => listing.hq) ?? [];
const nqListings = market.listings?.filter((listing: any) => !listing.hq) ?? [];
const hqSales = market.recentHistory?.filter((sale: any) => sale.hq) ?? [];
const nqSales = market.recentHistory?.filter((sale: any) => !sale.hq) ?? [];
const hqListings = market.listings?.filter((listing) => listing.hq) ?? [];
const nqListings = market.listings?.filter((listing) => !listing.hq) ?? [];
const hqSales = market.recentHistory?.filter((sale) => sale.hq) ?? [];
const nqSales = market.recentHistory?.filter((sale) => !sale.hq) ?? [];

const hqListingsAveragePpu =
Math.ceil(
hqListings
.map((listing: any) => listing.pricePerUnit)
.reduce((agg: any, next: any) => agg + next, 0) / hqListings.length
hqListings.map((listing) => listing.pricePerUnit).reduce((agg, next) => agg + next, 0) /
hqListings.length
) || 0;
const nqListingsAveragePpu =
Math.ceil(
nqListings
.map((listing: any) => listing.pricePerUnit)
.reduce((agg: any, next: any) => agg + next, 0) / nqListings.length
nqListings.map((listing) => listing.pricePerUnit).reduce((agg, next) => agg + next, 0) /
nqListings.length
) || 0;
const hqListingsAverageTotal =
Math.ceil(
hqListings
.map((listing: any) => listing.total)
.reduce((agg: any, next: any) => agg + next, 0) / hqListings.length
hqListings.map((listing) => listing.total).reduce((agg, next) => agg + next, 0) /
hqListings.length
) || 0;
const nqListingsAverageTotal =
Math.ceil(
nqListings
.map((listing: any) => listing.total)
.reduce((agg: any, next: any) => agg + next, 0) / nqListings.length
nqListings.map((listing) => listing.total).reduce((agg, next) => agg + next, 0) /
nqListings.length
) || 0;
const hqSalesAveragePpu =
Math.ceil(
hqSales.map((sale: any) => sale.pricePerUnit).reduce((agg: any, next: any) => agg + next, 0) /
hqSales.length
hqSales.map((sale) => sale.pricePerUnit).reduce((agg, next) => agg + next, 0) / hqSales.length
) || 0;
const nqSalesAveragePpu =
Math.ceil(
nqSales.map((sale: any) => sale.pricePerUnit).reduce((agg: any, next: any) => agg + next, 0) /
nqSales.length
nqSales.map((sale) => sale.pricePerUnit).reduce((agg, next) => agg + next, 0) / nqSales.length
) || 0;
const hqSalesAverageTotal =
Math.ceil(
hqSales.map((sale: any) => sale.total).reduce((agg: any, next: any) => agg + next, 0) /
hqSales.length
hqSales.map((sale) => sale.total).reduce((agg, next) => agg + next, 0) / hqSales.length
) || 0;
const nqSalesAverageTotal =
Math.ceil(
nqSales.map((sale: any) => sale.total).reduce((agg: any, next: any) => agg + next, 0) /
nqSales.length
nqSales.map((sale) => sale.total).reduce((agg, next) => agg + next, 0) / nqSales.length
) || 0;

const nqReferencePrice = calculateReferencePrice(market, Quality.NormalQuality);
const hqReferencePrice = calculateReferencePrice(market, Quality.HighQuality);

return (
<>
<div className="cross_world_markets">
Expand All @@ -94,8 +91,8 @@ export default function MarketDataCenter({ item, dc, market, lang, open }: Marke
</h6>
<ListingsTable
listings={hqListings}
averageHq={hqListingsAveragePpu}
averageNq={nqListingsAveragePpu}
averageHq={hqReferencePrice}
averageNq={nqReferencePrice}
crossWorld={true}
includeDiff={true}
lang={lang}
Expand All @@ -108,8 +105,8 @@ export default function MarketDataCenter({ item, dc, market, lang, open }: Marke
<h6>{sprintf(t`%s Prices`, 'NQ')}</h6>
<ListingsTable
listings={nqListings}
averageHq={hqListingsAveragePpu}
averageNq={nqListingsAveragePpu}
averageHq={hqReferencePrice}
averageNq={nqReferencePrice}
crossWorld={true}
includeDiff={true}
lang={lang}
Expand All @@ -126,8 +123,8 @@ export default function MarketDataCenter({ item, dc, market, lang, open }: Marke
</h6>
<SalesTable
sales={hqSales}
averageHq={hqSalesAveragePpu}
averageNq={nqSalesAveragePpu}
averageHq={hqReferencePrice}
averageNq={nqReferencePrice}
crossWorld={true}
includeDiff={true}
start={0}
Expand All @@ -139,8 +136,8 @@ export default function MarketDataCenter({ item, dc, market, lang, open }: Marke
<h6>{sprintf(t`%s Purchase History`, 'NQ')}</h6>
<SalesTable
sales={nqSales}
averageHq={hqSalesAveragePpu}
averageNq={nqSalesAveragePpu}
averageHq={hqReferencePrice}
averageNq={nqReferencePrice}
crossWorld={true}
includeDiff={true}
start={0}
Expand Down
65 changes: 30 additions & 35 deletions components/Market/MarketRegion/MarketRegion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import MarketCheapest from '../MarketCheapest/MarketCheapest';
import MarketHistoryGraph from '../MarketHistoryGraph/MarketHistoryGraph';
import MarketStackSizeHistogram from '../MarketStackSizeHistogram/MarketStackSizeHistogram';
import { useDataCenterMarkets } from '../../../hooks/market';
import ErrorBoundary from '../../ErrorBoundary/ErrorBoundary';
import { Suspense } from 'react';
import MarketWorld from '../MarketWorld/MarketWorld';
import { MarketV2 } from '../../../types/universalis/MarketV2';
import { calculateReferencePrice, Quality } from '../utils';

interface MarketRegionProps {
item: Item;
region: string;
dcs: DataCenter[];
dcMarkets: Record<string, any>;
dcMarkets: Record<string, MarketV2>;
lang: Language;
open: boolean;
}
Expand Down Expand Up @@ -47,56 +47,51 @@ export default function MarketRegion({
.flat()
.sort((a, b) => b.timestamp - a.timestamp);

const hqListings = allListings?.filter((listing: any) => listing.hq) ?? [];
const nqListings = allListings?.filter((listing: any) => !listing.hq) ?? [];
const hqSales = allSales?.filter((sale: any) => sale.hq) ?? [];
const nqSales = allSales?.filter((sale: any) => !sale.hq) ?? [];
const hqListings = allListings?.filter((listing) => listing.hq) ?? [];
const nqListings = allListings?.filter((listing) => !listing.hq) ?? [];
const hqSales = allSales?.filter((sale) => sale.hq) ?? [];
const nqSales = allSales?.filter((sale) => !sale.hq) ?? [];

const hqListingsAveragePpu =
Math.ceil(
hqListings
.map((listing: any) => listing.pricePerUnit)
.reduce((agg: any, next: any) => agg + next, 0) / hqListings.length
hqListings.map((listing) => listing.pricePerUnit).reduce((agg, next) => agg + next, 0) /
hqListings.length
) || 0;
const nqListingsAveragePpu =
Math.ceil(
nqListings
.map((listing: any) => listing.pricePerUnit)
.reduce((agg: any, next: any) => agg + next, 0) / nqListings.length
nqListings.map((listing) => listing.pricePerUnit).reduce((agg, next) => agg + next, 0) /
nqListings.length
) || 0;
const hqListingsAverageTotal =
Math.ceil(
hqListings
.map((listing: any) => listing.total)
.reduce((agg: any, next: any) => agg + next, 0) / hqListings.length
hqListings.map((listing) => listing.total).reduce((agg, next) => agg + next, 0) /
hqListings.length
) || 0;
const nqListingsAverageTotal =
Math.ceil(
nqListings
.map((listing: any) => listing.total)
.reduce((agg: any, next: any) => agg + next, 0) / nqListings.length
nqListings.map((listing) => listing.total).reduce((agg, next) => agg + next, 0) /
nqListings.length
) || 0;
const hqSalesAveragePpu =
Math.ceil(
hqSales.map((sale: any) => sale.pricePerUnit).reduce((agg: any, next: any) => agg + next, 0) /
hqSales.length
hqSales.map((sale) => sale.pricePerUnit).reduce((agg, next) => agg + next, 0) / hqSales.length
) || 0;
const nqSalesAveragePpu =
Math.ceil(
nqSales.map((sale: any) => sale.pricePerUnit).reduce((agg: any, next: any) => agg + next, 0) /
nqSales.length
nqSales.map((sale) => sale.pricePerUnit).reduce((agg, next) => agg + next, 0) / nqSales.length
) || 0;
const hqSalesAverageTotal =
Math.ceil(
hqSales.map((sale: any) => sale.total).reduce((agg: any, next: any) => agg + next, 0) /
hqSales.length
hqSales.map((sale) => sale.total).reduce((agg, next) => agg + next, 0) / hqSales.length
) || 0;
const nqSalesAverageTotal =
Math.ceil(
nqSales.map((sale: any) => sale.total).reduce((agg: any, next: any) => agg + next, 0) /
nqSales.length
nqSales.map((sale) => sale.total).reduce((agg, next) => agg + next, 0) / nqSales.length
) || 0;

const nqReferencePrice = calculateReferencePrice(dcMarkets, Quality.NormalQuality);
const hqReferencePrice = calculateReferencePrice(dcMarkets, Quality.HighQuality);

return (
<>
<div className="cross_world_markets">
Expand All @@ -115,8 +110,8 @@ export default function MarketRegion({
</h6>
<ListingsTable
listings={hqListings}
averageHq={hqListingsAveragePpu}
averageNq={nqListingsAveragePpu}
averageHq={hqReferencePrice}
averageNq={nqReferencePrice}
crossWorld={true}
crossDc={true}
dcs={dcs}
Expand All @@ -131,8 +126,8 @@ export default function MarketRegion({
<h6>{sprintf(t`%s Prices`, 'NQ')}</h6>
<ListingsTable
listings={nqListings}
averageHq={hqListingsAveragePpu}
averageNq={nqListingsAveragePpu}
averageHq={hqReferencePrice}
averageNq={nqReferencePrice}
crossWorld={true}
crossDc={true}
dcs={dcs}
Expand All @@ -151,8 +146,8 @@ export default function MarketRegion({
</h6>
<SalesTable
sales={hqSales}
averageHq={hqSalesAveragePpu}
averageNq={nqSalesAveragePpu}
averageHq={hqReferencePrice}
averageNq={nqReferencePrice}
crossWorld={true}
crossDc={true}
dcs={dcs}
Expand All @@ -166,8 +161,8 @@ export default function MarketRegion({
<h6>{sprintf(t`%s Purchase History`, 'NQ')}</h6>
<SalesTable
sales={nqSales}
averageHq={hqSalesAveragePpu}
averageNq={nqSalesAveragePpu}
averageHq={hqReferencePrice}
averageNq={nqReferencePrice}
crossWorld={true}
crossDc={true}
dcs={dcs}
Expand Down
15 changes: 10 additions & 5 deletions components/Market/MarketWorld/MarketWorld.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import MarketStackSizeHistogram from '../MarketStackSizeHistogram/MarketStackSiz
import NoMarketData from '../NoMarketData/NoMarketData';
import { useWorldMarket } from '../../../hooks/market';
import ContentLoader from 'react-content-loader';
import { MarketV2 } from '../../../types/universalis/MarketV2';
import { calculateReferencePrice, Quality } from '../utils';

interface MarketWorldProps {
item: Item;
world: World;
market: any;
market: MarketV2;
lang: Language;
open: boolean;
}
Expand All @@ -33,6 +35,9 @@ export default function MarketWorld({ item, world, market, lang, open }: MarketW
return <NoMarketData worldName={world.name} />;
}

const nqReferencePrice = calculateReferencePrice(market, Quality.NormalQuality);
const hqReferencePrice = calculateReferencePrice(market, Quality.HighQuality);

return (
<>
<div className="tab-market-tables">
Expand All @@ -47,8 +52,8 @@ export default function MarketWorld({ item, world, market, lang, open }: MarketW
</h4>
<ListingsTable
listings={market.listings}
averageHq={market.currentAveragePriceHQ}
averageNq={market.currentAveragePriceNQ}
averageHq={hqReferencePrice}
averageNq={nqReferencePrice}
crossWorld={false}
includeDiff={true}
lang={lang}
Expand All @@ -62,8 +67,8 @@ export default function MarketWorld({ item, world, market, lang, open }: MarketW
</h4>
<SalesTable
sales={market.recentHistory}
averageHq={market.averagePriceHQ}
averageNq={market.averagePriceNQ}
averageHq={hqReferencePrice}
averageNq={nqReferencePrice}
crossWorld={false}
includeDiff={true}
start={0}
Expand Down
Loading

0 comments on commit 09594bb

Please sign in to comment.