Add hub strategy calculator page with trend and roll risk-based sizing.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -702,6 +702,7 @@ def root_redirect():
|
||||
|
||||
@app.get("/monitor")
|
||||
@app.get("/plan")
|
||||
@app.get("/calculator")
|
||||
@app.get("/market")
|
||||
@app.get("/archive")
|
||||
@app.get("/dashboard")
|
||||
@@ -793,6 +794,7 @@ class SettingsDisplayBody(BaseModel):
|
||||
show_nav_plan: bool = True
|
||||
show_nav_archive: bool = True
|
||||
show_nav_ai: bool = True
|
||||
show_nav_calculator: bool = True
|
||||
|
||||
|
||||
class SettingsBody(BaseModel):
|
||||
@@ -819,6 +821,72 @@ def api_save_settings(body: SettingsBody):
|
||||
return {"ok": True, "settings": load_settings()}
|
||||
|
||||
|
||||
class TrendCalculatorBody(BaseModel):
|
||||
direction: str = "long"
|
||||
capital_usdt: float = Field(gt=0)
|
||||
risk_percent: float = Field(gt=0, le=100)
|
||||
leverage: int = Field(ge=1, le=125)
|
||||
entry_price: float = Field(gt=0)
|
||||
stop_loss: float = Field(gt=0)
|
||||
add_upper: float = Field(gt=0)
|
||||
take_profit: float = Field(gt=0)
|
||||
dca_legs: int = Field(default=5, ge=1, le=20)
|
||||
contract_size: float = Field(default=1.0, gt=0)
|
||||
|
||||
|
||||
class RollCalculatorBody(BaseModel):
|
||||
direction: str = "long"
|
||||
capital_usdt: float = Field(gt=0)
|
||||
risk_percent: float = Field(gt=0, le=100)
|
||||
qty_existing: float = Field(gt=0)
|
||||
entry_existing: float = Field(gt=0)
|
||||
take_profit: float = Field(gt=0)
|
||||
add_price: float = Field(gt=0)
|
||||
new_stop_loss: float = Field(gt=0)
|
||||
legs_done: int = Field(default=0, ge=0, le=10)
|
||||
|
||||
|
||||
@app.post("/api/calculator/trend")
|
||||
def api_calculator_trend(body: TrendCalculatorBody):
|
||||
from hub_calculator_lib import calc_trend_calculator
|
||||
|
||||
data, err = calc_trend_calculator(
|
||||
direction=body.direction,
|
||||
capital_usdt=body.capital_usdt,
|
||||
risk_percent=body.risk_percent,
|
||||
leverage=body.leverage,
|
||||
entry_price=body.entry_price,
|
||||
stop_loss=body.stop_loss,
|
||||
add_upper=body.add_upper,
|
||||
take_profit=body.take_profit,
|
||||
dca_legs=body.dca_legs,
|
||||
contract_size=body.contract_size,
|
||||
)
|
||||
if err:
|
||||
return JSONResponse({"ok": False, "msg": err}, status_code=400)
|
||||
return {"ok": True, "data": data}
|
||||
|
||||
|
||||
@app.post("/api/calculator/roll")
|
||||
def api_calculator_roll(body: RollCalculatorBody):
|
||||
from hub_calculator_lib import calc_roll_calculator
|
||||
|
||||
data, err = calc_roll_calculator(
|
||||
direction=body.direction,
|
||||
capital_usdt=body.capital_usdt,
|
||||
risk_percent=body.risk_percent,
|
||||
qty_existing=body.qty_existing,
|
||||
entry_existing=body.entry_existing,
|
||||
take_profit=body.take_profit,
|
||||
add_price=body.add_price,
|
||||
new_stop_loss=body.new_stop_loss,
|
||||
legs_done=body.legs_done,
|
||||
)
|
||||
if err:
|
||||
return JSONResponse({"ok": False, "msg": err}, status_code=400)
|
||||
return {"ok": True, "data": data}
|
||||
|
||||
|
||||
def _find_exchange_by_key(exchange_key: str) -> dict | None:
|
||||
key = (exchange_key or "").strip().lower()
|
||||
if not key:
|
||||
|
||||
Reference in New Issue
Block a user