Replace amp-stats straddle/perp overlays with move-points amplitude ratio.

Input points now drives amplitude hit share; table keeps both-side moves and amp达标.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-28 14:56:48 +08:00
parent 90be23e845
commit c81ba147cc
6 changed files with 885 additions and 1768 deletions
+12 -68
View File
@@ -12,33 +12,20 @@ from lib.hub.amp_stats_lib import (
build_export_csv,
compute_amp_stats,
export_filename,
normalize_straddle_premium,
normalize_take_profit,
normalize_move_points,
normalize_weekend_filter,
reframe_amp_stats,
rows_page,
)
class PerpHedgeBody(BaseModel):
spot: Optional[float] = None
target_profit_u: Optional[float] = None
perp_leverage: Optional[float] = None
option_leverage: Optional[float] = None
ratio_perp: float = 1.0
ratio_opt: float = 2.0
ct_mult: float = 0.01
class ComputeBody(BaseModel):
symbol: str = "eth"
start_hour: int = 16
period: str = "2m"
custom_days: Optional[int] = None
straddle_premium: Optional[float] = None
take_profit: Optional[float] = None
move_points: Optional[float] = None
weekend_filter: str = "all"
perp_hedge: Optional[PerpHedgeBody] = None
page: int = 1
page_size: int = 20
@@ -48,29 +35,21 @@ class SaveBody(BaseModel):
class ReframeBody(BaseModel):
"""已有日表上改周末/权利金/止盈/永期参数(不拉 K 线)."""
"""已有日表上改周末/波动点数(不拉 K 线)."""
rows_all: list[dict[str, Any]] = Field(default_factory=list)
symbol: str = "eth"
start_hour: int = 16
period: str = "2m"
sample_days: int = 60
straddle_premium: Optional[float] = None
take_profit: Optional[float] = None
move_points: Optional[float] = None
weekend_filter: str = "all"
perp_hedge: Optional[PerpHedgeBody] = None
price_source: str = ""
inst_id: str = ""
page: int = 1
page_size: int = 20
def _hedge_dict(body_hedge: Optional[PerpHedgeBody]) -> Optional[dict[str, Any]]:
if body_hedge is None:
return None
return body_hedge.model_dump()
def create_amp_stats_router() -> APIRouter:
router = APIRouter(prefix="/api/amp-stats", tags=["amp-stats"])
@@ -102,12 +81,7 @@ def create_amp_stats_router() -> APIRouter:
"default_weekend_filter": "all",
"timeframe": "1H",
"metric_note": "振幅与距离均为点数:振幅=最高-最低=(开→高)+(开→低)",
"straddle_note": "买跨:越过权利金用>;止盈≥触达用止盈点否则|涨跌|;收益=有效波动-权利金",
"perp_hedge_note": "永期对冲:永续多1币+买期权;入场按日开盘;比例默认1:2;与买跨二选一对照",
"overlay_modes": [
{"key": "straddle", "label": "买跨双边"},
{"key": "perp", "label": "永期对冲"},
],
"move_points_note": "填波动点数后统计振幅≥该点数的天数占比;日表显示开→高/开→低两边点数与振幅是否达标",
}
@router.post("/compute")
@@ -118,10 +92,8 @@ def create_amp_stats_router() -> APIRouter:
start_hour=body.start_hour,
period=body.period,
custom_days=body.custom_days,
straddle_premium=body.straddle_premium,
take_profit=body.take_profit,
move_points=body.move_points,
weekend_filter=body.weekend_filter,
perp_hedge=_hedge_dict(body.perp_hedge),
)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
@@ -146,10 +118,8 @@ def create_amp_stats_router() -> APIRouter:
start_hour=body.start_hour,
period=body.period,
sample_days=body.sample_days,
straddle_premium=body.straddle_premium,
take_profit=body.take_profit,
move_points=body.move_points,
weekend_filter=body.weekend_filter,
perp_hedge=_hedge_dict(body.perp_hedge),
price_source=body.price_source,
inst_id=body.inst_id,
)
@@ -190,33 +160,15 @@ def create_amp_stats_router() -> APIRouter:
start_hour: int = Query(default=16),
period: str = Query(default="2m"),
custom_days: Optional[int] = Query(default=None),
straddle_premium: Optional[float] = Query(default=None),
take_profit: Optional[float] = Query(default=None),
move_points: Optional[float] = Query(default=None),
weekend_filter: str = Query(default="all"),
hedge_spot: Optional[float] = Query(default=None),
hedge_target: Optional[float] = Query(default=None),
hedge_perp_lev: Optional[float] = Query(default=None),
hedge_opt_lev: Optional[float] = Query(default=None),
hedge_ratio_perp: float = Query(default=1.0),
hedge_ratio_opt: float = Query(default=2.0),
hedge_ct_mult: float = Query(default=0.01),
):
hedge_q = {
"target_profit_u": hedge_target,
"perp_leverage": hedge_perp_lev,
"option_leverage": hedge_opt_lev,
"ratio_perp": hedge_ratio_perp,
"ratio_opt": hedge_ratio_opt,
"ct_mult": hedge_ct_mult,
}
hedge_q_ready = hedge_target is not None and hedge_perp_lev is not None and hedge_opt_lev is not None
if (history_id or "").strip():
item = get_history(history_id.strip())
if not item:
raise HTTPException(status_code=404, detail="历史不存在")
rows_all = item.get("rows_all") or item.get("rows") or []
item_hedge = item.get("perp_hedge") if isinstance(item.get("perp_hedge"), dict) else None
use_hedge = hedge_q if hedge_q_ready else item_hedge
use_mp = move_points if move_points is not None else item.get("move_points")
try:
payload = reframe_amp_stats(
rows_all=rows_all,
@@ -224,12 +176,8 @@ def create_amp_stats_router() -> APIRouter:
start_hour=int(item.get("start_hour") if item.get("start_hour") is not None else start_hour),
period=str(item.get("period") or period),
sample_days=int(item.get("sample_days_requested") or 60),
straddle_premium=straddle_premium
if straddle_premium is not None
else item.get("straddle_premium"),
take_profit=take_profit if take_profit is not None else item.get("take_profit"),
move_points=use_mp,
weekend_filter=weekend_filter or item.get("weekend_filter") or "all",
perp_hedge=use_hedge,
price_source=str(item.get("price_source") or ""),
inst_id=str(item.get("inst_id") or ""),
missing=item.get("missing_days") or [],
@@ -238,19 +186,15 @@ def create_amp_stats_router() -> APIRouter:
raise HTTPException(status_code=400, detail=str(exc)) from exc
else:
try:
# validate enums early
normalize_weekend_filter(weekend_filter)
normalize_straddle_premium(straddle_premium)
normalize_take_profit(take_profit)
normalize_move_points(move_points)
payload = compute_amp_stats(
symbol=symbol,
start_hour=start_hour,
period=period,
custom_days=custom_days,
straddle_premium=straddle_premium,
take_profit=take_profit,
move_points=move_points,
weekend_filter=weekend_filter,
perp_hedge=hedge_q if hedge_q_ready else None,
)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc