Status when starting a new project on Chat GPT

This commit is contained in:
DaM
2026-03-01 16:50:15 +01:00
parent 547a909965
commit 2ec51d0daa
10 changed files with 1232 additions and 510 deletions

View File

@@ -10,6 +10,7 @@ from fastapi import APIRouter, Depends, HTTPException, Request
from fastapi.responses import JSONResponse, HTMLResponse
from src.data.storage import StorageManager
from src.strategies.registry import STRATEGY_REGISTRY
from src.calibration.strategies_inspector import (
inspect_strategies_config,
list_available_strategies,
@@ -37,22 +38,40 @@ def get_storage() -> StorageManager:
@router.get("/catalog")
def strategy_catalog():
strategies = list_available_strategies()
# Añadimos defaults sugeridos
for s in strategies:
s["parameters_meta"] = [
{
"name": p,
"type": "int",
"default_min": 10,
"default_max": 50,
"default_step": 10,
}
for p in s["params"]
]
enriched = []
for s in strategies:
strategy_id = s["strategy_id"]
strategy_class = STRATEGY_REGISTRY[strategy_id]
schema = strategy_class.parameters_schema()
parameters_meta = []
for name, meta in schema.items():
parameters_meta.append({
"name": name,
"type": meta.get("type"),
"default_value": meta.get("default"),
"choices": meta.get("choices"),
"min": meta.get("min"),
"max": meta.get("max"),
})
enriched.append({
"strategy_id": strategy_id,
"name": s["name"],
"params": list(schema.keys()),
"parameters_meta": parameters_meta,
})
return {"strategies": enriched}
return {"strategies": strategies}
@router.post("/inspect", response_model=CalibrationStrategiesInspectResponse)
def inspect_strategies(
@@ -147,9 +166,9 @@ def report_strategies(
"WF train_days": payload.wf.train_days,
"WF test_days": payload.wf.test_days,
"WF step_days": payload.wf.step_days or payload.wf.test_days,
"Optimizer metric": payload.optimization.optimizer_metric,
"Max combinations": payload.optimization.max_combinations,
"Min trades per window (test)": payload.wf.min_trades_test,
},
results=result,
)

View File

@@ -1,33 +1,24 @@
# src/web/api/v2/schemas/calibration_strategies.py
from typing import Any, Dict, List, Literal, Optional
from typing import Any, Dict, List, Literal, Optional, Union
from pydantic import BaseModel, Field
from .calibration_risk import StopConfigSchema, RiskConfigSchema, GlobalRiskRulesSchema
ParameterValue = Union[int, float, bool, str]
class WalkForwardConfigSchema(BaseModel):
train_days: int = Field(..., gt=0)
test_days: int = Field(..., gt=0)
step_days: Optional[int] = Field(None, gt=0) # if None => step = test_days
class OptimizationConfigSchema(BaseModel):
optimizer_metric: str = Field("sharpe_ratio")
max_combinations: int = Field(500, gt=0)
min_trades_train: int = Field(30, ge=0)
step_days: Optional[int] = Field(None, gt=0)
min_trades_test: int = Field(10, ge=0)
class ParameterRangeSchema(BaseModel):
min: float
max: float
step: float
class StrategySelectionSchema(BaseModel):
strategy_id: str
parameters: Dict[str, ParameterRangeSchema]
parameters: Dict[str, ParameterValue]
class CalibrationStrategiesInspectRequest(BaseModel):
@@ -42,7 +33,6 @@ class CalibrationStrategiesInspectRequest(BaseModel):
strategies: List[StrategySelectionSchema]
wf: WalkForwardConfigSchema
optimization: OptimizationConfigSchema
commission: float = Field(0.001, ge=0)
slippage: float = Field(0.0005, ge=0)

File diff suppressed because it is too large Load Diff

View File

@@ -187,7 +187,7 @@
<!-- ========================= -->
<div class="card mb-4">
<div class="card-header">
<h3 class="card-title">Walk-Forward & Optimization</h3>
<h3 class="card-title">Walk-Forward Validation (OOS)</h3>
</div>
<div class="card-body">
<div class="row g-3">
@@ -203,26 +203,10 @@
<label class="form-label">Step days (optional)</label>
<input id="wf_step_days" class="form-control" type="number" step="1" value="">
</div>
<div class="col-md-3">
<label class="form-label">Metric</label>
<select id="opt_metric" class="form-select">
<option value="sharpe_ratio">sharpe_ratio</option>
<option value="total_return">total_return</option>
<option value="max_drawdown">max_drawdown</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label">Max combinations</label>
<input id="opt_max_combinations" class="form-control" type="number" step="1" value="300">
</div>
<div class="col-md-3">
<label class="form-label">Min trades (train)</label>
<input id="opt_min_trades_train" class="form-control" type="number" step="1" value="30">
</div>
<div class="col-md-3">
<label class="form-label">Min trades (test)</label>
<input id="opt_min_trades_test" class="form-control" type="number" step="1" value="10">
<label class="form-label">Min trades per window (test)</label>
<input id="wf_min_trades_test" class="form-control" type="number" step="1" value="10">
</div>
<div class="col-md-3">
@@ -262,7 +246,7 @@
</small>
</div>
<div class="mt-3 text-secondary">
Cada estrategia incluye un <b>param_grid</b> en JSON.
Cada estrategia utiliza parámetros fijos (validación OOS sin grid).
</div>
</div>
</div>

View File

@@ -0,0 +1,366 @@
{% extends "layout.html" %}
{% block content %}
<div class="container-xl">
<!-- ========================= -->
<!-- Wizard header -->
<!-- ========================= -->
<div class="d-flex align-items-center mb-4">
<!-- Back arrow -->
<div class="me-3">
<a href="/calibration/risk" class="btn btn-outline-secondary btn-icon">
<svg xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-arrow-left"
width="24" height="24" viewBox="0 0 24 24"
stroke-width="2" stroke="currentColor"
fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z"/>
<path d="M15 6l-6 6l6 6"/>
</svg>
</a>
</div>
<div class="flex-grow-1 text-center">
<h2 class="mb-0">Calibración · Paso 3 · Strategies</h2>
<div class="text-secondary">Optimización + Walk Forward (OOS)</div>
</div>
<!-- Forward arrow (disabled until OK) -->
<div class="ms-3">
<a
id="next-step-btn"
href="#"
class="btn btn-outline-secondary btn-icon"
aria-disabled="true"
title="Next step not implemented yet"
>
<svg xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-arrow-right"
width="24" height="24" viewBox="0 0 24 24"
stroke-width="2" stroke="currentColor"
fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z"/>
<path d="M9 6l6 6l-6 6"/>
</svg>
</a>
</div>
</div>
<!-- ========================= -->
<!-- Context -->
<!-- ========================= -->
<div class="card mb-4">
<div class="card-header">
<h3 class="card-title">Context</h3>
</div>
<div class="card-body">
<div class="row g-3">
<div class="col-md-4">
<label class="form-label">Symbol</label>
<input id="symbol" class="form-control" placeholder="BTC/USDT">
</div>
<div class="col-md-4">
<label class="form-label">Timeframe</label>
<input id="timeframe" class="form-control" placeholder="1h">
</div>
<div class="col-md-4">
<label class="form-label">Account equity</label>
<input id="account_equity" class="form-control" type="number" step="0.01" value="10000">
</div>
</div>
<div class="mt-3 text-secondary">
Tip: Symbol y timeframe se cargan desde Step 1 (localStorage). Si no aparecen, rellénalos manualmente.
</div>
</div>
</div>
<!-- ========================= -->
<!-- Risk & Stops -->
<!-- ========================= -->
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<h3 class="card-title mb-0">Risk & Stops(Step 2)</h3>
<div class="form-check form-switch m-0">
<input class="form-check-input" type="checkbox" id="lock_inherited" checked>
<label class="form-check-label" for="lock_inherited">
Bloquear parámetros heredados
</label>
</div>
</div>
<div class="card-body">
<!-- ================= -->
<!-- Risk Configuration -->
<!-- ================= -->
<h4 class="mb-3">Risk Configuration</h4>
<div class="row g-3 mb-4">
<div class="col-md-4">
<label class="form-label">Risk per Trade (%)</label>
<input id="risk_fraction" class="form-control inherited-field" type="number" step="0.01">
</div>
<div class="col-md-4">
<label class="form-label">Max Position Size (%)</label>
<input id="max_position_fraction" class="form-control inherited-field" type="number" step="0.1">
</div>
</div>
<!-- ================= -->
<!-- Stop Configuration -->
<!-- ================= -->
<h4 class="mb-3">Stop Configuration</h4>
<div class="row g-3 mb-4">
<div class="col-md-4">
<label class="form-label">Stop Type</label>
<select id="stop_type" class="form-select inherited-field">
<option value="fixed">fixed</option>
<option value="trailing">trailing</option>
<option value="atr">atr</option>
</select>
</div>
<div id="stop_fraction_group" class="col-md-4">
<label class="form-label">Stop fraction (%)</label>
<input id="stop_fraction" class="form-control inherited-field" type="number" step="0.01">
</div>
<div id="atr_group" class="col-md-4 d-none">
<label class="form-label">ATR period</label>
<input id="atr_period" class="form-control inherited-field" type="number">
</div>
<div id="atr_multiplier_group" class="col-md-4 d-none">
<label class="form-label">ATR multiplier</label>
<input id="atr_multiplier" class="form-control inherited-field" type="number" step="0.1">
</div>
</div>
<!-- ================= -->
<!-- Global Rules -->
<!-- ================= -->
<h4 class="mb-3">Global Rules</h4>
<div class="row g-3 mb-4">
<div class="col-md-4">
<label class="form-label">Max Drawdown (%)</label>
<input id="max_drawdown_pct" class="form-control inherited-field" type="number" step="0.1">
</div>
</div>
<!-- ================= -->
<!-- Optional Parameters -->
<!-- ================= -->
<h4 class="mb-3">Optional Parameters</h4>
<div class="row g-3">
<div class="col-md-4">
<label class="form-label">Daily loss limit (%)</label>
<input id="daily_loss_limit_pct" class="form-control optional-field" type="number" step="0.1">
</div>
<div class="col-md-4">
<label class="form-label">Max consecutive losses</label>
<input id="max_consecutive_losses" class="form-control optional-field" type="number">
</div>
<div class="col-md-4">
<label class="form-label">Cooldown bars</label>
<input id="cooldown_bars" class="form-control optional-field" type="number">
</div>
</div>
</div>
</div>
<!-- ========================= -->
<!-- WF + Optimizer config -->
<!-- ========================= -->
<div class="card mb-4">
<div class="card-header">
<h3 class="card-title">Walk-Forward & Optimization</h3>
</div>
<div class="card-body">
<div class="row g-3">
<div class="col-md-3">
<label class="form-label">Train days</label>
<input id="wf_train_days" class="form-control" type="number" step="1" value="120">
</div>
<div class="col-md-3">
<label class="form-label">Test days</label>
<input id="wf_test_days" class="form-control" type="number" step="1" value="30">
</div>
<div class="col-md-3">
<label class="form-label">Step days (optional)</label>
<input id="wf_step_days" class="form-control" type="number" step="1" value="">
</div>
<div class="col-md-3">
<label class="form-label">Metric</label>
<select id="opt_metric" class="form-select">
<option value="sharpe_ratio">sharpe_ratio</option>
<option value="total_return">total_return</option>
<option value="max_drawdown">max_drawdown</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label">Max combinations</label>
<input id="opt_max_combinations" class="form-control" type="number" step="1" value="300">
</div>
<div class="col-md-3">
<label class="form-label">Min trades (train)</label>
<input id="opt_min_trades_train" class="form-control" type="number" step="1" value="30">
</div>
<div class="col-md-3">
<label class="form-label">Min trades (test)</label>
<input id="opt_min_trades_test" class="form-control" type="number" step="1" value="10">
</div>
<div class="col-md-3">
<label class="form-label">Commission</label>
<input id="commission" class="form-control" type="number" step="0.0001" value="0.001">
</div>
<div class="col-md-3">
<label class="form-label">Slippage</label>
<input id="slippage" class="form-control" type="number" step="0.0001" value="0.0005">
</div>
</div>
</div>
</div>
<!-- ========================= -->
<!-- Strategy selection -->
<!-- ========================= -->
<div class="card mb-4">
<div class="card-header">
<h3 class="card-title">Strategies</h3>
<div class="card-actions">
<button id="refresh_strategies_btn" class="btn btn-sm btn-outline-secondary">Refresh</button>
</div>
</div>
<div class="card-body">
<div id="strategies_container" class="d-flex flex-column gap-4"></div>
<div class="card p-3">
<div class="d-flex justify-content-between">
<strong>Total combinations</strong>
<span id="combination_counter">0</span>
</div>
</div>
<div class="mt-2 text-end">
<small class="text-muted">
Estimated WF time:
<span id="wf_time_estimate">~ 0 sec</span>
</small>
</div>
<div class="mt-3 text-secondary">
Cada estrategia incluye un <b>param_grid</b> en JSON.
</div>
</div>
</div>
<!-- ========================= -->
<!-- Actions -->
<!-- ========================= -->
<div class="d-flex gap-2 mb-4">
<button id="validate_strategies_btn" class="btn btn-primary">
Validate (WF)
</button>
<button id="report_strategies_btn" class="btn btn-outline-primary">
Generate PDF report
</button>
</div>
<!-- ========================= -->
<!-- Prograss Bar -->
<!-- ========================= -->
<div id="wf_progress_card" class="card mb-4">
<div class="card-header">
<h3 class="card-title">Walk-Forward Progress</h3>
</div>
<div class="card-body">
<div class="progress mb-2">
<div
id="wfProgressBar"
class="progress-bar progress-bar-striped progress-bar-animated"
role="progressbar"
style="width: 0%"
>
0%
</div>
</div>
<div id="wf_progress_text" class="text-secondary small">
Waiting to start...
</div>
</div>
</div>
<!-- ========================= -->
<!-- Results -->
<!-- ========================= -->
<div class="card mb-4">
<div class="card-header">
<h3 class="card-title">Results</h3>
<div class="card-actions">
<span id="strategies_status_badge" class="badge bg-secondary">—</span>
</div>
</div>
<div class="card-body">
<div id="strategies_message" class="mb-3 text-secondary">Run validation to see results.</div>
<div class="row g-3">
<div class="col-md-4">
<label class="form-label">Strategy plot</label>
<select id="plot_strategy_select" class="form-select"></select>
</div>
</div>
<div class="mt-3">
<div id="plot_equity" style="height: 320px;"></div>
</div>
<div class="mt-3">
<div id="plot_returns" style="height: 320px;"></div>
</div>
<hr class="my-4">
<div id="strategies_table_wrap"></div>
<details class="mt-3">
<summary class="text-secondary">Debug JSON</summary>
<pre id="strategies_debug" class="mt-2" style="max-height: 300px; overflow:auto;"></pre>
</details>
</div>
</div>
<!-- ========================= -->
<!-- PDF Viewer -->
<!-- ========================= -->
<div id="pdf_viewer_section" class="card mb-4 d-none">
<div class="card-header">
<h3 class="card-title">Strategies Report (PDF)</h3>
<div class="card-actions">
<button id="close_pdf_btn" class="btn btn-sm btn-outline-secondary">Close</button>
</div>
</div>
<div class="card-body">
<iframe id="pdf_frame" style="width: 100%; height: 800px; border: none;"></iframe>
</div>
</div>
</div>
<script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
<script src="/static/js/pages/calibration_strategies.js"></script>
{% endblock %}