Trade-Leiste: Laufzeit-Uhr des offenen Trades (v=118)
- trader: open_time (echte Epoch, Broker-Offset korrigiert) aus position.time, im Snapshot; nur 1x je Position berechnet, beim Close auf 0. - _broker_offset_s(sym=None): Symbol explizit uebergebbar -- beim Adoptieren ist self.symbol noch nicht gesetzt (war Offset 0 -> Zeit 3h in der Zukunft); zusaetzlich Selbstheilung bei Zukunftswerten. - app.js/index.html/style.css: Feld #tb-dur + Titel-Uhr #tb-runtime, eigener 1-s-Ticker (flüssig zwischen Snapshots), ab 2h bernstein (Time-Stop-Naehe). - Verifiziert: Live-Trade 48898382 open_time == Log-Zeile 13:22:48. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
e9653a842a
commit
919ed7c3ee
+29
@@ -50,6 +50,30 @@ function beepCloseAlert() {
|
||||
// der Button blinkt (Empfehlung aktiv & flat) — einmaliger Piep war überhörbar.
|
||||
const _REC_REBEEP_MS = 30000;
|
||||
let _lastRecBeep = 0, _lastRecSignal = null, _audioHintShown = false, _lastSrCloseCount = null;
|
||||
|
||||
// ── Laufzeit-Uhr des offenen Trades ───────────────────────────────────────────
|
||||
// Öffnungszeit kommt als echte Epoch (Broker-Offset serverseitig korrigiert) im
|
||||
// Snapshot (`position.open_time`); der Ticker läuft eigenständig jede Sekunde,
|
||||
// damit die Uhr auch zwischen den Snapshots (4 s Poll / 1 s WS) flüssig zählt.
|
||||
let _tradeOpenTime = 0;
|
||||
function _fmtDuration(sec) {
|
||||
sec = Math.max(0, Math.floor(sec));
|
||||
const h = Math.floor(sec / 3600), m = Math.floor((sec % 3600) / 60), s = sec % 60;
|
||||
const p2 = (n) => String(n).padStart(2, "0");
|
||||
return h > 0 ? `${h}:${p2(m)}:${p2(s)}` : `${m}:${p2(s)}`;
|
||||
}
|
||||
function _tickTradeDuration() {
|
||||
const el = document.getElementById("tb-dur"), hd = document.getElementById("tb-runtime");
|
||||
if (!el) return;
|
||||
if (!_tradeOpenTime) { el.textContent = "—"; if (hd) hd.textContent = ""; return; }
|
||||
const sec = Date.now() / 1000 - _tradeOpenTime;
|
||||
const txt = _fmtDuration(sec);
|
||||
el.textContent = txt;
|
||||
if (hd) hd.textContent = "⏱ " + txt;
|
||||
// Ab 2 h dezent hervorheben (Time-Stop greift bei 120 min in Phase „Init")
|
||||
el.className = "tb-val" + (sec >= 7200 ? " warn" : "");
|
||||
}
|
||||
setInterval(_tickTradeDuration, 1000);
|
||||
function beepRecommendation(sig, isNew) {
|
||||
if (_muted) return; // auch kein Sperr-Toast
|
||||
if (!_audioCtx || _audioCtx.state !== "running") {
|
||||
@@ -386,12 +410,17 @@ function render(d) {
|
||||
dEl.textContent = long ? "▲ LONG" : "▼ SHORT";
|
||||
$("tb-lots").textContent = fmt(p.lots, 2);
|
||||
$("tb-margin").textContent = p.margin ? cs + fmt(p.margin, 2) : "—";
|
||||
// Laufzeit: Öffnungszeit merken (echte Epoch, Broker-Offset korrigiert) und
|
||||
// sekündlich per Ticker anzeigen — unabhängig vom Snapshot-Intervall.
|
||||
_tradeOpenTime = p.open_time ? Number(p.open_time) : 0;
|
||||
_tickTradeDuration();
|
||||
// SL/TP-Felder nur befüllen, wenn nicht gerade bearbeitet (kein Tipp-Konflikt)
|
||||
const slEl = $("tb-sl"), tpEl = $("tb-tp");
|
||||
if (document.activeElement !== slEl) slEl.value = p.sl ? fmt(p.sl, 2) : "";
|
||||
if (document.activeElement !== tpEl) tpEl.value = p.tp ? fmt(p.tp, 2) : "";
|
||||
} else {
|
||||
tb.classList.add("hidden");
|
||||
_tradeOpenTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user