Files
atm-backtesting/scripts/manual_log.py

135 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Helper for manual M2D trade entry — derives full M2DExtraction dict from minimal user inputs.
User provides 6 required fields: data, ora_ro, directie, entry, sl, outcome_path.
All other fields default or are computed:
- tp0 = entry ± 0.4 × |entry - sl|
- tp1 = entry ± 0.6 × |entry - sl|
- tp2 = entry ± 1.0 × |entry - sl| (symmetric with sl)
- risc_pct = 100 × |entry - sl| / entry
- ora_utc = ora_ro converted via Europe/Bucharest (DST-aware)
- max_reached derived from outcome_path
- be_moved = True if outcome contains TP0 else False
- tf_mare/tf_mic default 5min/1min
- calitate default 'n/a'
- confidence = 'high' (manual entry)
- screenshot_file generated if not provided: <data>-<instrument>-<ora_ro>.png
"""
from __future__ import annotations
from datetime import date, datetime, time
from typing import Literal
from zoneinfo import ZoneInfo
RO_TZ = ZoneInfo("Europe/Bucharest")
UTC_TZ = ZoneInfo("UTC")
OUTCOME_TO_MAX_REACHED = {
"SL": "SL_first",
"TP0→SL": "TP0",
"TP0→TP1": "TP1",
"TP0→TP2": "TP2",
"TP0→pending": "TP0",
"pending": "SL_first", # placeholder; user can override
}
OUTCOME_TO_BE_MOVED = {
"SL": False,
"TP0→SL": True, # BE move should have happened; True = rule-enforced
"TP0→TP1": True,
"TP0→TP2": True,
"TP0→pending": True,
"pending": False,
}
def ro_to_utc(data_iso: str, ora_ro_str: str) -> str:
"""Convert (YYYY-MM-DD, HH:MM RO) -> HH:MM UTC string, DST-aware."""
d = date.fromisoformat(data_iso)
t = datetime.strptime(ora_ro_str, "%H:%M").time()
dt_ro = datetime.combine(d, t, tzinfo=RO_TZ)
dt_utc = dt_ro.astimezone(UTC_TZ)
return dt_utc.strftime("%H:%M")
def build_extraction(
data: str,
ora_ro: str,
directie: Literal["Buy", "Sell"],
entry: float,
sl: float,
outcome_path: Literal["SL", "TP0→SL", "TP0→TP1", "TP0→TP2", "TP0→pending", "pending"],
instrument: Literal["DIA", "US30", "other"] = "DIA",
tf_mare: Literal["5min", "15min"] = "5min",
tf_mic: Literal["1min", "3min"] = "1min",
calitate: Literal["Clară", "Mai mare ca impuls", "Slabă", "n/a"] = "n/a",
max_reached: Literal["SL_first", "TP0", "TP1", "TP2"] | None = None,
be_moved: bool | None = None,
screenshot_file: str | None = None,
note: str = "",
) -> dict:
"""Build a M2DExtraction-compatible dict from minimal manual inputs.
Derived fields:
- ora_utc from ora_ro (DST-aware)
- tp0/tp1/tp2 from entry/sl geometry
- risc_pct from |entry-sl|/entry
- max_reached/be_moved from outcome_path (overridable)
- screenshot_file generated from data+instrument+ora_ro if not provided
The returned dict satisfies scripts.vision_schema.M2DExtraction.
"""
if entry == sl:
raise ValueError("entry == sl — zero risk distance")
risk_abs = abs(entry - sl)
risc_pct = round(100 * risk_abs / entry, 4)
if directie == "Buy":
if sl >= entry:
raise ValueError(f"Buy: sl ({sl}) must be < entry ({entry})")
tp0 = round(entry + 0.4 * risk_abs, 4)
tp1 = round(entry + 0.6 * risk_abs, 4)
tp2 = round(entry + risk_abs, 4)
else: # Sell
if sl <= entry:
raise ValueError(f"Sell: sl ({sl}) must be > entry ({entry})")
tp0 = round(entry - 0.4 * risk_abs, 4)
tp1 = round(entry - 0.6 * risk_abs, 4)
tp2 = round(entry - risk_abs, 4)
ora_utc = ro_to_utc(data, ora_ro)
if max_reached is None:
max_reached = OUTCOME_TO_MAX_REACHED[outcome_path]
if be_moved is None:
be_moved = OUTCOME_TO_BE_MOVED[outcome_path]
if screenshot_file is None:
ora_compact = ora_ro.replace(":", "")
screenshot_file = f"{data}-{instrument.lower()}-{ora_compact}.png"
return {
"screenshot_file": screenshot_file,
"data": data,
"ora_utc": ora_utc,
"instrument": instrument,
"directie": directie,
"tf_mare": tf_mare,
"tf_mic": tf_mic,
"calitate": calitate,
"entry": round(float(entry), 4),
"sl": round(float(sl), 4),
"tp0": tp0,
"tp1": tp1,
"tp2": tp2,
"risc_pct": risc_pct,
"outcome_path": outcome_path,
"max_reached": max_reached,
"be_moved": be_moved,
"confidence": "high",
"ambiguities": [],
"note": note,
}