refactor: 移除四所统计分析页交易日历
删除日历 UI、bootstrap 与 /api/stats/calendar 注册;保留日/周/月统计表。内照明心档案日历不受影响。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1857,7 +1857,7 @@ def _compute_period_metrics(trades):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def compute_stats_bundle(conn, trading_day, now_dt=None, *, with_calendar=False):
|
def compute_stats_bundle(conn, trading_day, now_dt=None):
|
||||||
"""日 / 周 / 月 统计:平仓按北京时间交易日(默认 8:00 切日)计入。"""
|
"""日 / 周 / 月 统计:平仓按北京时间交易日(默认 8:00 切日)计入。"""
|
||||||
now_dt = now_dt or app_now()
|
now_dt = now_dt or app_now()
|
||||||
pnls = _load_completed_trade_pnls(conn)
|
pnls = _load_completed_trade_pnls(conn)
|
||||||
@@ -1888,15 +1888,6 @@ def compute_stats_bundle(conn, trading_day, now_dt=None, *, with_calendar=False)
|
|||||||
|
|
||||||
dm, wm, mm = slice_metrics("all")
|
dm, wm, mm = slice_metrics("all")
|
||||||
|
|
||||||
initial_calendar = None
|
|
||||||
calendar_bootstrap_json = None
|
|
||||||
if with_calendar:
|
|
||||||
from trade_stats_calendar_lib import build_stats_calendar_bootstrap
|
|
||||||
|
|
||||||
initial_calendar, calendar_bootstrap_json = build_stats_calendar_bootstrap(
|
|
||||||
pnls, now_dt, _pnl_row_matches_segment, reset_hour=TRADING_DAY_RESET_HOUR
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"trading_day": trading_day,
|
"trading_day": trading_day,
|
||||||
"total_opens_all": total_opens_all,
|
"total_opens_all": total_opens_all,
|
||||||
@@ -1905,8 +1896,6 @@ def compute_stats_bundle(conn, trading_day, now_dt=None, *, with_calendar=False)
|
|||||||
"month": mm,
|
"month": mm,
|
||||||
"segments": segments,
|
"segments": segments,
|
||||||
"stats_reset_hour": TRADING_DAY_RESET_HOUR,
|
"stats_reset_hour": TRADING_DAY_RESET_HOUR,
|
||||||
"initial_calendar": initial_calendar,
|
|
||||||
"calendar_bootstrap_json": calendar_bootstrap_json,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -7044,7 +7033,7 @@ def render_main_page(page="trade", embed_mode=None):
|
|||||||
else []
|
else []
|
||||||
)
|
)
|
||||||
stats_bundle = (
|
stats_bundle = (
|
||||||
compute_stats_bundle(conn, trading_day, now, with_calendar=(page == "stats"))
|
compute_stats_bundle(conn, trading_day, now)
|
||||||
if plan.stats_bundle
|
if plan.stats_bundle
|
||||||
else minimal_stats_bundle(TRADING_DAY_RESET_HOUR)
|
else minimal_stats_bundle(TRADING_DAY_RESET_HOUR)
|
||||||
)
|
)
|
||||||
@@ -9651,20 +9640,6 @@ try:
|
|||||||
except Exception as _hub_err:
|
except Exception as _hub_err:
|
||||||
print(f"[hub_bridge] binance: {_hub_err}")
|
print(f"[hub_bridge] binance: {_hub_err}")
|
||||||
|
|
||||||
try:
|
|
||||||
from hub_bridge import register_trade_stats_calendar_route
|
|
||||||
|
|
||||||
register_trade_stats_calendar_route(
|
|
||||||
app,
|
|
||||||
login_required_fn=login_required,
|
|
||||||
load_pnls_fn=_load_completed_trade_pnls,
|
|
||||||
row_matches_segment_fn=_pnl_row_matches_segment,
|
|
||||||
reset_hour=TRADING_DAY_RESET_HOUR,
|
|
||||||
get_db_fn=get_db,
|
|
||||||
)
|
|
||||||
except Exception as _cal_err:
|
|
||||||
print(f"[stats calendar] binance: {_cal_err}")
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/strategy")
|
@app.route("/strategy")
|
||||||
@login_required
|
@login_required
|
||||||
|
|||||||
@@ -244,7 +244,6 @@
|
|||||||
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
|
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="/static/instance_theme.css?v=48">
|
<link rel="stylesheet" href="/static/instance_theme.css?v=48">
|
||||||
<link rel="stylesheet" href="/static/trade_stats_calendar.css?v=4">
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
@@ -807,17 +806,6 @@
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{% if stats_bundle.calendar_bootstrap_json %}
|
|
||||||
<script type="application/json" id="stats-calendar-bootstrap">{{ stats_bundle.calendar_bootstrap_json | safe }}</script>
|
|
||||||
{% endif %}
|
|
||||||
<div id="stats-calendar-wrap" class="trade-cal-wrap stats-calendar-wrap">
|
|
||||||
<div class="trade-cal-head">
|
|
||||||
<button type="button" id="stats-cal-prev" class="btn" title="上一月">‹</button>
|
|
||||||
<span id="stats-cal-title" class="trade-cal-title"></span>
|
|
||||||
<button type="button" id="stats-cal-next" class="btn" title="下一月">›</button>
|
|
||||||
</div>
|
|
||||||
<div id="stats-calendar" class="trade-cal-grid-host" role="grid" aria-label="交易日历"></div>
|
|
||||||
</div>
|
|
||||||
{% for seg in stats_bundle.segments %}
|
{% for seg in stats_bundle.segments %}
|
||||||
<div class="stats-segment-block stats-segment-panel" data-stats-segment="{{ seg.key }}"{% if not loop.first %} style="display:none"{% endif %}>
|
<div class="stats-segment-block stats-segment-panel" data-stats-segment="{{ seg.key }}"{% if not loop.first %} style="display:none"{% endif %}>
|
||||||
{{ period_stats("日统计", seg.day) }}
|
{{ period_stats("日统计", seg.day) }}
|
||||||
@@ -854,7 +842,6 @@
|
|||||||
<script src="/static/form_submit_guard.js?v=2"></script>
|
<script src="/static/form_submit_guard.js?v=2"></script>
|
||||||
<script src="/static/manual_order_rr_preview.js?v=5"></script>
|
<script src="/static/manual_order_rr_preview.js?v=5"></script>
|
||||||
<script src="/static/strategy_roll.js?v=5"></script>
|
<script src="/static/strategy_roll.js?v=5"></script>
|
||||||
<script src="/static/trade_stats_calendar.js?v=4"></script>
|
|
||||||
<script>
|
<script>
|
||||||
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
|
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
|
||||||
const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }};
|
const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }};
|
||||||
@@ -1513,7 +1500,6 @@ function switchStatsSegment(){
|
|||||||
q.set("stats_segment", key);
|
q.set("stats_segment", key);
|
||||||
const qs = q.toString();
|
const qs = q.toString();
|
||||||
history.replaceState(null, "", qs ? (window.location.pathname + "?" + qs) : window.location.pathname);
|
history.replaceState(null, "", qs ? (window.location.pathname + "?" + qs) : window.location.pathname);
|
||||||
if(window.statsCalendarWidget) window.statsCalendarWidget.load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initStatsSegmentFromUrl(){
|
function initStatsSegmentFromUrl(){
|
||||||
@@ -1537,7 +1523,6 @@ function toggleStatsCard(){
|
|||||||
attachListWindowToExports();
|
attachListWindowToExports();
|
||||||
toggleListWindowCustom();
|
toggleListWindowCustom();
|
||||||
initStatsSegmentFromUrl();
|
initStatsSegmentFromUrl();
|
||||||
if(typeof initInstanceStatsCalendar === "function") initInstanceStatsCalendar();
|
|
||||||
if(document.getElementById("journal-list")) loadJournals();
|
if(document.getElementById("journal-list")) loadJournals();
|
||||||
if(document.getElementById("review-list")) loadReviews();
|
if(document.getElementById("review-list")) loadReviews();
|
||||||
const reviewToggle = document.getElementById("review-mode-toggle");
|
const reviewToggle = document.getElementById("review-mode-toggle");
|
||||||
|
|||||||
@@ -1846,7 +1846,7 @@ def _compute_period_metrics(trades):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def compute_stats_bundle(conn, trading_day, now_dt=None, *, with_calendar=False):
|
def compute_stats_bundle(conn, trading_day, now_dt=None):
|
||||||
"""日 / 周 / 月 统计:平仓按北京时间交易日(默认 8:00 切日)计入。"""
|
"""日 / 周 / 月 统计:平仓按北京时间交易日(默认 8:00 切日)计入。"""
|
||||||
now_dt = now_dt or app_now()
|
now_dt = now_dt or app_now()
|
||||||
pnls = _load_completed_trade_pnls(conn)
|
pnls = _load_completed_trade_pnls(conn)
|
||||||
@@ -1883,15 +1883,6 @@ def compute_stats_bundle(conn, trading_day, now_dt=None, *, with_calendar=False)
|
|||||||
|
|
||||||
dm, wm, mm = slice_metrics("all")
|
dm, wm, mm = slice_metrics("all")
|
||||||
|
|
||||||
initial_calendar = None
|
|
||||||
calendar_bootstrap_json = None
|
|
||||||
if with_calendar:
|
|
||||||
from trade_stats_calendar_lib import build_stats_calendar_bootstrap
|
|
||||||
|
|
||||||
initial_calendar, calendar_bootstrap_json = build_stats_calendar_bootstrap(
|
|
||||||
pnls, now_dt, _pnl_row_matches_segment, reset_hour=TRADING_DAY_RESET_HOUR
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"trading_day": trading_day,
|
"trading_day": trading_day,
|
||||||
"total_opens_all": total_opens_all,
|
"total_opens_all": total_opens_all,
|
||||||
@@ -1900,8 +1891,6 @@ def compute_stats_bundle(conn, trading_day, now_dt=None, *, with_calendar=False)
|
|||||||
"month": mm,
|
"month": mm,
|
||||||
"segments": segments,
|
"segments": segments,
|
||||||
"stats_reset_hour": TRADING_DAY_RESET_HOUR,
|
"stats_reset_hour": TRADING_DAY_RESET_HOUR,
|
||||||
"initial_calendar": initial_calendar,
|
|
||||||
"calendar_bootstrap_json": calendar_bootstrap_json,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6886,7 +6875,7 @@ def render_main_page(page="trade", embed_mode=None):
|
|||||||
else []
|
else []
|
||||||
)
|
)
|
||||||
stats_bundle = (
|
stats_bundle = (
|
||||||
compute_stats_bundle(conn, trading_day, now, with_calendar=(page == "stats"))
|
compute_stats_bundle(conn, trading_day, now)
|
||||||
if plan.stats_bundle
|
if plan.stats_bundle
|
||||||
else minimal_stats_bundle(TRADING_DAY_RESET_HOUR)
|
else minimal_stats_bundle(TRADING_DAY_RESET_HOUR)
|
||||||
)
|
)
|
||||||
@@ -9572,20 +9561,6 @@ try:
|
|||||||
except Exception as _hub_err:
|
except Exception as _hub_err:
|
||||||
print(f"[hub_bridge] gate: {_hub_err}")
|
print(f"[hub_bridge] gate: {_hub_err}")
|
||||||
|
|
||||||
try:
|
|
||||||
from hub_bridge import register_trade_stats_calendar_route
|
|
||||||
|
|
||||||
register_trade_stats_calendar_route(
|
|
||||||
app,
|
|
||||||
login_required_fn=login_required,
|
|
||||||
load_pnls_fn=_load_completed_trade_pnls,
|
|
||||||
row_matches_segment_fn=_pnl_row_matches_segment,
|
|
||||||
reset_hour=TRADING_DAY_RESET_HOUR,
|
|
||||||
get_db_fn=get_db,
|
|
||||||
)
|
|
||||||
except Exception as _cal_err:
|
|
||||||
print(f"[stats calendar] gate: {_cal_err}")
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/strategy")
|
@app.route("/strategy")
|
||||||
@login_required
|
@login_required
|
||||||
|
|||||||
@@ -244,7 +244,6 @@
|
|||||||
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
|
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="/static/instance_theme.css?v=48">
|
<link rel="stylesheet" href="/static/instance_theme.css?v=48">
|
||||||
<link rel="stylesheet" href="/static/trade_stats_calendar.css?v=4">
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
@@ -774,17 +773,6 @@
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{% if stats_bundle.calendar_bootstrap_json %}
|
|
||||||
<script type="application/json" id="stats-calendar-bootstrap">{{ stats_bundle.calendar_bootstrap_json | safe }}</script>
|
|
||||||
{% endif %}
|
|
||||||
<div id="stats-calendar-wrap" class="trade-cal-wrap stats-calendar-wrap">
|
|
||||||
<div class="trade-cal-head">
|
|
||||||
<button type="button" id="stats-cal-prev" class="btn" title="上一月">‹</button>
|
|
||||||
<span id="stats-cal-title" class="trade-cal-title"></span>
|
|
||||||
<button type="button" id="stats-cal-next" class="btn" title="下一月">›</button>
|
|
||||||
</div>
|
|
||||||
<div id="stats-calendar" class="trade-cal-grid-host" role="grid" aria-label="交易日历"></div>
|
|
||||||
</div>
|
|
||||||
{% for seg in stats_bundle.segments %}
|
{% for seg in stats_bundle.segments %}
|
||||||
<div class="stats-segment-block stats-segment-panel" data-stats-segment="{{ seg.key }}"{% if not loop.first %} style="display:none"{% endif %}>
|
<div class="stats-segment-block stats-segment-panel" data-stats-segment="{{ seg.key }}"{% if not loop.first %} style="display:none"{% endif %}>
|
||||||
{{ period_stats("日统计", seg.day) }}
|
{{ period_stats("日统计", seg.day) }}
|
||||||
@@ -821,7 +809,6 @@
|
|||||||
<script src="/static/form_submit_guard.js?v=2"></script>
|
<script src="/static/form_submit_guard.js?v=2"></script>
|
||||||
<script src="/static/manual_order_rr_preview.js?v=5"></script>
|
<script src="/static/manual_order_rr_preview.js?v=5"></script>
|
||||||
<script src="/static/strategy_roll.js?v=5"></script>
|
<script src="/static/strategy_roll.js?v=5"></script>
|
||||||
<script src="/static/trade_stats_calendar.js?v=4"></script>
|
|
||||||
<script>
|
<script>
|
||||||
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
|
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
|
||||||
const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }};
|
const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }};
|
||||||
@@ -1480,7 +1467,6 @@ function switchStatsSegment(){
|
|||||||
q.set("stats_segment", key);
|
q.set("stats_segment", key);
|
||||||
const qs = q.toString();
|
const qs = q.toString();
|
||||||
history.replaceState(null, "", qs ? (window.location.pathname + "?" + qs) : window.location.pathname);
|
history.replaceState(null, "", qs ? (window.location.pathname + "?" + qs) : window.location.pathname);
|
||||||
if(window.statsCalendarWidget) window.statsCalendarWidget.load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initStatsSegmentFromUrl(){
|
function initStatsSegmentFromUrl(){
|
||||||
@@ -1504,7 +1490,6 @@ function toggleStatsCard(){
|
|||||||
attachListWindowToExports();
|
attachListWindowToExports();
|
||||||
toggleListWindowCustom();
|
toggleListWindowCustom();
|
||||||
initStatsSegmentFromUrl();
|
initStatsSegmentFromUrl();
|
||||||
if(typeof initInstanceStatsCalendar === "function") initInstanceStatsCalendar();
|
|
||||||
if(document.getElementById("journal-list")) loadJournals();
|
if(document.getElementById("journal-list")) loadJournals();
|
||||||
if(document.getElementById("review-list")) loadReviews();
|
if(document.getElementById("review-list")) loadReviews();
|
||||||
const reviewToggle = document.getElementById("review-mode-toggle");
|
const reviewToggle = document.getElementById("review-mode-toggle");
|
||||||
|
|||||||
@@ -1846,7 +1846,7 @@ def _compute_period_metrics(trades):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def compute_stats_bundle(conn, trading_day, now_dt=None, *, with_calendar=False):
|
def compute_stats_bundle(conn, trading_day, now_dt=None):
|
||||||
"""日 / 周 / 月 统计:平仓按北京时间交易日(默认 8:00 切日)计入。"""
|
"""日 / 周 / 月 统计:平仓按北京时间交易日(默认 8:00 切日)计入。"""
|
||||||
now_dt = now_dt or app_now()
|
now_dt = now_dt or app_now()
|
||||||
pnls = _load_completed_trade_pnls(conn)
|
pnls = _load_completed_trade_pnls(conn)
|
||||||
@@ -1883,15 +1883,6 @@ def compute_stats_bundle(conn, trading_day, now_dt=None, *, with_calendar=False)
|
|||||||
|
|
||||||
dm, wm, mm = slice_metrics("all")
|
dm, wm, mm = slice_metrics("all")
|
||||||
|
|
||||||
initial_calendar = None
|
|
||||||
calendar_bootstrap_json = None
|
|
||||||
if with_calendar:
|
|
||||||
from trade_stats_calendar_lib import build_stats_calendar_bootstrap
|
|
||||||
|
|
||||||
initial_calendar, calendar_bootstrap_json = build_stats_calendar_bootstrap(
|
|
||||||
pnls, now_dt, _pnl_row_matches_segment, reset_hour=TRADING_DAY_RESET_HOUR
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"trading_day": trading_day,
|
"trading_day": trading_day,
|
||||||
"total_opens_all": total_opens_all,
|
"total_opens_all": total_opens_all,
|
||||||
@@ -1900,8 +1891,6 @@ def compute_stats_bundle(conn, trading_day, now_dt=None, *, with_calendar=False)
|
|||||||
"month": mm,
|
"month": mm,
|
||||||
"segments": segments,
|
"segments": segments,
|
||||||
"stats_reset_hour": TRADING_DAY_RESET_HOUR,
|
"stats_reset_hour": TRADING_DAY_RESET_HOUR,
|
||||||
"initial_calendar": initial_calendar,
|
|
||||||
"calendar_bootstrap_json": calendar_bootstrap_json,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6886,7 +6875,7 @@ def render_main_page(page="trade", embed_mode=None):
|
|||||||
else []
|
else []
|
||||||
)
|
)
|
||||||
stats_bundle = (
|
stats_bundle = (
|
||||||
compute_stats_bundle(conn, trading_day, now, with_calendar=(page == "stats"))
|
compute_stats_bundle(conn, trading_day, now)
|
||||||
if plan.stats_bundle
|
if plan.stats_bundle
|
||||||
else minimal_stats_bundle(TRADING_DAY_RESET_HOUR)
|
else minimal_stats_bundle(TRADING_DAY_RESET_HOUR)
|
||||||
)
|
)
|
||||||
@@ -9568,20 +9557,6 @@ try:
|
|||||||
except Exception as _hub_err:
|
except Exception as _hub_err:
|
||||||
print(f"[hub_bridge] gate_bot: {_hub_err}")
|
print(f"[hub_bridge] gate_bot: {_hub_err}")
|
||||||
|
|
||||||
try:
|
|
||||||
from hub_bridge import register_trade_stats_calendar_route
|
|
||||||
|
|
||||||
register_trade_stats_calendar_route(
|
|
||||||
app,
|
|
||||||
login_required_fn=login_required,
|
|
||||||
load_pnls_fn=_load_completed_trade_pnls,
|
|
||||||
row_matches_segment_fn=_pnl_row_matches_segment,
|
|
||||||
reset_hour=TRADING_DAY_RESET_HOUR,
|
|
||||||
get_db_fn=get_db,
|
|
||||||
)
|
|
||||||
except Exception as _cal_err:
|
|
||||||
print(f"[stats calendar] gate_bot: {_cal_err}")
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/strategy")
|
@app.route("/strategy")
|
||||||
@login_required
|
@login_required
|
||||||
|
|||||||
@@ -244,7 +244,6 @@
|
|||||||
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
|
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="/static/instance_theme.css?v=48">
|
<link rel="stylesheet" href="/static/instance_theme.css?v=48">
|
||||||
<link rel="stylesheet" href="/static/trade_stats_calendar.css?v=4">
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
@@ -774,17 +773,6 @@
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{% if stats_bundle.calendar_bootstrap_json %}
|
|
||||||
<script type="application/json" id="stats-calendar-bootstrap">{{ stats_bundle.calendar_bootstrap_json | safe }}</script>
|
|
||||||
{% endif %}
|
|
||||||
<div id="stats-calendar-wrap" class="trade-cal-wrap stats-calendar-wrap">
|
|
||||||
<div class="trade-cal-head">
|
|
||||||
<button type="button" id="stats-cal-prev" class="btn" title="上一月">‹</button>
|
|
||||||
<span id="stats-cal-title" class="trade-cal-title"></span>
|
|
||||||
<button type="button" id="stats-cal-next" class="btn" title="下一月">›</button>
|
|
||||||
</div>
|
|
||||||
<div id="stats-calendar" class="trade-cal-grid-host" role="grid" aria-label="交易日历"></div>
|
|
||||||
</div>
|
|
||||||
{% for seg in stats_bundle.segments %}
|
{% for seg in stats_bundle.segments %}
|
||||||
<div class="stats-segment-block stats-segment-panel" data-stats-segment="{{ seg.key }}"{% if not loop.first %} style="display:none"{% endif %}>
|
<div class="stats-segment-block stats-segment-panel" data-stats-segment="{{ seg.key }}"{% if not loop.first %} style="display:none"{% endif %}>
|
||||||
{{ period_stats("日统计", seg.day) }}
|
{{ period_stats("日统计", seg.day) }}
|
||||||
@@ -821,7 +809,6 @@
|
|||||||
<script src="/static/form_submit_guard.js?v=2"></script>
|
<script src="/static/form_submit_guard.js?v=2"></script>
|
||||||
<script src="/static/manual_order_rr_preview.js?v=5"></script>
|
<script src="/static/manual_order_rr_preview.js?v=5"></script>
|
||||||
<script src="/static/strategy_roll.js?v=5"></script>
|
<script src="/static/strategy_roll.js?v=5"></script>
|
||||||
<script src="/static/trade_stats_calendar.js?v=4"></script>
|
|
||||||
<script>
|
<script>
|
||||||
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
|
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
|
||||||
const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }};
|
const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }};
|
||||||
@@ -1480,7 +1467,6 @@ function switchStatsSegment(){
|
|||||||
q.set("stats_segment", key);
|
q.set("stats_segment", key);
|
||||||
const qs = q.toString();
|
const qs = q.toString();
|
||||||
history.replaceState(null, "", qs ? (window.location.pathname + "?" + qs) : window.location.pathname);
|
history.replaceState(null, "", qs ? (window.location.pathname + "?" + qs) : window.location.pathname);
|
||||||
if(window.statsCalendarWidget) window.statsCalendarWidget.load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initStatsSegmentFromUrl(){
|
function initStatsSegmentFromUrl(){
|
||||||
@@ -1504,7 +1490,6 @@ function toggleStatsCard(){
|
|||||||
attachListWindowToExports();
|
attachListWindowToExports();
|
||||||
toggleListWindowCustom();
|
toggleListWindowCustom();
|
||||||
initStatsSegmentFromUrl();
|
initStatsSegmentFromUrl();
|
||||||
if(typeof initInstanceStatsCalendar === "function") initInstanceStatsCalendar();
|
|
||||||
if(document.getElementById("journal-list")) loadJournals();
|
if(document.getElementById("journal-list")) loadJournals();
|
||||||
if(document.getElementById("review-list")) loadReviews();
|
if(document.getElementById("review-list")) loadReviews();
|
||||||
const reviewToggle = document.getElementById("review-mode-toggle");
|
const reviewToggle = document.getElementById("review-mode-toggle");
|
||||||
|
|||||||
@@ -1830,7 +1830,7 @@ def _compute_period_metrics(trades):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def compute_stats_bundle(conn, trading_day, now_dt=None, *, with_calendar=False):
|
def compute_stats_bundle(conn, trading_day, now_dt=None):
|
||||||
"""日 / 周 / 月 统计:平仓按北京时间交易日(默认 8:00 切日)计入。"""
|
"""日 / 周 / 月 统计:平仓按北京时间交易日(默认 8:00 切日)计入。"""
|
||||||
now_dt = now_dt or app_now()
|
now_dt = now_dt or app_now()
|
||||||
pnls = _load_completed_trade_pnls(conn)
|
pnls = _load_completed_trade_pnls(conn)
|
||||||
@@ -1861,15 +1861,6 @@ def compute_stats_bundle(conn, trading_day, now_dt=None, *, with_calendar=False)
|
|||||||
|
|
||||||
dm, wm, mm = slice_metrics("all")
|
dm, wm, mm = slice_metrics("all")
|
||||||
|
|
||||||
initial_calendar = None
|
|
||||||
calendar_bootstrap_json = None
|
|
||||||
if with_calendar:
|
|
||||||
from trade_stats_calendar_lib import build_stats_calendar_bootstrap
|
|
||||||
|
|
||||||
initial_calendar, calendar_bootstrap_json = build_stats_calendar_bootstrap(
|
|
||||||
pnls, now_dt, _pnl_row_matches_segment, reset_hour=TRADING_DAY_RESET_HOUR
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"trading_day": trading_day,
|
"trading_day": trading_day,
|
||||||
"total_opens_all": total_opens_all,
|
"total_opens_all": total_opens_all,
|
||||||
@@ -1878,8 +1869,6 @@ def compute_stats_bundle(conn, trading_day, now_dt=None, *, with_calendar=False)
|
|||||||
"month": mm,
|
"month": mm,
|
||||||
"segments": segments,
|
"segments": segments,
|
||||||
"stats_reset_hour": TRADING_DAY_RESET_HOUR,
|
"stats_reset_hour": TRADING_DAY_RESET_HOUR,
|
||||||
"initial_calendar": initial_calendar,
|
|
||||||
"calendar_bootstrap_json": calendar_bootstrap_json,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6385,7 +6374,7 @@ def render_main_page(page="trade", embed_mode=None):
|
|||||||
else []
|
else []
|
||||||
)
|
)
|
||||||
stats_bundle = (
|
stats_bundle = (
|
||||||
compute_stats_bundle(conn, trading_day, now, with_calendar=(page == "stats"))
|
compute_stats_bundle(conn, trading_day, now)
|
||||||
if plan.stats_bundle
|
if plan.stats_bundle
|
||||||
else minimal_stats_bundle(TRADING_DAY_RESET_HOUR)
|
else minimal_stats_bundle(TRADING_DAY_RESET_HOUR)
|
||||||
)
|
)
|
||||||
@@ -9032,20 +9021,6 @@ try:
|
|||||||
except Exception as _hub_err:
|
except Exception as _hub_err:
|
||||||
print(f"[hub_bridge] okx: {_hub_err}")
|
print(f"[hub_bridge] okx: {_hub_err}")
|
||||||
|
|
||||||
try:
|
|
||||||
from hub_bridge import register_trade_stats_calendar_route
|
|
||||||
|
|
||||||
register_trade_stats_calendar_route(
|
|
||||||
app,
|
|
||||||
login_required_fn=login_required,
|
|
||||||
load_pnls_fn=_load_completed_trade_pnls,
|
|
||||||
row_matches_segment_fn=_pnl_row_matches_segment,
|
|
||||||
reset_hour=TRADING_DAY_RESET_HOUR,
|
|
||||||
get_db_fn=get_db,
|
|
||||||
)
|
|
||||||
except Exception as _cal_err:
|
|
||||||
print(f"[stats calendar] okx: {_cal_err}")
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/strategy")
|
@app.route("/strategy")
|
||||||
@login_required
|
@login_required
|
||||||
|
|||||||
@@ -244,7 +244,6 @@
|
|||||||
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
|
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="/static/instance_theme.css?v=48">
|
<link rel="stylesheet" href="/static/instance_theme.css?v=48">
|
||||||
<link rel="stylesheet" href="/static/trade_stats_calendar.css?v=4">
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
@@ -803,17 +802,6 @@
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{% if stats_bundle.calendar_bootstrap_json %}
|
|
||||||
<script type="application/json" id="stats-calendar-bootstrap">{{ stats_bundle.calendar_bootstrap_json | safe }}</script>
|
|
||||||
{% endif %}
|
|
||||||
<div id="stats-calendar-wrap" class="trade-cal-wrap stats-calendar-wrap">
|
|
||||||
<div class="trade-cal-head">
|
|
||||||
<button type="button" id="stats-cal-prev" class="btn" title="上一月">‹</button>
|
|
||||||
<span id="stats-cal-title" class="trade-cal-title"></span>
|
|
||||||
<button type="button" id="stats-cal-next" class="btn" title="下一月">›</button>
|
|
||||||
</div>
|
|
||||||
<div id="stats-calendar" class="trade-cal-grid-host" role="grid" aria-label="交易日历"></div>
|
|
||||||
</div>
|
|
||||||
{% for seg in stats_bundle.segments %}
|
{% for seg in stats_bundle.segments %}
|
||||||
<div class="stats-segment-block stats-segment-panel" data-stats-segment="{{ seg.key }}"{% if not loop.first %} style="display:none"{% endif %}>
|
<div class="stats-segment-block stats-segment-panel" data-stats-segment="{{ seg.key }}"{% if not loop.first %} style="display:none"{% endif %}>
|
||||||
{{ period_stats("日统计", seg.day) }}
|
{{ period_stats("日统计", seg.day) }}
|
||||||
@@ -850,7 +838,6 @@
|
|||||||
<script src="/static/form_submit_guard.js?v=2"></script>
|
<script src="/static/form_submit_guard.js?v=2"></script>
|
||||||
<script src="/static/manual_order_rr_preview.js?v=5"></script>
|
<script src="/static/manual_order_rr_preview.js?v=5"></script>
|
||||||
<script src="/static/strategy_roll.js?v=5"></script>
|
<script src="/static/strategy_roll.js?v=5"></script>
|
||||||
<script src="/static/trade_stats_calendar.js?v=4"></script>
|
|
||||||
<script>
|
<script>
|
||||||
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
|
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
|
||||||
const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }};
|
const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }};
|
||||||
@@ -1509,7 +1496,6 @@ function switchStatsSegment(){
|
|||||||
q.set("stats_segment", key);
|
q.set("stats_segment", key);
|
||||||
const qs = q.toString();
|
const qs = q.toString();
|
||||||
history.replaceState(null, "", qs ? (window.location.pathname + "?" + qs) : window.location.pathname);
|
history.replaceState(null, "", qs ? (window.location.pathname + "?" + qs) : window.location.pathname);
|
||||||
if(window.statsCalendarWidget) window.statsCalendarWidget.load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initStatsSegmentFromUrl(){
|
function initStatsSegmentFromUrl(){
|
||||||
@@ -1533,7 +1519,6 @@ function toggleStatsCard(){
|
|||||||
attachListWindowToExports();
|
attachListWindowToExports();
|
||||||
toggleListWindowCustom();
|
toggleListWindowCustom();
|
||||||
initStatsSegmentFromUrl();
|
initStatsSegmentFromUrl();
|
||||||
if(typeof initInstanceStatsCalendar === "function") initInstanceStatsCalendar();
|
|
||||||
if(document.getElementById("journal-list")) loadJournals();
|
if(document.getElementById("journal-list")) loadJournals();
|
||||||
if(document.getElementById("review-list")) loadReviews();
|
if(document.getElementById("review-list")) loadReviews();
|
||||||
const reviewToggle = document.getElementById("review-mode-toggle");
|
const reviewToggle = document.getElementById("review-mode-toggle");
|
||||||
|
|||||||
@@ -664,7 +664,6 @@ function switchStatsSegment(){
|
|||||||
q.set("stats_segment", key);
|
q.set("stats_segment", key);
|
||||||
const qs = q.toString();
|
const qs = q.toString();
|
||||||
history.replaceState(null, "", qs ? (window.location.pathname + "?" + qs) : window.location.pathname);
|
history.replaceState(null, "", qs ? (window.location.pathname + "?" + qs) : window.location.pathname);
|
||||||
if(window.statsCalendarWidget) window.statsCalendarWidget.load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initStatsSegmentFromUrl(){
|
function initStatsSegmentFromUrl(){
|
||||||
@@ -701,7 +700,6 @@ attachListWindowToExports();
|
|||||||
toggleListWindowCustom();
|
toggleListWindowCustom();
|
||||||
bindListWindowDateAutoCustom();
|
bindListWindowDateAutoCustom();
|
||||||
initStatsSegmentFromUrl();
|
initStatsSegmentFromUrl();
|
||||||
if(typeof initInstanceStatsCalendar === "function") initInstanceStatsCalendar();
|
|
||||||
if(document.getElementById("journal-list")) loadJournals();
|
if(document.getElementById("journal-list")) loadJournals();
|
||||||
if(document.getElementById("review-list")) loadReviews();
|
if(document.getElementById("review-list")) loadReviews();
|
||||||
const reviewToggle = document.getElementById("review-mode-toggle");
|
const reviewToggle = document.getElementById("review-mode-toggle");
|
||||||
|
|||||||
@@ -452,17 +452,6 @@
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{% if stats_bundle.calendar_bootstrap_json %}
|
|
||||||
<script type="application/json" id="stats-calendar-bootstrap">{{ stats_bundle.calendar_bootstrap_json | safe }}</script>
|
|
||||||
{% endif %}
|
|
||||||
<div id="stats-calendar-wrap" class="trade-cal-wrap stats-calendar-wrap">
|
|
||||||
<div class="trade-cal-head">
|
|
||||||
<button type="button" id="stats-cal-prev" class="btn" title="上一月">‹</button>
|
|
||||||
<span id="stats-cal-title" class="trade-cal-title"></span>
|
|
||||||
<button type="button" id="stats-cal-next" class="btn" title="下一月">›</button>
|
|
||||||
</div>
|
|
||||||
<div id="stats-calendar" class="trade-cal-grid-host" role="grid" aria-label="交易日历"></div>
|
|
||||||
</div>
|
|
||||||
{% for seg in stats_bundle.segments %}
|
{% for seg in stats_bundle.segments %}
|
||||||
<div class="stats-segment-block stats-segment-panel" data-stats-segment="{{ seg.key }}"{% if not loop.first %} style="display:none"{% endif %}>
|
<div class="stats-segment-block stats-segment-panel" data-stats-segment="{{ seg.key }}"{% if not loop.first %} style="display:none"{% endif %}>
|
||||||
{{ period_stats("日统计", seg.day) }}
|
{{ period_stats("日统计", seg.day) }}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
|
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
|
||||||
<link rel="stylesheet" href="/static/instance_page.css?v=2">
|
<link rel="stylesheet" href="/static/instance_page.css?v=2">
|
||||||
<link rel="stylesheet" href="/static/instance_theme.css?v=48">
|
<link rel="stylesheet" href="/static/instance_theme.css?v=48">
|
||||||
<link rel="stylesheet" href="/static/trade_stats_calendar.css?v=4">
|
|
||||||
<script src="/static/account_risk_badge.js?v=4"></script>
|
<script src="/static/account_risk_badge.js?v=4"></script>
|
||||||
<meta name="theme-color" content="#0b0d14">
|
<meta name="theme-color" content="#0b0d14">
|
||||||
<title>{{ exchange_display }} · 加密货币 | 交易监控复盘系统</title>
|
<title>{{ exchange_display }} · 加密货币 | 交易监控复盘系统</title>
|
||||||
@@ -121,7 +120,6 @@
|
|||||||
<script src="/static/manual_order_rr_preview.js?v=5"></script>
|
<script src="/static/manual_order_rr_preview.js?v=5"></script>
|
||||||
<script src="/static/strategy_roll.js?v=5"></script>
|
<script src="/static/strategy_roll.js?v=5"></script>
|
||||||
<script src="/static/key_monitor_form.js?v=2"></script>
|
<script src="/static/key_monitor_form.js?v=2"></script>
|
||||||
<script src="/static/trade_stats_calendar.js?v=4"></script>
|
|
||||||
{% include 'embed_boot_scripts.html' %}
|
{% include 'embed_boot_scripts.html' %}
|
||||||
<script src="/static/instance_embed.js?v=5"></script>
|
<script src="/static/instance_embed.js?v=5"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -81,9 +81,4 @@ def trade_records_summary(conn, start_bj: str, end_bj: str, tr_ts: str) -> dict[
|
|||||||
|
|
||||||
|
|
||||||
def minimal_stats_bundle(reset_hour: int) -> dict[str, Any]:
|
def minimal_stats_bundle(reset_hour: int) -> dict[str, Any]:
|
||||||
return {
|
return {"stats_reset_hour": reset_hour, "segments": []}
|
||||||
"stats_reset_hour": reset_hour,
|
|
||||||
"segments": [],
|
|
||||||
"initial_calendar": None,
|
|
||||||
"calendar_bootstrap_json": None,
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -78,7 +78,6 @@
|
|||||||
}
|
}
|
||||||
if (tab === "stats") {
|
if (tab === "stats") {
|
||||||
if (typeof global.initStatsSegmentFromUrl === "function") global.initStatsSegmentFromUrl();
|
if (typeof global.initStatsSegmentFromUrl === "function") global.initStatsSegmentFromUrl();
|
||||||
if (typeof global.initInstanceStatsCalendar === "function") global.initInstanceStatsCalendar();
|
|
||||||
}
|
}
|
||||||
if (typeof global.refreshPriceSnapshotConditional === "function") {
|
if (typeof global.refreshPriceSnapshotConditional === "function") {
|
||||||
global.refreshPriceSnapshotConditional();
|
global.refreshPriceSnapshotConditional();
|
||||||
|
|||||||
Reference in New Issue
Block a user