完成模型更新
This commit is contained in:
+69
-6
@@ -324,9 +324,9 @@ class _GridPanel:
|
||||
return self._col
|
||||
|
||||
def _rebuild(self):
|
||||
# (width, expand): 0=固定宽, >0=弹性比重
|
||||
_C = [(35, 0), (0, 2), (70, 1), (0, 2), (50, 1), (55, 1), (60, 1), (0, 1)]
|
||||
H = ["ID", "股票", "市场价", "网格基准", "持仓", "成本", "状态", "操作"]
|
||||
# (width, expand): 0=固定宽, >0=弹性比重; 新增排名列(50px)
|
||||
_C = [(35, 0), (0, 2), (70, 1), (0, 2), (50, 1), (55, 1), (50, 0), (60, 1), (0, 1)]
|
||||
H = ["ID", "股票", "市场价", "网格基准", "持仓", "成本", "排名", "状态", "操作"]
|
||||
header = []
|
||||
for h, (w, e) in zip(H, _C):
|
||||
if e > 0:
|
||||
@@ -335,6 +335,22 @@ class _GridPanel:
|
||||
header.append(ft.Container(_text(h, bold=True), width=w, padding=4))
|
||||
rows = [ft.Row(header, spacing=0), ft.Divider(height=1, color='#e0e0e0')]
|
||||
|
||||
# 获取最新评分排名
|
||||
rank_map = {} # stock_code -> score_rank
|
||||
try:
|
||||
from core.scoring.models import ScoringResult
|
||||
from peewee import fn
|
||||
latest_date = ScoringResult.select(fn.MAX(ScoringResult.trade_date)).scalar()
|
||||
if latest_date:
|
||||
scored = (ScoringResult
|
||||
.select(ScoringResult.stock_code, ScoringResult.score_rank)
|
||||
.where(ScoringResult.trade_date == latest_date)
|
||||
.dicts())
|
||||
for r in scored:
|
||||
rank_map[r['stock_code']] = r['score_rank']
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
for tid, t in self._data.tradeTargets.items():
|
||||
if t.strategy_type != STRATEGY_TYPE_GRID: continue
|
||||
pg = t.getPriceGrid()
|
||||
@@ -358,6 +374,22 @@ class _GridPanel:
|
||||
))
|
||||
gcell = ft.Row(gcells, spacing=3) if len(gcells) > 1 else gcells[0]
|
||||
|
||||
# 排名列
|
||||
plain = t.stock_code.split('.')[0] if '.' in t.stock_code else t.stock_code
|
||||
rank = rank_map.get(plain, None)
|
||||
if rank is not None and rank <= 50:
|
||||
rank_str = f'#{rank}'
|
||||
rank_color = '#4CAF50'
|
||||
elif rank is not None and rank <= 100:
|
||||
rank_str = f'#{rank}'
|
||||
rank_color = '#2196F3'
|
||||
elif rank is not None:
|
||||
rank_str = f'#{rank}'
|
||||
rank_color = '#888888'
|
||||
else:
|
||||
rank_str = '—'
|
||||
rank_color = '#888888'
|
||||
|
||||
# 操作按钮
|
||||
_ICON = 22 # 图标大小,比默认 18 好按
|
||||
if t.enabled:
|
||||
@@ -385,6 +417,7 @@ class _GridPanel:
|
||||
f'{mp:.3f}', gcell,
|
||||
str(t.current_position),
|
||||
f'{self._data.avgPrices.get(tid, 0):.3f}',
|
||||
rank_str,
|
||||
'▶运行中' if t.enabled else '⏸已暂停',
|
||||
btns]
|
||||
row_cells = []
|
||||
@@ -392,6 +425,8 @@ class _GridPanel:
|
||||
content = cells_text[i]
|
||||
if i == 2: # 市场价用颜色
|
||||
content = _text(cells_text[i], color=pcolor, bold=True)
|
||||
elif i == 6: # 排名用颜色
|
||||
content = _text(cells_text[i], color=rank_color, bold=True)
|
||||
elif isinstance(content, str):
|
||||
content = _text(content)
|
||||
elif isinstance(content, list):
|
||||
@@ -495,8 +530,25 @@ class _DrawerPanel:
|
||||
|
||||
def _refresh_grid(self):
|
||||
# (width, expand): 0=固定宽, >0=弹性比重; 股票列 expand 自动填充剩余空间
|
||||
_C = [(35, 0), (0, 1), (80, 0), (60, 0), (70, 0), (65, 0)]
|
||||
H = ["ID", "股票", "市场价", "持仓", "成本", "操作"]
|
||||
# 新增: 排名列 (50px)
|
||||
_C = [(35, 0), (0, 1), (80, 0), (60, 0), (70, 0), (50, 0), (65, 0)]
|
||||
H = ["ID", "股票", "市场价", "持仓", "成本", "排名", "操作"]
|
||||
|
||||
# 获取最新评分排名
|
||||
rank_map = {} # stock_code -> score_rank
|
||||
try:
|
||||
from core.scoring.models import ScoringResult
|
||||
from peewee import fn
|
||||
latest_date = ScoringResult.select(fn.MAX(ScoringResult.trade_date)).scalar()
|
||||
if latest_date:
|
||||
rows = (ScoringResult
|
||||
.select(ScoringResult.stock_code, ScoringResult.score_rank)
|
||||
.where(ScoringResult.trade_date == latest_date)
|
||||
.dicts())
|
||||
for r in rows:
|
||||
rank_map[r['stock_code']] = r['score_rank']
|
||||
except Exception:
|
||||
pass # 数据库未就绪时忽略
|
||||
|
||||
def _cell(text, w, e, color=None):
|
||||
if e > 0:
|
||||
@@ -509,15 +561,26 @@ class _DrawerPanel:
|
||||
for tid, t in self._data.tradeTargets.items():
|
||||
if t.strategy_type == STRATEGY_TYPE_GRID: continue
|
||||
mp = self._data.marketPrices.get(tid, 0) or 0
|
||||
plain = t.stock_code.split('.')[0] if '.' in t.stock_code else t.stock_code
|
||||
rank = rank_map.get(plain, None)
|
||||
rank_str = f"#{rank}" if rank is not None else "—"
|
||||
# 排名颜色: top50 绿色, top100 蓝色, 其他灰色
|
||||
if rank is not None and rank <= 50:
|
||||
rank_color = '#4CAF50'
|
||||
elif rank is not None and rank <= 100:
|
||||
rank_color = '#2196F3'
|
||||
else:
|
||||
rank_color = '#888888'
|
||||
cells = [
|
||||
_cell(str(tid), *_C[0]),
|
||||
_cell(f'{t.stock_code} {t.stock_name}', *_C[1]),
|
||||
_cell(f'{mp:.3f}', *_C[2]),
|
||||
_cell(str(t.current_position), *_C[3]),
|
||||
_cell(f'{self._data.avgPrices.get(tid, 0):.3f}', *_C[4]),
|
||||
_cell(rank_str, *_C[5], color=rank_color),
|
||||
ft.Container(ft.IconButton(ft.Icons.SETTINGS, icon_size=20, tooltip="网格配置",
|
||||
on_click=lambda e, tt=t: self._dialogs.open_config(tt)),
|
||||
width=_C[5][0], padding=0),
|
||||
width=_C[6][0], padding=0),
|
||||
]
|
||||
row = ft.Row(cells, spacing=0)
|
||||
rows.append(ft.Container(row, padding=ft.Padding(0, 2, 0, 2)))
|
||||
|
||||
Reference in New Issue
Block a user