Fix detail pricing labels and price semantics tests
This commit is contained in:
@@ -142,6 +142,34 @@ function getSideRow(
|
||||
return null;
|
||||
}
|
||||
|
||||
function getDetailSideAsk(
|
||||
scanRow: ScanOpportunityRow | null,
|
||||
marketScan: MarketScan | null | undefined,
|
||||
side: "yes" | "no",
|
||||
) {
|
||||
if (scanRow?.ask != null) return scanRow.ask;
|
||||
if (side === "yes") {
|
||||
if (scanRow?.yes_ask != null) return scanRow.yes_ask;
|
||||
return marketScan?.yes_buy ?? null;
|
||||
}
|
||||
if (scanRow?.no_ask != null) return scanRow.no_ask;
|
||||
return marketScan?.no_buy ?? null;
|
||||
}
|
||||
|
||||
function getDetailSideBid(
|
||||
scanRow: ScanOpportunityRow | null,
|
||||
marketScan: MarketScan | null | undefined,
|
||||
side: "yes" | "no",
|
||||
) {
|
||||
if (scanRow?.bid != null) return scanRow.bid;
|
||||
if (side === "yes") {
|
||||
if (scanRow?.yes_bid != null) return scanRow.yes_bid;
|
||||
return marketScan?.yes_sell ?? null;
|
||||
}
|
||||
if (scanRow?.no_bid != null) return scanRow.no_bid;
|
||||
return marketScan?.no_sell ?? null;
|
||||
}
|
||||
|
||||
function buildComparisonBuckets(
|
||||
marketScan: MarketScan | null | undefined,
|
||||
row: ScanOpportunityRow | null,
|
||||
@@ -396,24 +424,30 @@ function DetailPanel({
|
||||
{isEn ? "Buy Yes" : "买入 Yes"} {displayRow.target_label || ""}
|
||||
</div>
|
||||
<p>
|
||||
{formatPrice(yesRow?.ask ?? marketScan?.yes_buy)} →{" "}
|
||||
{formatPrice(getDetailSideAsk(yesRow, marketScan, "yes"))} →{" "}
|
||||
{formatProbability(yesRow?.model_probability)}
|
||||
</p>
|
||||
<p className="positive">{formatPercent(yesRow?.edge_percent, true)} {isEn ? "edge" : "边际优势"}</p>
|
||||
<p>{isEn ? "Spread" : "点差"} {formatPrice(yesRow?.spread)}</p>
|
||||
<p>
|
||||
{isEn ? "Bid / Ask" : "买卖价"} {formatPrice(getDetailSideBid(yesRow, marketScan, "yes"))} /{" "}
|
||||
{formatPrice(getDetailSideAsk(yesRow, marketScan, "yes"))}
|
||||
</p>
|
||||
</div>
|
||||
<div className="scan-trade-card sell">
|
||||
<div className="scan-trade-card-title">
|
||||
{isEn ? "Buy No" : "买入 No"} {displayRow.target_label || ""}
|
||||
</div>
|
||||
<p>
|
||||
{formatPrice(noRow?.ask ?? marketScan?.no_buy)} →{" "}
|
||||
{formatPrice(getDetailSideAsk(noRow, marketScan, "no"))} →{" "}
|
||||
{formatProbability(noRow?.model_probability)}
|
||||
</p>
|
||||
<p className={Number(noRow?.edge_percent || 0) >= 0 ? "positive" : "negative"}>
|
||||
{formatPercent(noRow?.edge_percent, true)} {isEn ? "edge" : "边际优势"}
|
||||
</p>
|
||||
<p>{isEn ? "Spread" : "点差"} {formatPrice(noRow?.spread)}</p>
|
||||
<p>
|
||||
{isEn ? "Bid / Ask" : "买卖价"} {formatPrice(getDetailSideBid(noRow, marketScan, "no"))} /{" "}
|
||||
{formatPrice(getDetailSideAsk(noRow, marketScan, "no"))}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 225 KiB |
@@ -40,8 +40,8 @@ def test_extract_market_bucket_range_supports_fahrenheit_ranges():
|
||||
def test_fetch_token_market_data_uses_rest_orderbook_executable_prices():
|
||||
layer = PolymarketReadOnlyLayer()
|
||||
payloads = {
|
||||
("/price", "BUY"): {"price": "0.11"},
|
||||
("/price", "SELL"): {"price": "0.88"},
|
||||
("/price", "BUY"): {"price": "0.27"},
|
||||
("/price", "SELL"): {"price": "0.23"},
|
||||
("/midpoint", None): {"midpoint": "0.50"},
|
||||
("/last-trade-price", None): {"price": "0.49"},
|
||||
("/book", None): {
|
||||
@@ -68,6 +68,30 @@ def test_fetch_token_market_data_uses_rest_orderbook_executable_prices():
|
||||
assert data["quote_source"] == "polymarket_clob_rest"
|
||||
|
||||
|
||||
def test_fetch_token_market_data_keeps_buy_sell_semantics_without_orderbook():
|
||||
layer = PolymarketReadOnlyLayer()
|
||||
payloads = {
|
||||
("/price", "BUY"): {"price": "0.23"},
|
||||
("/price", "SELL"): {"price": "0.27"},
|
||||
("/midpoint", None): {"midpoint": "0.25"},
|
||||
("/last-trade-price", None): {"price": "0.24"},
|
||||
("/book", None): None,
|
||||
}
|
||||
|
||||
def _fake_clob_get(path, params):
|
||||
if path == "/price":
|
||||
return payloads[(path, params.get("side"))]
|
||||
return payloads[(path, None)]
|
||||
|
||||
layer._clob_get = _fake_clob_get
|
||||
|
||||
data = layer._fetch_token_market_data("token-1")
|
||||
|
||||
assert data["buy"] == 0.27
|
||||
assert data["sell"] == 0.23
|
||||
assert data["midpoint"] == 0.25
|
||||
|
||||
|
||||
def test_get_token_market_data_uses_price_cache_within_ttl():
|
||||
layer = PolymarketReadOnlyLayer()
|
||||
calls = []
|
||||
|
||||
Reference in New Issue
Block a user