Add professional intraday meteorology analysis
This commit is contained in:
@@ -2921,6 +2921,97 @@
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-sync-strip-compact) {
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-sync-strip-compact .future-v2-sync-chip) {
|
||||
padding: 8px 10px;
|
||||
border-radius: 8px;
|
||||
background: rgba(15, 23, 42, 0.62);
|
||||
}
|
||||
|
||||
.root :global(.future-v2-sync-strip-compact .future-v2-sync-copy span) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-brief) {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(320px, 0.56fr);
|
||||
gap: 14px;
|
||||
padding: 16px;
|
||||
border: 1px solid rgba(34, 211, 238, 0.22);
|
||||
border-radius: 8px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(8, 47, 73, 0.42), rgba(15, 23, 42, 0.78));
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-copy) {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-copy h3) {
|
||||
margin: 0;
|
||||
color: #f8fafc;
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
line-height: 1.35;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-meta) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-meta span) {
|
||||
min-height: 26px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 5px 8px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
border-radius: 8px;
|
||||
background: rgba(15, 23, 42, 0.62);
|
||||
color: #cbd5e1;
|
||||
font-size: 12px;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-paths) {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-paths div) {
|
||||
min-width: 0;
|
||||
padding: 12px;
|
||||
border: 1px solid rgba(34, 211, 238, 0.18);
|
||||
border-radius: 8px;
|
||||
background: rgba(2, 6, 23, 0.5);
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-paths span) {
|
||||
display: block;
|
||||
color: var(--text-muted);
|
||||
font-size: 11px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-paths strong) {
|
||||
display: block;
|
||||
margin-top: 8px;
|
||||
color: #67e8f9;
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-sync-chip) {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
@@ -3688,6 +3779,124 @@
|
||||
min-height: 340px;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-chart-thresholds) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-chart-thresholds span) {
|
||||
min-height: 26px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 5px 8px;
|
||||
border: 1px solid rgba(34, 211, 238, 0.16);
|
||||
border-radius: 8px;
|
||||
background: rgba(8, 47, 73, 0.24);
|
||||
color: #cbd5e1;
|
||||
font-size: 12px;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-grid) {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.9fr) minmax(0, 0.9fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-evidence-list) {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-evidence-row) {
|
||||
padding: 10px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.14);
|
||||
border-left-width: 3px;
|
||||
border-radius: 8px;
|
||||
background: rgba(15, 23, 42, 0.5);
|
||||
}
|
||||
|
||||
.root :global(.future-v2-evidence-row.cyan) {
|
||||
border-left-color: #22d3ee;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-evidence-row.amber) {
|
||||
border-left-color: #f59e0b;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-evidence-row.blue) {
|
||||
border-left-color: #60a5fa;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-evidence-head) {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-evidence-head strong) {
|
||||
color: #f8fafc;
|
||||
font-size: 13px;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-evidence-head span) {
|
||||
color: var(--text-muted);
|
||||
font-size: 11px;
|
||||
line-height: 1.35;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-evidence-row p) {
|
||||
margin: 7px 0 0;
|
||||
color: var(--text-secondary);
|
||||
font-size: 12px;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-rule-list) {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-rule-list li) {
|
||||
position: relative;
|
||||
padding-left: 16px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 12px;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-rule-list li::before) {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0.65em;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 999px;
|
||||
background: #22d3ee;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-rule-panel:nth-child(2) .future-v2-rule-list li::before) {
|
||||
background: #f59e0b;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-model-note) {
|
||||
margin-top: 12px;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid rgba(148, 163, 184, 0.14);
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.root :global(.future-modal-section) {
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
border: 1px solid var(--border-subtle);
|
||||
@@ -3909,6 +4118,15 @@
|
||||
}
|
||||
|
||||
@media (max-width: 960px) {
|
||||
.root :global(.future-v2-meteorology-brief),
|
||||
.root :global(.future-v2-meteorology-grid) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-paths) {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.root :global(.future-v2-layout) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
@@ -3934,6 +4152,18 @@
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-brief) {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-paths) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-meteorology-copy h3) {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.root :global(.future-v2-card),
|
||||
.root :global(.future-modal-section) {
|
||||
border-radius: 12px;
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
getTemperatureChartData,
|
||||
getWeatherSummary,
|
||||
} from "@/lib/dashboard-utils";
|
||||
import type { IntradayMeteorologySignal } from "@/lib/dashboard-types";
|
||||
|
||||
function normalizeMarketValue(value?: number | null) {
|
||||
if (value == null) return null;
|
||||
@@ -175,6 +176,35 @@ function parsePercentFromText(value?: string | number | null) {
|
||||
return parseLeadingNumber(text);
|
||||
}
|
||||
|
||||
function formatConfidenceLabel(value?: string | null, locale = "zh-CN") {
|
||||
const normalized = String(value || "").trim().toLowerCase();
|
||||
if (normalized === "high") return locale === "en-US" ? "High" : "高";
|
||||
if (normalized === "medium") return locale === "en-US" ? "Medium" : "中";
|
||||
if (normalized === "low") return locale === "en-US" ? "Low" : "低";
|
||||
return locale === "en-US" ? "Pending" : "待确认";
|
||||
}
|
||||
|
||||
function formatSignalDirection(value?: string | null, locale = "zh-CN") {
|
||||
const normalized = String(value || "").trim().toLowerCase();
|
||||
if (normalized === "support") return locale === "en-US" ? "Support" : "支持升温";
|
||||
if (normalized === "suppress") return locale === "en-US" ? "Suppress" : "压制峰值";
|
||||
return locale === "en-US" ? "Neutral" : "中性";
|
||||
}
|
||||
|
||||
function formatSignalStrength(value?: string | null, locale = "zh-CN") {
|
||||
const normalized = String(value || "").trim().toLowerCase();
|
||||
if (normalized === "strong") return locale === "en-US" ? "Strong" : "强";
|
||||
if (normalized === "medium") return locale === "en-US" ? "Medium" : "中";
|
||||
return locale === "en-US" ? "Weak" : "弱";
|
||||
}
|
||||
|
||||
function signalTone(signal?: IntradayMeteorologySignal | null) {
|
||||
const direction = String(signal?.direction || "").trim().toLowerCase();
|
||||
if (direction === "support") return "cyan";
|
||||
if (direction === "suppress") return "amber";
|
||||
return "blue";
|
||||
}
|
||||
|
||||
function getTrendMetricVisual(metric: {
|
||||
label?: string;
|
||||
value?: string;
|
||||
@@ -1081,6 +1111,58 @@ export function FutureForecastModal() {
|
||||
}
|
||||
return lines.slice(0, 3);
|
||||
}, [boundaryRiskView, isToday, locale, localizedAiCommentaryLines, networkLeadView, paceView, showDeferredTodaySections]);
|
||||
const intradayMeteorology = detail.intraday_meteorology || {};
|
||||
const meteorologySignals = Array.isArray(intradayMeteorology.signal_contributions)
|
||||
? intradayMeteorology.signal_contributions
|
||||
: [];
|
||||
const invalidationRules = Array.isArray(intradayMeteorology.invalidation_rules)
|
||||
? intradayMeteorology.invalidation_rules
|
||||
: [];
|
||||
const confirmationRules = Array.isArray(intradayMeteorology.confirmation_rules)
|
||||
? intradayMeteorology.confirmation_rules
|
||||
: [];
|
||||
const meteorologyHeadline =
|
||||
String(intradayMeteorology.headline || "").trim() ||
|
||||
todayTradeSummaryLines[0] ||
|
||||
(locale === "en-US"
|
||||
? "Intraday meteorology layers are still syncing; use the next observation as the anchor."
|
||||
: "关键日内气象层仍在同步,先以下一次观测作为判断锚点。");
|
||||
const baseCaseBucket =
|
||||
String(intradayMeteorology.base_case_bucket || "").trim() ||
|
||||
formatBucketLabel(topProbabilityBucket);
|
||||
const nextObservationTime =
|
||||
String(intradayMeteorology.next_observation_time || "").trim() || "--";
|
||||
const baseBucketNumber = parseLeadingNumber(baseCaseBucket);
|
||||
const referenceObservedTemp =
|
||||
topObservedTemp != null && Number.isFinite(Number(topObservedTemp))
|
||||
? Number(topObservedTemp)
|
||||
: detail.current?.temp != null
|
||||
? Number(detail.current.temp)
|
||||
: null;
|
||||
const gapToBaseBucket =
|
||||
baseBucketNumber != null && referenceObservedTemp != null
|
||||
? Math.max(0, baseBucketNumber - referenceObservedTemp)
|
||||
: null;
|
||||
const pathStatus =
|
||||
gapToBaseBucket == null
|
||||
? locale === "en-US"
|
||||
? "Awaiting anchor"
|
||||
: "等待锚点"
|
||||
: gapToBaseBucket <= 0.05
|
||||
? locale === "en-US"
|
||||
? "Base path touched"
|
||||
: "基准路径已触达"
|
||||
: gapToBaseBucket <= 1.0
|
||||
? locale === "en-US"
|
||||
? "Base path open"
|
||||
: "基准路径开放"
|
||||
: locale === "en-US"
|
||||
? "Needs peak push"
|
||||
: "需要峰值推动";
|
||||
const peakWindowText =
|
||||
String(intradayMeteorology.peak_window || "").trim() ||
|
||||
paceView?.peakWindowText ||
|
||||
"--";
|
||||
const syncStatusItems = [
|
||||
{
|
||||
key: "base",
|
||||
@@ -1215,7 +1297,49 @@ export function FutureForecastModal() {
|
||||
</button>
|
||||
</div>
|
||||
<div className="modal-body future-modal-body">
|
||||
<section className="future-v2-sync-strip" aria-live="polite">
|
||||
{isToday && (
|
||||
<section className="future-v2-meteorology-brief">
|
||||
<div className="future-v2-meteorology-copy">
|
||||
<div className="modal-section-kicker">
|
||||
{locale === "en-US" ? "Professional meteorology read" : "专业气象判断"}
|
||||
</div>
|
||||
<h3>{meteorologyHeadline}</h3>
|
||||
<div className="future-v2-meteorology-meta">
|
||||
<span>
|
||||
{locale === "en-US" ? "Confidence" : "置信度"} ·{" "}
|
||||
{formatConfidenceLabel(intradayMeteorology.confidence, locale)}
|
||||
</span>
|
||||
<span>
|
||||
{locale === "en-US" ? "Peak window" : "峰值窗口"} · {peakWindowText}
|
||||
</span>
|
||||
<span>
|
||||
{locale === "en-US" ? "Next observation" : "下一观测"} · {nextObservationTime}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="future-v2-meteorology-paths">
|
||||
<div>
|
||||
<span>{locale === "en-US" ? "Base case" : "基准路径"}</span>
|
||||
<strong>{baseCaseBucket || "--"}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>{locale === "en-US" ? "Upside" : "上修路径"}</span>
|
||||
<strong>{intradayMeteorology.upside_bucket || "--"}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>{locale === "en-US" ? "Downside" : "下修路径"}</span>
|
||||
<strong>{intradayMeteorology.downside_bucket || "--"}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
<section
|
||||
className={clsx(
|
||||
"future-v2-sync-strip",
|
||||
isToday && "future-v2-sync-strip-compact",
|
||||
)}
|
||||
aria-live="polite"
|
||||
>
|
||||
{syncStatusItems.map((item) => (
|
||||
<div
|
||||
key={item.key}
|
||||
@@ -1314,6 +1438,22 @@ export function FutureForecastModal() {
|
||||
</span>
|
||||
<strong>{detail.current?.obs_time || "--"}</strong>
|
||||
</div>
|
||||
<div className="future-v2-mini-item">
|
||||
<span>
|
||||
{locale === "en-US" ? "Gap to base" : "距基准档"}
|
||||
</span>
|
||||
<strong>
|
||||
{gapToBaseBucket != null
|
||||
? `${gapToBaseBucket.toFixed(1)}${detail.temp_symbol}`
|
||||
: "--"}
|
||||
</strong>
|
||||
</div>
|
||||
<div className="future-v2-mini-item">
|
||||
<span>
|
||||
{locale === "en-US" ? "Path state" : "路径状态"}
|
||||
</span>
|
||||
<strong>{pathStatus}</strong>
|
||||
</div>
|
||||
<div className="future-v2-mini-item">
|
||||
<span>
|
||||
{locale === "en-US" ? "Sunrise" : "日出时间"}
|
||||
@@ -1484,16 +1624,103 @@ export function FutureForecastModal() {
|
||||
</h3>
|
||||
</div>
|
||||
<DailyTemperatureChart dateStr={dateStr} />
|
||||
<div className="future-v2-chart-thresholds">
|
||||
<span>{locale === "en-US" ? "Base" : "基准"} · {baseCaseBucket || "--"}</span>
|
||||
<span>{locale === "en-US" ? "Upside" : "上修"} · {intradayMeteorology.upside_bucket || "--"}</span>
|
||||
<span>{locale === "en-US" ? "Invalidates at" : "失效观察"} · {nextObservationTime}</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="future-v2-meteorology-grid">
|
||||
<section className="future-modal-section future-v2-evidence-panel">
|
||||
<div className="modal-section-heading">
|
||||
<div className="modal-section-kicker">
|
||||
{locale === "en-US" ? "Evidence chain" : "气象证据链"}
|
||||
</div>
|
||||
<h3>{locale === "en-US" ? "Signal Contributions" : "信号贡献"}</h3>
|
||||
</div>
|
||||
<div className="future-v2-evidence-list">
|
||||
{meteorologySignals.length > 0 ? (
|
||||
meteorologySignals.map((signal, index) => (
|
||||
<div
|
||||
key={`${signal.label || "signal"}-${index}`}
|
||||
className={clsx(
|
||||
"future-v2-evidence-row",
|
||||
signalTone(signal),
|
||||
)}
|
||||
>
|
||||
<div className="future-v2-evidence-head">
|
||||
<strong>{signal.label || "--"}</strong>
|
||||
<span>
|
||||
{formatSignalDirection(signal.direction, locale)} ·{" "}
|
||||
{formatSignalStrength(signal.strength, locale)}
|
||||
</span>
|
||||
</div>
|
||||
<p>{signal.summary || "--"}</p>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className="future-text-block">
|
||||
{locale === "en-US"
|
||||
? "Meteorology signals are still loading."
|
||||
: "气象信号仍在加载。"}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="future-modal-section future-v2-rule-panel">
|
||||
<div className="modal-section-heading">
|
||||
<div className="modal-section-kicker">
|
||||
{locale === "en-US" ? "Failure modes" : "失效条件"}
|
||||
</div>
|
||||
<h3>{locale === "en-US" ? "What Downgrades the Read" : "什么会让判断降级"}</h3>
|
||||
</div>
|
||||
<ul className="future-v2-rule-list">
|
||||
{(invalidationRules.length > 0
|
||||
? invalidationRules
|
||||
: [
|
||||
locale === "en-US"
|
||||
? "If observations stop tracking the expected curve, wait for the next refresh."
|
||||
: "若实测不再贴近预期曲线,等待下一次刷新确认。",
|
||||
]
|
||||
).map((rule, index) => (
|
||||
<li key={`${rule}-${index}`}>{rule}</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section className="future-modal-section future-v2-rule-panel">
|
||||
<div className="modal-section-heading">
|
||||
<div className="modal-section-kicker">
|
||||
{locale === "en-US" ? "Confirmation" : "确认条件"}
|
||||
</div>
|
||||
<h3>{locale === "en-US" ? "What Confirms the Path" : "什么会确认主路径"}</h3>
|
||||
</div>
|
||||
<ul className="future-v2-rule-list">
|
||||
{(confirmationRules.length > 0
|
||||
? confirmationRules
|
||||
: [
|
||||
locale === "en-US"
|
||||
? "Keep watching the next settlement-source observation."
|
||||
: "继续观察下一次结算源报文。",
|
||||
]
|
||||
).map((rule, index) => (
|
||||
<li key={`${rule}-${index}`}>{rule}</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="future-v2-model-note">{modelSummary}</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div className="future-modal-grid">
|
||||
<section className="future-modal-section">
|
||||
<div className="modal-section-heading">
|
||||
<div className="modal-section-kicker">
|
||||
{locale === "en-US" ? "Probability layer" : "概率层"}
|
||||
{locale === "en-US" ? "Auxiliary probability" : "辅助概率"}
|
||||
</div>
|
||||
<h3>
|
||||
{locale === "en-US" ? "Current Hit Odds" : "当前命中胜率"}
|
||||
{locale === "en-US" ? "Model & Market Reference" : "模型与市场参考"}
|
||||
</h3>
|
||||
</div>
|
||||
<div className="future-text-block" style={{ marginBottom: "12px" }}>
|
||||
@@ -1503,6 +1730,7 @@ export function FutureForecastModal() {
|
||||
<ProbabilityDistribution
|
||||
detail={detail}
|
||||
targetDate={dateStr}
|
||||
marketScan={detail.market_scan}
|
||||
hideTitle
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -485,12 +485,12 @@ export function ProbabilityDistribution({
|
||||
const buyNoText = toPriceCents(bucket.no_buy);
|
||||
const marketTag = buyYesText
|
||||
? locale === "en-US"
|
||||
? `Buy Yes: ${buyYesText}`
|
||||
: `买 Yes: ${buyYesText}`
|
||||
? `Market ref: ${buyYesText}`
|
||||
: `市场参考: ${buyYesText}`
|
||||
: buyNoText
|
||||
? locale === "en-US"
|
||||
? `Buy No: ${buyNoText}`
|
||||
: `买 No: ${buyNoText}`
|
||||
? `Market hedge: ${buyNoText}`
|
||||
: `市场反向: ${buyNoText}`
|
||||
: null;
|
||||
|
||||
return (
|
||||
@@ -530,23 +530,23 @@ export function ProbabilityDistribution({
|
||||
Math.abs(bucketTemp - marketBucketTemp) < 0.26;
|
||||
const marketTag = isMarketBucket
|
||||
? locale === "en-US"
|
||||
? `Buy Yes: ${marketYesText || "--"}`
|
||||
: `买 Yes: ${marketYesText || "--"}`
|
||||
? `Market ref: ${marketYesText || "--"}`
|
||||
: `市场参考: ${marketYesText || "--"}`
|
||||
: marketNoText
|
||||
? locale === "en-US"
|
||||
? `Buy No: ${marketNoText}`
|
||||
: `买 No: ${marketNoText}`
|
||||
? `Market hedge: ${marketNoText}`
|
||||
: `市场反向: ${marketNoText}`
|
||||
: null;
|
||||
const yesPriceText = toPriceCents(marketYesPrice);
|
||||
const noPriceText = toPriceCents(marketNoPrice);
|
||||
const marketTagFinal = isMarketBucket
|
||||
? locale === "en-US"
|
||||
? `Buy Yes: ${yesPriceText || "--"}`
|
||||
: `买 Yes: ${yesPriceText || "--"}`
|
||||
? `Market ref: ${yesPriceText || "--"}`
|
||||
: `市场参考: ${yesPriceText || "--"}`
|
||||
: noPriceText
|
||||
? locale === "en-US"
|
||||
? `Buy No: ${noPriceText}`
|
||||
: `买 No: ${noPriceText}`
|
||||
? `Market hedge: ${noPriceText}`
|
||||
: `市场反向: ${noPriceText}`
|
||||
: marketTag;
|
||||
let bucketLabel =
|
||||
bucket.label || `${bucket.value}${detail.temp_symbol}`;
|
||||
|
||||
Reference in New Issue
Block a user