File size: 2,356 Bytes
6ca1e7a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
from __future__ import annotations
from typing import Any, Optional, Literal
from pydantic import BaseModel, Field

Decision = Literal["BUY", "SELL", "WAIT"]
Mode = Literal["demo", "live"]
Side = Literal["BUY", "SELL"]


class Candle(BaseModel):
    epoch: int
    open: float
    high: float
    low: float
    close: float
    volume: float = 0.0


class FVG(BaseModel):
    kind: Literal["bullish", "bearish"]
    top: float
    bottom: float
    index: int          # index of middle candle in series
    filled: bool = False


class OrderBlock(BaseModel):
    kind: Literal["bullish", "bearish"]
    top: float
    bottom: float
    index: int          # index of OB candle
    fvg_index: int      # the FVG this OB anchors
    mitigated: bool = False


class StrategySignal(BaseModel):
    symbol: str
    timeframe: str
    decision: Decision
    confidence: float = Field(ge=0, le=1)
    price: float
    entry: Optional[float] = None
    sl: Optional[float] = None
    tp: Optional[float] = None
    ob: Optional[OrderBlock] = None
    fvg: Optional[FVG] = None
    rationale: str
    indicators: dict[str, Any] = {}


class PredictRequest(BaseModel):
    symbol: str = "R_10"
    timeframe: str = "1m"
    lookback: int = 200


class ReasonRequest(BaseModel):
    symbol: str
    timeframe: str = "1m"
    indicators: dict[str, Any]
    prediction: dict[str, Any]
    market_state: dict[str, Any] = {}


class ReasonResponse(BaseModel):
    decision: Decision
    confidence: float
    risk_score: float
    success_probability: float
    reasoning: str
    trade_plan: dict[str, Any]


class PaperTradeRequest(BaseModel):
    symbol: str
    side: Side
    size: float
    entry: Optional[float] = None
    sl: Optional[float] = None
    tp: Optional[float] = None
    prediction_id: Optional[str] = None


class TradeRequest(PaperTradeRequest):
    pass


class TradeResponse(BaseModel):
    ok: bool
    trade_id: Optional[str] = None
    contract_id: Optional[str] = None
    message: str
    pnl: Optional[float] = None


class FeedbackRequest(BaseModel):
    prediction_id: str
    rating: int = Field(ge=1, le=5)
    comment: Optional[str] = None


class RetrainRequest(BaseModel):
    model_name: str
    reason: Optional[str] = None