记录一次全量验证(2026-06-18)
记录一次全量验证(2026-06-18)验证不是"看起来没报错",是把每一格都点开看过
v1.25 的代码前一天已经写完、入库、冒烟。但"写完"和"验证完"之间,隔着一段必须走的流程:换一个干净进程、把回测跑满、把每个页面的数据源挨个查一遍。
这天做的就是把这段流程走完。全量验证,一个页面都不跳。
先换一个干净的进程验证的第一原则是别在旧的进程上验。
杀掉旧进程(417088、416872),重启 4 个新实例,主进程 PID 402864 加 3 个辅助进程,port 8501 返回 HTTP 200。
为什么非要重启?因为旧进程里可能还残留着改代码之前加载的模块。**要验的是"现在这份代码",不是"过去某个时刻加载过的代码"**——不重启,验的可能是一份已经不存在的版本。
104 秒,50 个版本backtest_runner.py 跑完,耗时 104s,exit 0,50 个版本回测完成,结果写入 bt_cf_summary 和 bt_cf_trades,最新 run_at 是 ...
记录一次看板数据丢失的修复(2026-06-15)
记录一次看板数据丢失的修复(2026-06-15)数据"消失"的时候,先看它是被删了,还是根本没写进去
TVL 看板某天开始是空的。不是加载慢,是图表直接报错,一张干干净净的空白。
这天把这块看板修回来。
一块空的图页面 pages/1_tvl_rank.py 里的 Plotly 柱状图,x 轴取的是 protocol 字段:
1px.bar(x='protocol')
它读到的是一个空列,于是图表报错、数据全丢。
前端报错看着像渲染问题,但真正的疑点应该往后推一步:数据是什么时候没的?是同步进来的数据本来就空,还是本来有、后来被写没了?
根因:往一个不存在的列里写查下来,问题在写入端,而且比想象中更基础。
tvl_rank 表原本就没有 protocol 列。而 save_tvl_rank 在做 INSERT 的时候,把协议名写进了这个不存在的列——结果数据全丢。
同时,页面又反过来用 px.bar(x='protocol') 去引用这个空列,于是一起报错。
这条链子很典型:写入端写了个不存在的目标,读取端读了个空的结果,两 ...
记录一次车间看板的搭建(2026-05-14)
记录一次车间看板的搭建(2026-05-14)需求很简单:让工时自己说话,别再靠人抄
车间里的工时数据是有的——机器一直在采,落在 MySQL 里。问题是没人看。数据躺在表里,要问产量就得有人去查、去汇总、去做表。信息在,但不在需要它的人眼前。
这块看板就是为了把这句话反过来:数据在哪儿产生,就在哪儿显示。
先看数据长什么样第一步永远是看表结构,而不是先想界面。
表是 work_load,在一台早期的 MySQL 上(100.64.0.2:3306,库叫 m3_ai_data)。字段不复杂:
字段
含义
START_TIME / END_TIME
一段工作的起止
WORKER_NUM
工位编号
WORKTIME
工时,单位秒
WORKLOAD
工作量,单位人·秒
AREA / MAIN_AREA
区域 / 主区域
两个细节后来证明很关键:工时是秒不是分钟,**工作量是"人·秒"**。也就是说,同是一小时,两个人干出来的是一个人的两倍——这一条决定了后面所有图表的口径。
还有一点,这几个字段都是 varc ...