MoFin 初始提交

完整数据采集+分析管道:
- market_watch.py:90行业板块采集(同花顺/东方财富)
- 市场精选推荐 cron:全市场分析+候选池+星级推荐
- price_monitor.py:持仓/自选高频价格监控
- refresh_mtf_cache.py:多周期K线缓存
- 策略评估/知识萃取管道

文档:docs/ 含完整需求+架构设计
注意:尚未配置 git remote,笑笑接手后自行配置
This commit is contained in:
知微 (MoFin)
2026-06-20 12:04:21 +08:00
commit aa0f740381
950 changed files with 189006 additions and 0 deletions
+194
View File
@@ -0,0 +1,194 @@
"""提示词注册表 — 所有提示词的CRUD和版本管理"""
import json
import shutil
from pathlib import Path
from datetime import datetime
from typing import Optional
from .models import PromptDef, PromptVersion, PROMPT_CATEGORIES
# 数据文件路径
DATA_DIR = Path("/home/hmo/projects/MoFin/data/prompts")
REGISTRY_PATH = DATA_DIR / "registry.json"
VERSIONS_DIR = DATA_DIR / "versions"
def ensure_dirs():
DATA_DIR.mkdir(parents=True, exist_ok=True)
VERSIONS_DIR.mkdir(parents=True, exist_ok=True)
def load_registry() -> dict:
"""加载注册表"""
ensure_dirs()
if not REGISTRY_PATH.exists():
return {"prompts": [], "updated_at": datetime.now().isoformat()}
try:
return json.loads(REGISTRY_PATH.read_text(encoding="utf-8"))
except (json.JSONDecodeError, FileNotFoundError):
return {"prompts": [], "updated_at": datetime.now().isoformat()}
def save_registry(data: dict):
ensure_dirs()
data["updated_at"] = datetime.now().isoformat()
REGISTRY_PATH.write_text(
json.dumps(data, ensure_ascii=False, indent=2),
encoding="utf-8",
)
# ═══════════════════════════════════════════
# CRUD
# ═══════════════════════════════════════════
def list_prompts(category: str = None) -> list:
"""列出所有提示词,可选按分类过滤"""
reg = load_registry()
prompts = []
for p in reg.get("prompts", []):
if category and p.get("category") != category:
continue
prompts.append(dict(PromptDef.from_dict(p).to_dict()))
return prompts
def get_prompt(prompt_id: str) -> Optional[PromptDef]:
"""获取单个提示词"""
reg = load_registry()
for p in reg.get("prompts", []):
if p["id"] == prompt_id:
return PromptDef.from_dict(p)
return None
def add_prompt(prompt_def: PromptDef):
"""添加新提示词"""
reg = load_registry()
# 检查是否已存在
for i, p in enumerate(reg.get("prompts", [])):
if p["id"] == prompt_def.id:
reg["prompts"][i] = prompt_def.to_dict()
break
else:
reg.setdefault("prompts", []).append(prompt_def.to_dict())
save_registry(reg)
def update_prompt(prompt_id: str, updates: dict):
"""更新提示词元数据"""
reg = load_registry()
for p in reg.get("prompts", []):
if p["id"] == prompt_id:
for k, v in updates.items():
if k not in ("id", "versions", "created_at"):
p[k] = v
break
save_registry(reg)
def delete_prompt(prompt_id: str):
"""删除提示词"""
reg = load_registry()
reg["prompts"] = [p for p in reg.get("prompts", []) if p["id"] != prompt_id]
save_registry(reg)
def get_version_content(prompt_id: str, version: str) -> Optional[str]:
"""读取版本内容文件"""
content_path = VERSIONS_DIR / f"{prompt_id}-{version}.md"
if content_path.exists():
return content_path.read_text(encoding="utf-8")
# 回退:从版本记录的 content 字段读取
prompt = get_prompt(prompt_id)
if prompt:
for v in prompt.versions:
if v.version == version:
return v.content
return None
# ═══════════════════════════════════════════
# 版本管理
# ═══════════════════════════════════════════
def add_version(prompt_id: str, version: PromptVersion):
"""添加新版本到提示词"""
prompt = get_prompt(prompt_id)
if not prompt:
raise ValueError(f"提示词 '{prompt_id}' 不存在")
# 检查版本号是否已存在
for i, v in enumerate(prompt.versions):
if v.version == version.version:
prompt.versions[i] = version
break
else:
prompt.versions.append(version)
# 保存版本内容到独立文件
content_path = VERSIONS_DIR / f"{prompt_id}-{version.version}.md"
content_path.write_text(version.content, encoding="utf-8")
# 更新 content_path 只存路径,content 字段只存摘要
version.content_path = str(content_path)
version.content = version.content[:200] + "..." if len(version.content) > 200 else version.content
# 设置当前版本
prompt.current_version = version.version
prompt.updated_at = datetime.now().isoformat()
# 保存
add_prompt(prompt)
def set_active_version(prompt_id: str, version_str: str):
"""切换当前活跃版本"""
prompt = get_prompt(prompt_id)
if not prompt:
raise ValueError(f"提示词 '{prompt_id}' 不存在")
# 验证版本存在
version_exists = any(v.version == version_str for v in prompt.versions)
if not version_exists:
raise ValueError(f"版本 '{version_str}' 不存在于 '{prompt_id}'")
# 将所有版本标记为非活跃,目标版本标记为活跃
for v in prompt.versions:
if v.version == version_str:
v.status = "active"
elif v.status == "active":
v.status = "deprecated"
prompt.current_version = version_str
prompt.updated_at = datetime.now().isoformat()
add_prompt(prompt)
# ═══════════════════════════════════════════
# 分类信息
# ═══════════════════════════════════════════
def get_categories() -> dict:
"""获取所有分类"""
return dict(PROMPT_CATEGORIES)
def get_version_history(prompt_id: str) -> list:
"""获取某个提示词的所有版本历史"""
prompt = get_prompt(prompt_id)
if not prompt:
return []
history = []
for v in prompt.versions:
history.append({
"version": v.version,
"label": v.label,
"status": v.status,
"created_at": v.created_at,
"changelog": v.changelog,
"tags": v.tags,
"is_current": v.version == prompt.current_version,
})
return sorted(history, key=lambda x: x["version"])