From bab7c4d893d3c0a959a384fff6992c04d0776854 Mon Sep 17 00:00:00 2001 From: claude_dev Date: Sun, 16 Aug 2026 09:34:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(strategy):=20TODO#68-#75=E5=85=AB=E9=A1=B9?= =?UTF-8?q?=E5=85=A8=E5=81=9A+=E5=AF=BC=E8=88=AA=E8=87=AA=E6=B5=8B?= =?UTF-8?q?=E2=80=94=E2=80=94#68=E7=81=AF=E8=81=8C=E8=B4=A3=E6=8B=86?= =?UTF-8?q?=E5=88=86:=E5=AE=9E=E8=B5=B0/=E5=BD=B1=E5=AD=90=E5=9C=A8?= =?UTF-8?q?=E8=B7=91=3D=E7=9B=B4=E8=BE=BE/paper/live/{aid}=E7=9B=91?= =?UTF-8?q?=E6=8E=A7=E9=A1=B5,=E5=AE=9E=E7=9B=98=E5=9C=A8=E8=B7=91=3D/live?= =?UTF-8?q?/monitor/{aid},=E6=9C=AA=E8=B7=91=3D=E5=8F=91=E8=B5=B7;?= =?UTF-8?q?=E5=9B=9E=E6=94=BE=E7=81=AFdone=3D=E7=9B=B4=E8=BE=BE/paper/resu?= =?UTF-8?q?lt/{aid}(run=5Fmeta.replay.account=5Fid);#69=E5=9B=9E=E6=B5=8B?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=8C=89=E5=AE=9E=E4=BE=8B=E8=BF=87=E6=BB=A4?= =?UTF-8?q?:backtest=5Fstats=E5=8A=A0instance=5Fid=E5=88=97(ALTER=E8=BF=81?= =?UTF-8?q?=E7=A7=BB)+=5Fwrite=5Fback=E8=90=BD=E5=88=97+GET=20/task=3Finst?= =?UTF-8?q?ance=3DN+=E4=BB=BB=E5=8A=A1=E4=B8=AD=E5=BF=83=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E6=9D=A1+=E7=AD=96=E7=95=A5=E5=BA=93=E3=80=8C=E5=9B=9E?= =?UTF-8?q?=E6=B5=8B=E5=8E=86=E5=8F=B2=E3=80=8D=E6=8C=89=E9=92=AE;?= =?UTF-8?q?=E5=9B=9E=E6=B5=8B=E7=81=AFdone=3D=E7=9B=B4=E8=BE=BE=E6=9C=80?= =?UTF-8?q?=E6=96=B0=E7=BB=93=E6=9E=9C=E9=A1=B5(run=5Fmeta.backtest.task?= =?UTF-8?q?=5Fid=E6=8C=89=E5=89=8D=E7=BC=80=E5=88=86=E6=B5=81),=E8=B7=91?= =?UTF-8?q?=E8=BF=87=E6=97=A0=E7=BB=93=E6=9E=9C=3D=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E4=B8=AD=E5=BF=83=E8=BF=87=E6=BB=A4;#70=E6=A8=A1=E6=8B=9F?= =?UTF-8?q?=E7=9B=98=E5=88=9B=E5=BB=BA=E5=90=8E=E7=9B=B4=E6=8E=A5=E8=B7=B3?= =?UTF-8?q?=E5=88=97=E8=A1=A8(=E4=B8=8D=E8=B7=B3=E7=BB=93=E6=9E=9C/?= =?UTF-8?q?=E7=9B=91=E6=8E=A7=E9=A1=B5);=E5=88=97=E5=AE=BD=E9=87=8D?= =?UTF-8?q?=E6=8E=92(=E7=AD=96=E7=95=A5/=E5=AE=9E=E4=BE=8B150=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F96=E9=A2=91=E7=8E=8760=E6=93=8D=E4=BD=9C250,=E6=8A=98?= =?UTF-8?q?=E8=A1=8C=E5=AE=9E=E6=B5=8B=E6=B6=88=E9=99=A4);#71=E5=88=97?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E5=AF=B9=E9=BD=90=E5=AE=9E=E7=9B=98:?= =?UTF-8?q?=E7=AD=96=E7=95=A5/=E5=AE=9E=E4=BE=8B=E5=88=97=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=AE=9E=E4=BE=8B=E5=90=8D(instances=E6=98=A0?= =?UTF-8?q?=E5=B0=84,#id=E9=80=80=E5=8C=96)+=E6=8C=81=E4=BB=93=E6=95=B0?= =?UTF-8?q?=E5=88=97(list=5Fpapers=E9=A1=BA=E5=B8=A6count=20volume>0)+?= =?UTF-8?q?=E5=88=A0=E5=88=9B=E5=BB=BA=E6=97=B6=E9=97=B4=E5=88=97(?= =?UTF-8?q?=E5=87=80=E5=80=BC=E6=97=A5=E6=9C=9F=E5=B7=B2=E5=90=AB);#72?= =?UTF-8?q?=E5=AE=9E=E7=9B=98=E5=90=8D=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90?= =?UTF-8?q?=3D{=E5=AE=9E=E4=BE=8B=E5=90=8D}=5Fv{YYYYMMDD}{minor}(=E5=90=8C?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B=E5=90=8C=E6=97=A5=E9=80=92=E5=A2=9E,listLive?= =?UTF-8?q?s=E8=AE=A1=E6=95=B0);=E6=A8=A1=E6=8B=9F=E7=9B=98=E5=90=8D=3D{?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B=E5=90=8D}=C2=B7{=E6=A8=A1=E5=BC=8F};#73?= =?UTF-8?q?=E6=9C=AF=E8=AF=AD=E7=BB=9F=E4=B8=80=E6=A1=A3=E6=A1=88=E2=86=92?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B(=E5=85=A8=E5=B1=808=E6=96=87=E4=BB=B6UI?= =?UTF-8?q?=E6=96=87=E6=A1=88+=E5=90=8E=E7=AB=AF409=E6=8F=90=E7=A4=BA,?= =?UTF-8?q?=E7=B2=BE=E7=A1=AE=E7=9F=AD=E8=AF=AD=E9=98=B2=E8=AF=AF=E4=BC=A4?= =?UTF-8?q?,spec=E6=AF=94=E5=96=BB=E4=BF=9D=E7=95=99=E6=96=87=E6=A1=A3);#7?= =?UTF-8?q?4MonacoDiff=20v4:=E4=BC=98=E5=85=88monaco=E5=8E=9F=E7=94=9Fdiff?= =?UTF-8?q?(=E5=B7=AE=E5=BC=82=E9=AB=98=E4=BA=AE),=E6=8C=82=E8=BD=BD450ms?= =?UTF-8?q?=E8=87=AA=E6=A3=80original=E6=A0=8F=E5=8D=A0=E6=AF=94<30%?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=99=8D=E7=BA=A7=E5=8F=8C=E5=8F=AA=E8=AF=BB?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8(=E6=BB=9A=E5=8A=A8=E8=81=94?= =?UTF-8?q?=E5=8A=A8)=E2=80=94=E2=80=94=E5=85=A8=E5=B1=8F=E6=A8=A1?= =?UTF-8?q?=E6=80=81=E4=B8=8B=E5=A4=A7=E6=A6=82=E7=8E=87=E5=90=83=E5=88=B0?= =?UTF-8?q?=E5=8E=9F=E7=94=9Fdiff;#75=E6=94=B6=E7=9B=8A=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E4=B8=8E=E6=95=B0=E5=80=BC=E5=90=8C=E6=BA=90(retInfoOf:?= =?UTF-8?q?=E8=BF=90=E8=A1=8Cret=E4=BC=98=E5=85=88=E5=90=ABkind,fallback?= =?UTF-8?q?=20run=5Freturns,=E6=A0=87=E7=AD=BE=E8=B7=9F=E9=9A=8F=E6=95=B0?= =?UTF-8?q?=E5=80=BC=E6=9D=A5=E6=BA=90,=E6=A0=B9=E6=B2=BB=E5=BD=B1?= =?UTF-8?q?=E5=AD=901044%=E5=AE=9E=E4=B8=BA=E5=9B=9E=E6=B5=8B=E6=94=B6?= =?UTF-8?q?=E7=9B=8A=E6=8C=82=E5=BD=B1=E5=AD=90=E6=A0=87=E7=AD=BE);927?= =?UTF-8?q?=E7=BB=BF+build=E7=BB=BF+dev=E6=B5=8F=E8=A7=88=E5=99=A8?= =?UTF-8?q?=E8=87=AA=E6=B5=8B:=E7=AD=96=E7=95=A5=E5=BA=936=E5=85=A5?= =?UTF-8?q?=E5=8F=A3(=E5=9B=9E=E6=B5=8B=E5=8E=86=E5=8F=B2/=E6=A8=A1?= =?UTF-8?q?=E6=8B=9F=E5=8E=86=E5=8F=B2/=E5=AE=9E=E7=9B=98=E5=8E=86?= =?UTF-8?q?=E5=8F=B2/=E5=9B=9E=E6=B5=8B=E7=81=AF/=E5=AE=9E=E8=B5=B0?= =?UTF-8?q?=E7=81=AF=E7=9B=B4=E8=BE=BE=E7=9B=91=E6=8E=A7/=E7=BB=84?= =?UTF-8?q?=E5=90=88=E6=97=A0=E5=9B=9E=E6=94=BE)=E4=B8=8E=E6=A8=A1?= =?UTF-8?q?=E6=8B=9F=E7=9B=98=E5=88=97=E8=A1=A8=E6=96=B0=E5=88=97=E5=85=A8?= =?UTF-8?q?=E8=BF=87=20[vps]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/backtest.ts | 7 +- frontend/src/api/paper.ts | 1 + frontend/src/components/MonacoDiff.vue | 168 ++++++++++++------ frontend/src/views/backtest/History.vue | 12 +- frontend/src/views/backtest/New.vue | 6 +- .../src/views/backtest/PortfolioBacktest.vue | 6 +- frontend/src/views/live/List.vue | 2 +- frontend/src/views/live/New.vue | 31 +++- frontend/src/views/paper/List.vue | 42 +++-- frontend/src/views/paper/New.vue | 17 +- frontend/src/views/strategy/List.vue | 75 +++++--- sanguo_api/routes.py | 19 +- sanguo_api/routes_paper.py | 10 +- sanguo_api/routes_strategy.py | 2 +- sanguo_backtest/result_store.py | 5 + sanguo_orchestrator/runner.py | 16 +- 16 files changed, 293 insertions(+), 126 deletions(-) diff --git a/frontend/src/api/backtest.ts b/frontend/src/api/backtest.ts index 0feb593..c0a24d1 100644 --- a/frontend/src/api/backtest.ts +++ b/frontend/src/api/backtest.ts @@ -107,13 +107,16 @@ export interface TaskListItem { start: string end: string instance?: string + instance_id?: number | null created_at?: string finished_at?: string duration_s?: number | null } -export async function getTasks(type?: string): Promise { - const { data } = await apiClient.get<{ tasks: TaskListItem[] }>('/task', { params: type ? { type } : {} }) +export async function getTasks(type?: string, instance?: number): Promise { + const { data } = await apiClient.get<{ tasks: TaskListItem[] }>('/task', { + params: { ...(type ? { type } : {}), ...(instance ? { instance } : {}) }, + }) return data.tasks } diff --git a/frontend/src/api/paper.ts b/frontend/src/api/paper.ts index 2ce7e7e..487c953 100644 --- a/frontend/src/api/paper.ts +++ b/frontend/src/api/paper.ts @@ -9,6 +9,7 @@ export interface StrategyCfg { } export interface PaperCreate { + name?: string mode: string interval: string symbols: string[] diff --git a/frontend/src/components/MonacoDiff.vue b/frontend/src/components/MonacoDiff.vue index e6166e8..dd067cd 100644 --- a/frontend/src/components/MonacoDiff.vue +++ b/frontend/src/components/MonacoDiff.vue @@ -1,7 +1,7 @@ diff --git a/frontend/src/views/backtest/History.vue b/frontend/src/views/backtest/History.vue index 8a19004..7e6324a 100644 --- a/frontend/src/views/backtest/History.vue +++ b/frontend/src/views/backtest/History.vue @@ -1,16 +1,21 @@