Format trade prices to 3 decimals and round on ingest.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-21 10:30:21 +08:00
parent c436b76e64
commit a6062fbacc
4 changed files with 49 additions and 11 deletions
+24
View File
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import annotations from __future__ import annotations
from typing import Any
from flask import Flask from flask import Flask
from app.config import Config from app.config import Config
@@ -8,11 +10,33 @@ from app.db import init_db, seed_if_empty
from app.routes import register_routes from app.routes import register_routes
def _fmt_price(value: Any, digits: int = 3) -> str:
"""价格展示:固定小数位,避免浮点尾巴。"""
if value is None or value == "":
return "—"
try:
return f"{float(value):.{int(digits)}f}"
except (TypeError, ValueError):
return str(value)
def _fmt_money(value: Any, digits: int = 2) -> str:
if value is None or value == "":
return "—"
try:
return f"{float(value):.{int(digits)}f}"
except (TypeError, ValueError):
return str(value)
def create_app() -> Flask: def create_app() -> Flask:
app = Flask(__name__, template_folder="templates", static_folder="static") app = Flask(__name__, template_folder="templates", static_folder="static")
app.config.from_object(Config) app.config.from_object(Config)
app.secret_key = Config.SECRET_KEY app.secret_key = Config.SECRET_KEY
app.jinja_env.filters["fmt_price"] = _fmt_price
app.jinja_env.filters["fmt_money"] = _fmt_money
init_db() init_db()
seed_if_empty() seed_if_empty()
register_routes(app) register_routes(app)
+18 -4
View File
@@ -662,10 +662,10 @@ def register_routes(app: Flask) -> None:
ticket = str(data.get("ticket") or "").strip() ticket = str(data.get("ticket") or "").strip()
symbol = (data.get("symbol") or "XAUUSD").upper() symbol = (data.get("symbol") or "XAUUSD").upper()
side = (data.get("side") or "").lower() side = (data.get("side") or "").lower()
volume = float(data.get("volume") or 0) volume = round(float(data.get("volume") or 0), 4)
open_price = float(data.get("open_price") or 0) open_price = round(float(data.get("open_price") or 0), 3)
close_price = ( close_price = (
float(data.get("close_price") or 0) round(float(data.get("close_price") or 0), 3)
if data.get("close_price") is not None if data.get("close_price") is not None
else None else None
) )
@@ -674,9 +674,23 @@ def register_routes(app: Flask) -> None:
if data.get("profit") is None: if data.get("profit") is None:
profit = None profit = None
else: else:
profit = float(data.get("profit") or 0) profit = round(float(data.get("profit") or 0), 2)
sl = data.get("sl") sl = data.get("sl")
tp = data.get("tp") tp = data.get("tp")
if sl is not None and sl != "":
try:
sl = round(float(sl), 3)
except (TypeError, ValueError):
sl = None
else:
sl = None
if tp is not None and tp != "":
try:
tp = round(float(tp), 3)
except (TypeError, ValueError):
tp = None
else:
tp = None
entry_style = (data.get("entry_style") or "").strip() entry_style = (data.get("entry_style") or "").strip()
review_note = (data.get("review_note") or "").strip() review_note = (data.get("review_note") or "").strip()
snap_json = json.dumps(snapshot, ensure_ascii=False) snap_json = json.dumps(snapshot, ensure_ascii=False)
+4 -4
View File
@@ -11,13 +11,13 @@
<tr><th>账户</th><td>{{ trade.account_name or '—' }}</td></tr> <tr><th>账户</th><td>{{ trade.account_name or '—' }}</td></tr>
<tr><th>机器</th><td>{{ trade.machine_name or '—' }}</td></tr> <tr><th>机器</th><td>{{ trade.machine_name or '—' }}</td></tr>
<tr><th>手数</th><td>{{ trade.volume }}</td></tr> <tr><th>手数</th><td>{{ trade.volume }}</td></tr>
<tr><th>开仓价</th><td>{{ trade.open_price }}</td></tr> <tr><th>开仓价</th><td>{{ trade.open_price|fmt_price }}</td></tr>
<tr><th>平仓价</th><td>{{ trade.close_price if trade.close_price is not none else '—' }}</td></tr> <tr><th>平仓价</th><td>{{ trade.close_price|fmt_price }}</td></tr>
<tr><th>开仓时间</th><td>{{ trade.open_time_fmt }} <span class="muted">北京时间</span></td></tr> <tr><th>开仓时间</th><td>{{ trade.open_time_fmt }} <span class="muted">北京时间</span></td></tr>
<tr><th>平仓时间</th><td>{{ trade.close_time_fmt }} <span class="muted">北京时间</span></td></tr> <tr><th>平仓时间</th><td>{{ trade.close_time_fmt }} <span class="muted">北京时间</span></td></tr>
<tr><th>持仓时间</th><td style="font-weight:700;color:var(--accent)">{{ trade.hold_duration }}</td></tr> <tr><th>持仓时间</th><td style="font-weight:700;color:var(--accent)">{{ trade.hold_duration }}</td></tr>
<tr><th>盈亏</th><td>{{ trade.profit }}</td></tr> <tr><th>盈亏</th><td>{{ trade.profit|fmt_money }}</td></tr>
<tr><th>SL / TP</th><td>{{ trade.sl }} / {{ trade.tp }}</td></tr> <tr><th>SL / TP</th><td>{{ trade.sl|fmt_price }} / {{ trade.tp|fmt_price }}</td></tr>
<tr><th>单号</th><td>{{ trade.ticket or '—' }}</td></tr> <tr><th>单号</th><td>{{ trade.ticket or '—' }}</td></tr>
</table> </table>
</div> </div>
+3 -3
View File
@@ -56,10 +56,10 @@
<td>{{ t.symbol }}</td> <td>{{ t.symbol }}</td>
<td><span class="tag {% if t.side=='buy' %}green{% else %}red{% endif %}">{{ t.side }}</span></td> <td><span class="tag {% if t.side=='buy' %}green{% else %}red{% endif %}">{{ t.side }}</span></td>
<td>{{ t.volume }}</td> <td>{{ t.volume }}</td>
<td>{{ t.open_price }}</td> <td>{{ t.open_price|fmt_price }}</td>
<td>{{ t.close_price if t.close_price is not none else '—' }}</td> <td>{{ t.close_price|fmt_price }}</td>
<td style="color:{% if t.profit and t.profit>0 %}var(--green){% elif t.profit and t.profit<0 %}var(--red){% else %}inherit{% endif %}"> <td style="color:{% if t.profit and t.profit>0 %}var(--green){% elif t.profit and t.profit<0 %}var(--red){% else %}inherit{% endif %}">
{{ t.profit if t.profit is not none else '—' }} {{ t.profit|fmt_money }}
</td> </td>
<td class="muted" style="white-space:nowrap">{{ t.open_time_fmt }}</td> <td class="muted" style="white-space:nowrap">{{ t.open_time_fmt }}</td>
<td class="muted" style="white-space:nowrap">{{ t.close_time_fmt }}</td> <td class="muted" style="white-space:nowrap">{{ t.close_time_fmt }}</td>