|
|
|
@ -626,121 +626,126 @@ def save_plan_to_db(db: Session, plan_data: dict) -> int:
|
|
|
|
review_date_str = plan_data["review_date"]
|
|
|
|
review_date_str = plan_data["review_date"]
|
|
|
|
week_day = plan_data["week_day"]
|
|
|
|
week_day = plan_data["week_day"]
|
|
|
|
|
|
|
|
|
|
|
|
# 清理旧数据
|
|
|
|
try:
|
|
|
|
existing = db.query(ReviewPlanV2).filter_by(review_date=review_date_str).first()
|
|
|
|
# 清理旧数据
|
|
|
|
if existing:
|
|
|
|
existing = db.query(ReviewPlanV2).filter_by(review_date=review_date_str).first()
|
|
|
|
review_plan_id = existing.id
|
|
|
|
if existing:
|
|
|
|
# 清理关联数据
|
|
|
|
review_plan_id = existing.id
|
|
|
|
db.query(SymbolScoreV2).filter_by(review_date_id=review_plan_id).delete()
|
|
|
|
# 清理关联数据
|
|
|
|
db.query(TradingPlanV2).filter_by(review_date_id=review_plan_id).delete()
|
|
|
|
db.query(SymbolScoreV2).filter_by(review_date_id=review_plan_id).delete()
|
|
|
|
db.query(SectorHeat).filter_by(review_date_id=review_plan_id).delete()
|
|
|
|
db.query(TradingPlanV2).filter_by(review_date_id=review_plan_id).delete()
|
|
|
|
# 更新元数据
|
|
|
|
db.query(SectorHeat).filter_by(review_date_id=review_plan_id).delete()
|
|
|
|
existing.week_day = week_day
|
|
|
|
# 更新元数据
|
|
|
|
existing.data_basis = plan_data.get("data_basis")
|
|
|
|
existing.week_day = week_day
|
|
|
|
existing.core_conclusion = plan_data.get("core_conclusion")
|
|
|
|
existing.data_basis = plan_data.get("data_basis")
|
|
|
|
existing.bull_count = plan_data.get("bull_count")
|
|
|
|
existing.core_conclusion = plan_data.get("core_conclusion")
|
|
|
|
existing.bear_count = plan_data.get("bear_count")
|
|
|
|
existing.bull_count = plan_data.get("bull_count")
|
|
|
|
existing.neutral_count = plan_data.get("neutral_count")
|
|
|
|
existing.bear_count = plan_data.get("bear_count")
|
|
|
|
existing.opportunity_count = plan_data.get("opportunity_count")
|
|
|
|
existing.neutral_count = plan_data.get("neutral_count")
|
|
|
|
existing.risk_warnings = plan_data.get("risk_warnings")
|
|
|
|
existing.opportunity_count = plan_data.get("opportunity_count")
|
|
|
|
existing.actual_data_date = plan_data.get("actual_data_date")
|
|
|
|
existing.risk_warnings = plan_data.get("risk_warnings")
|
|
|
|
existing.data_date_matches = 1 if plan_data.get("data_date_matches") else 0
|
|
|
|
existing.actual_data_date = plan_data.get("actual_data_date")
|
|
|
|
else:
|
|
|
|
existing.data_date_matches = 1 if plan_data.get("data_date_matches") else 0
|
|
|
|
review_plan = ReviewPlanV2(
|
|
|
|
else:
|
|
|
|
review_date=review_date_str,
|
|
|
|
review_plan = ReviewPlanV2(
|
|
|
|
week_day=week_day,
|
|
|
|
review_date=review_date_str,
|
|
|
|
data_basis=plan_data.get("data_basis"),
|
|
|
|
week_day=week_day,
|
|
|
|
core_conclusion=plan_data.get("core_conclusion"),
|
|
|
|
data_basis=plan_data.get("data_basis"),
|
|
|
|
bull_count=plan_data.get("bull_count"),
|
|
|
|
core_conclusion=plan_data.get("core_conclusion"),
|
|
|
|
bear_count=plan_data.get("bear_count"),
|
|
|
|
bull_count=plan_data.get("bull_count"),
|
|
|
|
neutral_count=plan_data.get("neutral_count"),
|
|
|
|
bear_count=plan_data.get("bear_count"),
|
|
|
|
opportunity_count=plan_data.get("opportunity_count"),
|
|
|
|
neutral_count=plan_data.get("neutral_count"),
|
|
|
|
risk_warnings=plan_data.get("risk_warnings"),
|
|
|
|
opportunity_count=plan_data.get("opportunity_count"),
|
|
|
|
actual_data_date=plan_data.get("actual_data_date"),
|
|
|
|
risk_warnings=plan_data.get("risk_warnings"),
|
|
|
|
data_date_matches=1 if plan_data.get("data_date_matches") else 0,
|
|
|
|
actual_data_date=plan_data.get("actual_data_date"),
|
|
|
|
)
|
|
|
|
data_date_matches=1 if plan_data.get("data_date_matches") else 0,
|
|
|
|
db.add(review_plan)
|
|
|
|
)
|
|
|
|
db.flush()
|
|
|
|
db.add(review_plan)
|
|
|
|
review_plan_id = review_plan.id
|
|
|
|
db.flush()
|
|
|
|
|
|
|
|
review_plan_id = review_plan.id
|
|
|
|
# 保存评分数据
|
|
|
|
|
|
|
|
for s in plan_data.get("scores", []):
|
|
|
|
# 保存评分数据
|
|
|
|
pivots = s.get("pivots", {})
|
|
|
|
for s in plan_data.get("scores", []):
|
|
|
|
score_record = SymbolScoreV2(
|
|
|
|
pivots = s.get("pivots", {})
|
|
|
|
review_date_id=review_plan_id,
|
|
|
|
score_record = SymbolScoreV2(
|
|
|
|
symbol=s["symbol"],
|
|
|
|
review_date_id=review_plan_id,
|
|
|
|
name=s["name"],
|
|
|
|
symbol=s["symbol"],
|
|
|
|
close_price=s.get("close_price"),
|
|
|
|
name=s["name"],
|
|
|
|
prev_close=s.get("prev_close"),
|
|
|
|
close_price=s.get("close_price"),
|
|
|
|
high_price=s.get("high_price"),
|
|
|
|
prev_close=s.get("prev_close"),
|
|
|
|
low_price=s.get("low_price"),
|
|
|
|
high_price=s.get("high_price"),
|
|
|
|
volume=s.get("volume"),
|
|
|
|
low_price=s.get("low_price"),
|
|
|
|
avg_volume_5=s.get("avg_volume_5"),
|
|
|
|
volume=s.get("volume"),
|
|
|
|
amplitude_score=s.get("amplitude_score"),
|
|
|
|
avg_volume_5=s.get("avg_volume_5"),
|
|
|
|
volume_score=s.get("volume_score"),
|
|
|
|
amplitude_score=s.get("amplitude_score"),
|
|
|
|
change_score=s.get("change_score"),
|
|
|
|
volume_score=s.get("volume_score"),
|
|
|
|
trend_score=s.get("trend_score"),
|
|
|
|
change_score=s.get("change_score"),
|
|
|
|
activity_score=s.get("activity_score"),
|
|
|
|
trend_score=s.get("trend_score"),
|
|
|
|
composite_score=s.get("composite_score"),
|
|
|
|
activity_score=s.get("activity_score"),
|
|
|
|
amplitude_pct=s.get("amplitude_pct"),
|
|
|
|
composite_score=s.get("composite_score"),
|
|
|
|
change_pct=s.get("change_pct"),
|
|
|
|
amplitude_pct=s.get("amplitude_pct"),
|
|
|
|
volume_ratio=s.get("volume_ratio"),
|
|
|
|
change_pct=s.get("change_pct"),
|
|
|
|
trend_60m=s.get("trend_60m"),
|
|
|
|
volume_ratio=s.get("volume_ratio"),
|
|
|
|
trend_15m=s.get("trend_15m"),
|
|
|
|
trend_60m=s.get("trend_60m"),
|
|
|
|
trend_5m=s.get("trend_5m"),
|
|
|
|
trend_15m=s.get("trend_15m"),
|
|
|
|
direction=s.get("direction"),
|
|
|
|
trend_5m=s.get("trend_5m"),
|
|
|
|
direction_tag=s.get("direction_tag"),
|
|
|
|
direction=s.get("direction"),
|
|
|
|
category=s.get("category"),
|
|
|
|
direction_tag=s.get("direction_tag"),
|
|
|
|
pivot=pivots.get("pivot"),
|
|
|
|
category=s.get("category"),
|
|
|
|
r1=pivots.get("r1"),
|
|
|
|
pivot=pivots.get("pivot"),
|
|
|
|
r2=pivots.get("r2"),
|
|
|
|
r1=pivots.get("r1"),
|
|
|
|
s1=pivots.get("s1"),
|
|
|
|
r2=pivots.get("r2"),
|
|
|
|
s2=pivots.get("s2"),
|
|
|
|
s1=pivots.get("s1"),
|
|
|
|
rank=s.get("rank"),
|
|
|
|
s2=pivots.get("s2"),
|
|
|
|
data_date=s.get("data_date"),
|
|
|
|
rank=s.get("rank"),
|
|
|
|
)
|
|
|
|
data_date=s.get("data_date"),
|
|
|
|
db.add(score_record)
|
|
|
|
)
|
|
|
|
|
|
|
|
db.add(score_record)
|
|
|
|
# 保存交易计划
|
|
|
|
|
|
|
|
for p in plan_data.get("plans", []):
|
|
|
|
# 保存交易计划
|
|
|
|
plan_record = TradingPlanV2(
|
|
|
|
for p in plan_data.get("plans", []):
|
|
|
|
review_date_id=review_plan_id,
|
|
|
|
plan_record = TradingPlanV2(
|
|
|
|
symbol=p["symbol"],
|
|
|
|
review_date_id=review_plan_id,
|
|
|
|
name=p["name"],
|
|
|
|
symbol=p["symbol"],
|
|
|
|
direction=p["direction"],
|
|
|
|
name=p["name"],
|
|
|
|
composite_score=p.get("composite_score"),
|
|
|
|
direction=p["direction"],
|
|
|
|
entry_low=p.get("entry_low"),
|
|
|
|
composite_score=p.get("composite_score"),
|
|
|
|
entry_high=p.get("entry_high"),
|
|
|
|
entry_low=p.get("entry_low"),
|
|
|
|
stop_loss=p.get("stop_loss"),
|
|
|
|
entry_high=p.get("entry_high"),
|
|
|
|
target1=p.get("target1"),
|
|
|
|
stop_loss=p.get("stop_loss"),
|
|
|
|
target2=p.get("target2"),
|
|
|
|
target1=p.get("target1"),
|
|
|
|
trigger=p.get("trigger"),
|
|
|
|
target2=p.get("target2"),
|
|
|
|
amplitude_score=p.get("amplitude_score"),
|
|
|
|
trigger=p.get("trigger"),
|
|
|
|
volume_score=p.get("volume_score"),
|
|
|
|
amplitude_score=p.get("amplitude_score"),
|
|
|
|
trend_score=p.get("trend_score"),
|
|
|
|
volume_score=p.get("volume_score"),
|
|
|
|
activity_score=p.get("activity_score"),
|
|
|
|
trend_score=p.get("trend_score"),
|
|
|
|
category=p.get("category"),
|
|
|
|
activity_score=p.get("activity_score"),
|
|
|
|
)
|
|
|
|
category=p.get("category"),
|
|
|
|
db.add(plan_record)
|
|
|
|
)
|
|
|
|
|
|
|
|
db.add(plan_record)
|
|
|
|
# 保存板块热度
|
|
|
|
|
|
|
|
for sec in plan_data.get("sectors", []):
|
|
|
|
# 保存板块热度
|
|
|
|
sector_record = SectorHeat(
|
|
|
|
for sec in plan_data.get("sectors", []):
|
|
|
|
review_date_id=review_plan_id,
|
|
|
|
sector_record = SectorHeat(
|
|
|
|
sector_name=sec["sector_name"],
|
|
|
|
review_date_id=review_plan_id,
|
|
|
|
avg_score=sec.get("avg_score"),
|
|
|
|
sector_name=sec["sector_name"],
|
|
|
|
avg_trend=sec.get("avg_trend"),
|
|
|
|
avg_score=sec.get("avg_score"),
|
|
|
|
direction=sec.get("direction"),
|
|
|
|
avg_trend=sec.get("avg_trend"),
|
|
|
|
heat_level=sec.get("heat_level"),
|
|
|
|
direction=sec.get("direction"),
|
|
|
|
leader_symbol=sec.get("leader_symbol"),
|
|
|
|
heat_level=sec.get("heat_level"),
|
|
|
|
leader_score=sec.get("leader_score"),
|
|
|
|
leader_symbol=sec.get("leader_symbol"),
|
|
|
|
members=sec.get("members"),
|
|
|
|
leader_score=sec.get("leader_score"),
|
|
|
|
)
|
|
|
|
members=sec.get("members"),
|
|
|
|
db.add(sector_record)
|
|
|
|
)
|
|
|
|
|
|
|
|
db.add(sector_record)
|
|
|
|
db.commit()
|
|
|
|
|
|
|
|
logger.info(f"交易计划已保存: {review_date_str}, ID={review_plan_id}")
|
|
|
|
db.commit()
|
|
|
|
return review_plan_id
|
|
|
|
logger.info(f"交易计划已保存: {review_date_str}, ID={review_plan_id}")
|
|
|
|
|
|
|
|
return review_plan_id
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
|
|
db.rollback()
|
|
|
|
|
|
|
|
logger.exception(f"保存交易计划失败: {e}")
|
|
|
|
|
|
|
|
raise
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_plan_data(db: Session, review_plan_id: int) -> Optional[dict]:
|
|
|
|
def get_plan_data(db: Session, review_plan_id: int) -> Optional[dict]:
|
|
|
|
|