feat: DB-first architecture with lock-safe writes
- price_monitor: writes live prices to both JSON and mofin.db (holdings + live_prices + portfolio_summary) - mofin_db: added execute_with_retry/commit_with_retry with exponential backoff on 'database is locked' - mofin_db: increased timeout 5s->15s, added PRAGMA busy_timeout=15000 - price_monitor retry loop: fixed break-before-if-ok bug (was not retrying on write failure) - DB connection: WAL mode + retry decorator for all write operations - cash sync: preserves DB authoritative cash (JSON cash not pushed to DB) This is the DB-first version. JSON writes remain for dashboard compatibility. Next step: remove JSON writes entirely for full DB-only architecture.
This commit is contained in:
+147
-221
@@ -1,240 +1,166 @@
|
||||
{
|
||||
"holdings": [
|
||||
{
|
||||
"code": "300308",
|
||||
"name": "中际旭创",
|
||||
"shares": 100,
|
||||
"cost": 1316.53,
|
||||
"price": 1116.0,
|
||||
"market_value": 111600.0,
|
||||
"change_pct": -2.36,
|
||||
"currency": "CNY",
|
||||
"position_pct": 15.27,
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "06869",
|
||||
"name": "长飞光纤光缆",
|
||||
"shares": 500,
|
||||
"cost": 263.73,
|
||||
"price": 201.2,
|
||||
"market_value": 87220.0,
|
||||
"change_pct": 1.64,
|
||||
"currency": "HKD",
|
||||
"position_pct": 13.47,
|
||||
"_currency": "HKD"
|
||||
},
|
||||
{
|
||||
"code": "01478",
|
||||
"name": "丘钛科技",
|
||||
"shares": 11000,
|
||||
"cost": 13.47,
|
||||
"price": 6.99,
|
||||
"market_value": 66660.0,
|
||||
"change_pct": 4.02,
|
||||
"currency": "HKD",
|
||||
"position_pct": 7.97,
|
||||
"_currency": "HKD"
|
||||
},
|
||||
{
|
||||
"code": "601899",
|
||||
"name": "紫金矿业",
|
||||
"shares": 2400,
|
||||
"cost": 39.89,
|
||||
"price": 27.82,
|
||||
"market_value": 66768.0,
|
||||
"change_pct": 5.78,
|
||||
"currency": "CNY",
|
||||
"position_pct": 7.34,
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "688411",
|
||||
"name": "海博思创",
|
||||
"shares": 200,
|
||||
"cost": 266.95,
|
||||
"price": 251.15,
|
||||
"market_value": 50230.0,
|
||||
"change_pct": -1.78,
|
||||
"currency": "CNY",
|
||||
"position_pct": 6.31,
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "688981",
|
||||
"name": "中芯国际",
|
||||
"shares": 300,
|
||||
"cost": 126.07,
|
||||
"price": 140.31,
|
||||
"market_value": 42093.0,
|
||||
"change_pct": -2.63,
|
||||
"currency": "CNY",
|
||||
"position_pct": 5.44,
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "01888",
|
||||
"name": "建滔积层板",
|
||||
"shares": 500,
|
||||
"cost": 88.24,
|
||||
"price": 84.45,
|
||||
"market_value": 36545.0,
|
||||
"change_pct": 0.78,
|
||||
"currency": "HKD",
|
||||
"position_pct": 5.28,
|
||||
"_currency": "HKD"
|
||||
},
|
||||
{
|
||||
"code": "688639",
|
||||
"name": "华恒生物",
|
||||
"shares": 2800,
|
||||
"cost": 21.51,
|
||||
"price": 16.66,
|
||||
"market_value": 46648.0,
|
||||
"change_pct": -1.71,
|
||||
"currency": "CNY",
|
||||
"position_pct": 5.25,
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "300750",
|
||||
"name": "宁德时代",
|
||||
"shares": 100,
|
||||
"cost": 401.78,
|
||||
"price": 380.0,
|
||||
"market_value": 38000.0,
|
||||
"change_pct": -0.61,
|
||||
"currency": "CNY",
|
||||
"position_pct": 4.64,
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "01211",
|
||||
"name": "比亚迪股份",
|
||||
"shares": 600,
|
||||
"cost": 104.87,
|
||||
"price": 84.1,
|
||||
"market_value": 43932.0,
|
||||
"change_pct": 7.41,
|
||||
"currency": "HKD",
|
||||
"position_pct": 4.62,
|
||||
"_currency": "HKD"
|
||||
},
|
||||
{
|
||||
"code": "02202",
|
||||
"name": "万科企业",
|
||||
"shares": 19700,
|
||||
"cost": 4.67,
|
||||
"price": 2.34,
|
||||
"market_value": 40188.0,
|
||||
"change_pct": 4.93,
|
||||
"currency": "HKD",
|
||||
"position_pct": 4.6,
|
||||
"_currency": "HKD"
|
||||
},
|
||||
{
|
||||
"code": "00700",
|
||||
"name": "腾讯",
|
||||
"shares": 100,
|
||||
"cost": 443.13,
|
||||
"price": 431.2,
|
||||
"market_value": 37437.0,
|
||||
"change_pct": 0.23,
|
||||
"price": 447.0,
|
||||
"market_value": 39063.0,
|
||||
"change_pct": 3.66,
|
||||
"currency": "HKD",
|
||||
"position_pct": null,
|
||||
"_currency": "HKD"
|
||||
},
|
||||
{
|
||||
"code": "00981",
|
||||
"name": "中芯国际",
|
||||
"shares": 500,
|
||||
"cost": 75.94,
|
||||
"price": 77.6,
|
||||
"market_value": 33530.0,
|
||||
"change_pct": -3.48,
|
||||
"currency": "HKD",
|
||||
"position_pct": 4.2,
|
||||
"_currency": "HKD"
|
||||
},
|
||||
{
|
||||
"code": "300548",
|
||||
"name": "长芯博创",
|
||||
"shares": 100,
|
||||
"cost": 231.46,
|
||||
"price": 221.01,
|
||||
"market_value": 22101.0,
|
||||
"change_pct": -0.45,
|
||||
"currency": "CNY",
|
||||
"position_pct": 3.2,
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "518880",
|
||||
"name": "黄金ETF华安",
|
||||
"shares": 2400,
|
||||
"cost": 12.19,
|
||||
"price": 8.67,
|
||||
"market_value": 20808.0,
|
||||
"change_pct": 2.32,
|
||||
"currency": "CNY",
|
||||
"position_pct": 2.45,
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "300035",
|
||||
"name": "中科电气",
|
||||
"shares": 1400,
|
||||
"cost": 22.29,
|
||||
"price": 14.29,
|
||||
"market_value": 20006.0,
|
||||
"change_pct": 0.85,
|
||||
"currency": "CNY",
|
||||
"position_pct": 2.42,
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "000700",
|
||||
"name": "模塑科技",
|
||||
"shares": 1400,
|
||||
"cost": 14.83,
|
||||
"price": 17.6,
|
||||
"market_value": 24640.0,
|
||||
"change_pct": 4.33,
|
||||
"currency": "CNY",
|
||||
"position_pct": 2.41,
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "600563",
|
||||
"name": "法拉电子",
|
||||
"shares": 100,
|
||||
"cost": 147.18,
|
||||
"price": 157.06,
|
||||
"market_value": 15706.0,
|
||||
"change_pct": -4.41,
|
||||
"currency": "CNY",
|
||||
"position_pct": 2.3,
|
||||
"_currency": "CNY"
|
||||
"position_pct": null
|
||||
},
|
||||
{
|
||||
"code": "01088",
|
||||
"name": "中国神华",
|
||||
"shares": 500,
|
||||
"cost": 45.89,
|
||||
"price": 40.0,
|
||||
"market_value": 17355.0,
|
||||
"change_pct": 1.01,
|
||||
"price": 40.68,
|
||||
"market_value": 17575.0,
|
||||
"change_pct": 1.7,
|
||||
"currency": "HKD",
|
||||
"position_pct": 2.14,
|
||||
"_currency": "HKD"
|
||||
"position_pct": 2.14
|
||||
},
|
||||
{
|
||||
"code": "01211",
|
||||
"name": "比亚迪股份",
|
||||
"shares": 600,
|
||||
"cost": 104.87,
|
||||
"price": 84.2,
|
||||
"market_value": 44376.0,
|
||||
"change_pct": 0.12,
|
||||
"currency": "HKD",
|
||||
"position_pct": 4.62
|
||||
},
|
||||
{
|
||||
"code": "01478",
|
||||
"name": "丘钛科技",
|
||||
"shares": 11000,
|
||||
"cost": 13.47,
|
||||
"price": 6.77,
|
||||
"market_value": 64460.0,
|
||||
"change_pct": -3.15,
|
||||
"currency": "HKD",
|
||||
"position_pct": 7.97
|
||||
},
|
||||
{
|
||||
"code": "02202",
|
||||
"name": "万科企业",
|
||||
"shares": 19700,
|
||||
"cost": 4.67,
|
||||
"price": 2.33,
|
||||
"market_value": 40385.0,
|
||||
"change_pct": -0.43,
|
||||
"currency": "HKD",
|
||||
"position_pct": 4.6
|
||||
},
|
||||
{
|
||||
"code": "300035",
|
||||
"name": "中科电气",
|
||||
"shares": 1400,
|
||||
"cost": 22.29,
|
||||
"price": 14.02,
|
||||
"market_value": 19712.0,
|
||||
"change_pct": -1.89,
|
||||
"currency": "CNY",
|
||||
"position_pct": 2.42
|
||||
},
|
||||
{
|
||||
"code": "300308",
|
||||
"name": "中际旭创",
|
||||
"shares": 100,
|
||||
"cost": 1316.53,
|
||||
"price": 1116.03,
|
||||
"market_value": 106181.0,
|
||||
"change_pct": 0.0,
|
||||
"currency": "CNY",
|
||||
"position_pct": 15.27
|
||||
},
|
||||
{
|
||||
"code": "300750",
|
||||
"name": "宁德时代",
|
||||
"shares": 100,
|
||||
"cost": 401.78,
|
||||
"price": 377.6,
|
||||
"market_value": 37726.0,
|
||||
"change_pct": -0.63,
|
||||
"currency": "CNY",
|
||||
"position_pct": 4.64
|
||||
},
|
||||
{
|
||||
"code": "518880",
|
||||
"name": "黄金ETF华安",
|
||||
"shares": 2400,
|
||||
"cost": 12.19,
|
||||
"price": 8.66,
|
||||
"market_value": 20832.0,
|
||||
"change_pct": -0.08,
|
||||
"currency": "CNY",
|
||||
"position_pct": 2.45
|
||||
},
|
||||
{
|
||||
"code": "600563",
|
||||
"name": "法拉电子",
|
||||
"shares": 100,
|
||||
"cost": 147.18,
|
||||
"price": 153.42,
|
||||
"market_value": 15021.0,
|
||||
"change_pct": -2.32,
|
||||
"currency": "CNY",
|
||||
"position_pct": 2.3
|
||||
},
|
||||
{
|
||||
"code": "601899",
|
||||
"name": "紫金矿业",
|
||||
"shares": 2400,
|
||||
"cost": 39.89,
|
||||
"price": 28.41,
|
||||
"market_value": 68784.0,
|
||||
"change_pct": 2.12,
|
||||
"currency": "CNY",
|
||||
"position_pct": 7.34
|
||||
},
|
||||
{
|
||||
"code": "688411",
|
||||
"name": "海博思创",
|
||||
"shares": 200,
|
||||
"cost": 266.95,
|
||||
"price": 262.98,
|
||||
"market_value": 52064.0,
|
||||
"change_pct": 4.71,
|
||||
"currency": "CNY",
|
||||
"position_pct": 6.31
|
||||
},
|
||||
{
|
||||
"code": "688639",
|
||||
"name": "华恒生物",
|
||||
"shares": 2800,
|
||||
"cost": 21.51,
|
||||
"price": 16.61,
|
||||
"market_value": 46480.0,
|
||||
"change_pct": -0.3,
|
||||
"currency": "CNY",
|
||||
"position_pct": 5.25
|
||||
},
|
||||
{
|
||||
"code": "688981",
|
||||
"name": "中芯国际",
|
||||
"shares": 300,
|
||||
"cost": 126.07,
|
||||
"price": 147.18,
|
||||
"market_value": 40599.0,
|
||||
"change_pct": 4.9,
|
||||
"currency": "CNY",
|
||||
"position_pct": 5.44
|
||||
}
|
||||
],
|
||||
"total_assets": 952877.07,
|
||||
"total_mv": 820755.14,
|
||||
"stock_value": 820755.14,
|
||||
"cash": 132121.93,
|
||||
"frozen_cash": 0,
|
||||
"position_pct": 86.13,
|
||||
"cash": 289196.0,
|
||||
"frozen_cash": 0.0,
|
||||
"total_mv": 619713.76,
|
||||
"total_assets": 908909.76,
|
||||
"position_pct": 68.18,
|
||||
"currency": "CNY",
|
||||
"updated_at": "2026-07-04 09:51"
|
||||
"updated_at": "2026-07-06 11:35:19",
|
||||
"stock_value": 619713.76
|
||||
}
|
||||
Reference in New Issue
Block a user