update
This commit is contained in:
parent
d4d5351c66
commit
15bd9d06a7
@ -24,12 +24,21 @@ def department_prompt(settings: "DepartmentSettings", context: "DepartmentContex
|
||||
market_lines = "\n".join(
|
||||
f"- {key}: {value}" for key, value in sorted(context.market_snapshot.items())
|
||||
)
|
||||
scope_lines = "\n".join(f"- {item}" for item in settings.data_scope)
|
||||
role_description = settings.description.strip()
|
||||
role_instruction = settings.prompt.strip()
|
||||
|
||||
instructions = f"""
|
||||
部门名称:{settings.title}
|
||||
股票代码:{context.ts_code}
|
||||
交易日:{context.trade_date}
|
||||
|
||||
角色说明:{role_description or '未配置,默认沿用部门名称所代表的研究职责。'}
|
||||
职责指令:{role_instruction or '在保持部门风格的前提下,结合可用数据做出审慎判断。'}
|
||||
|
||||
【可用数据范围】
|
||||
{scope_lines or '- 使用系统提供的全部上下文,必要时指出仍需的额外数据。'}
|
||||
|
||||
【核心特征】
|
||||
{feature_lines or '- (无)'}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ from dataclasses import dataclass, field
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional
|
||||
from typing import Dict, Iterable, List, Optional
|
||||
|
||||
|
||||
def _default_root() -> Path:
|
||||
@ -186,19 +186,102 @@ class DepartmentSettings:
|
||||
title: str
|
||||
description: str = ""
|
||||
weight: float = 1.0
|
||||
data_scope: List[str] = field(default_factory=list)
|
||||
prompt: str = ""
|
||||
llm: LLMConfig = field(default_factory=LLMConfig)
|
||||
|
||||
|
||||
def _default_departments() -> Dict[str, DepartmentSettings]:
|
||||
presets = [
|
||||
("momentum", "动量策略部门"),
|
||||
("value", "价值评估部门"),
|
||||
("news", "新闻情绪部门"),
|
||||
("liquidity", "流动性评估部门"),
|
||||
("macro", "宏观研究部门"),
|
||||
("risk", "风险控制部门"),
|
||||
{
|
||||
"code": "momentum",
|
||||
"title": "动量策略部门",
|
||||
"description": "跟踪价格动量与量价共振,评估短线趋势延续的概率。",
|
||||
"data_scope": [
|
||||
"daily.close",
|
||||
"daily.open",
|
||||
"daily_basic.turnover_rate",
|
||||
"factors.mom_20",
|
||||
"factors.mom_60",
|
||||
],
|
||||
"prompt": "你主导动量风格研究,关注价格与成交量的加速变化,需在保持纪律的前提下判定短期多空倾向。",
|
||||
},
|
||||
{
|
||||
"code": "value",
|
||||
"title": "价值评估部门",
|
||||
"description": "衡量估值水平与盈利质量,为中期配置提供性价比判断。",
|
||||
"data_scope": [
|
||||
"daily_basic.pe",
|
||||
"daily_basic.pb",
|
||||
"daily_basic.roe",
|
||||
"fundamental.growth",
|
||||
],
|
||||
"prompt": "你负责价值与质量评估,应结合估值分位、盈利持续性及安全边际给出配置建议。",
|
||||
},
|
||||
{
|
||||
"code": "news",
|
||||
"title": "新闻情绪部门",
|
||||
"description": "监控舆情热度与事件影响,识别情绪驱动的短期风险与机会。",
|
||||
"data_scope": [
|
||||
"news.sentiment_index",
|
||||
"news.heat_score",
|
||||
"events.latest_headlines",
|
||||
],
|
||||
"prompt": "你专注新闻和事件驱动,应评估正负面舆情对标的短线波动的可能影响。",
|
||||
},
|
||||
{
|
||||
"code": "liquidity",
|
||||
"title": "流动性评估部门",
|
||||
"description": "衡量成交活跃度与交易成本,控制进出场的实现可能性。",
|
||||
"data_scope": [
|
||||
"daily_basic.volume_ratio",
|
||||
"daily_basic.turnover_rate_f",
|
||||
"market.spread_estimate",
|
||||
],
|
||||
"prompt": "你负责评估该标的的流动性与滑点风险,需要提出可执行的仓位调整建议。",
|
||||
},
|
||||
{
|
||||
"code": "macro",
|
||||
"title": "宏观研究部门",
|
||||
"description": "追踪宏观与行业景气度,为行业配置和风险偏好提供参考。",
|
||||
"data_scope": [
|
||||
"macro.industry_heat",
|
||||
"macro.liquidity_cycle",
|
||||
"index.performance_peers",
|
||||
],
|
||||
"prompt": "你负责宏观与行业研判,应结合宏观周期、行业景气与相对强弱给出方向性意见。",
|
||||
},
|
||||
{
|
||||
"code": "risk",
|
||||
"title": "风险控制部门",
|
||||
"description": "监控极端风险、合规与交易限制,必要时行使否决。",
|
||||
"data_scope": [
|
||||
"market.limit_flags",
|
||||
"portfolio.position",
|
||||
"risk.alerts",
|
||||
],
|
||||
"prompt": "你负责风险控制,应识别停牌、涨跌停、持仓约束等因素,必要时提出减仓或观望建议。",
|
||||
},
|
||||
]
|
||||
return {code: DepartmentSettings(code=code, title=title) for code, title in presets}
|
||||
return {
|
||||
item["code"]: DepartmentSettings(
|
||||
code=item["code"],
|
||||
title=item["title"],
|
||||
description=item.get("description", ""),
|
||||
data_scope=list(item.get("data_scope", [])),
|
||||
prompt=item.get("prompt", ""),
|
||||
)
|
||||
for item in presets
|
||||
}
|
||||
|
||||
|
||||
def _normalize_data_scope(raw: object) -> List[str]:
|
||||
if isinstance(raw, str):
|
||||
tokens = raw.replace(";", "\n").replace(",", "\n").splitlines()
|
||||
return [token.strip() for token in tokens if token.strip()]
|
||||
if isinstance(raw, Iterable) and not isinstance(raw, (bytes, bytearray, str)):
|
||||
return [str(item).strip() for item in raw if str(item).strip()]
|
||||
return []
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -388,6 +471,8 @@ def _load_from_file(cfg: AppConfig) -> None:
|
||||
title = data.get("title") or code
|
||||
description = data.get("description") or ""
|
||||
weight = float(data.get("weight", 1.0))
|
||||
prompt_text = str(data.get("prompt") or "")
|
||||
data_scope = _normalize_data_scope(data.get("data_scope"))
|
||||
llm_cfg = LLMConfig()
|
||||
route_name = data.get("llm_route")
|
||||
resolved_cfg = None
|
||||
@ -420,6 +505,8 @@ def _load_from_file(cfg: AppConfig) -> None:
|
||||
title=title,
|
||||
description=description,
|
||||
weight=weight,
|
||||
data_scope=data_scope,
|
||||
prompt=prompt_text,
|
||||
llm=resolved_cfg,
|
||||
)
|
||||
if new_departments:
|
||||
@ -451,6 +538,8 @@ def save_config(cfg: AppConfig | None = None) -> None:
|
||||
"title": dept.title,
|
||||
"description": dept.description,
|
||||
"weight": dept.weight,
|
||||
"data_scope": list(dept.data_scope),
|
||||
"prompt": dept.prompt,
|
||||
"llm": {
|
||||
"strategy": dept.llm.strategy if dept.llm.strategy in ALLOWED_LLM_STRATEGIES else "single",
|
||||
"majority_threshold": dept.llm.majority_threshold,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user