Provider-Failover bei hartem Fehlschlag + Einsatz-Prozentfeld im Dashboard
1) LLM-Failover (core/agent.py): ein hart gescheiterter Provider wird zeitweise uebersprungen, analyze() nimmt den naechsten aus der Kette. Hart = 401/402/403/ 404 (Key/Guthaben/Modell) -> 30 min, nicht erreichbar -> 5 min. Timeout/429/5xx loesen BEWUSST keinen Wechsel aus (voruebergehend; sonst kostet jede Lastspitze die volle Timeout-Summe aller Anbieter). Neu im Snapshot: agent.provider_dead mit Restminuten - der DeepSeek-Ausfall stand vorher nur im Log und blieb deshalb 18 h unbemerkt. 9 Szenarien getestet. 2) Einsatz-Prozentfeld (web, v=137): margin_buffer_pct hatte bisher keine UI. Neues Feld "Einsatz %" neben "Einsatz EUR", POST /api/marginpct -> engine.set_margin_pct -> config.set_margin_buffer, Snapshot margin_pct, neustart-fest. Der feste EUR-Betrag hat Vorrang; das Prozentfeld wird dann ausgegraut, damit nicht unklar bleibt was gilt. Auf 1-99 % geklemmt. Ende-zu-Ende getestet (50, 150->99, 0 und -5 abgelehnt, 95, persistiert). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7e9b0196a5
commit
cc4f1a0863
+54
@@ -908,6 +908,24 @@ function render(d) {
|
||||
mgi.value = mm > 0 ? String(mm) : "";
|
||||
mgi.classList.toggle("on", mm > 0);
|
||||
}
|
||||
// Einsatz in Prozent der freien Margin. Ausgegraut, sobald links ein fester
|
||||
// Betrag steht — der hat Vorrang, und ohne den Hinweis wäre unklar, was gilt.
|
||||
const mpi = $("marginpct-input");
|
||||
if (mpi && document.activeElement !== mpi) {
|
||||
const mp = d.margin_pct || 0;
|
||||
mpi.value = mp > 0 ? String(mp) : "";
|
||||
const fest = (d.manual_margin || 0) > 0;
|
||||
mpi.classList.toggle("on", mp > 0 && !fest);
|
||||
const wrap = $("marginpct-wrap");
|
||||
if (wrap) {
|
||||
wrap.classList.toggle("muted", fest);
|
||||
wrap.title = fest
|
||||
? `Ohne Wirkung: links steht ein fester Einsatz (${fmt(d.manual_margin, 2)} €). `
|
||||
+ `Der Prozentsatz (${mp} %) bleibt nur die Obergrenze.`
|
||||
: "Einsatz als Prozent der freien Margin (1–99). "
|
||||
+ "Greift, solange links kein fester Betrag steht.";
|
||||
}
|
||||
}
|
||||
// Einblendung: der Bot hat am S/R automatisch geschlossen (Zähler stieg)
|
||||
const src = d.sr_close_count;
|
||||
if (src != null) {
|
||||
@@ -1307,6 +1325,42 @@ async function setManualMargin() {
|
||||
});
|
||||
})();
|
||||
|
||||
// Einsatz in PROZENT der freien Margin (User-Wunsch 2026-08-05) — das Gegenstück
|
||||
// zum festen Betrag oben. Steuert `margin_buffer_pct`, das bisher nur in der ini
|
||||
// stand. ⚠ Ein gesetzter fester Betrag hat Vorrang; darauf weist der Toast hin.
|
||||
async function setMarginPct() {
|
||||
const el = $("marginpct-input"); if (!el) return;
|
||||
const v = parseFloat(el.value);
|
||||
if (isNaN(v) || v < 1 || v > 99) {
|
||||
toast("Bitte 1–99 % eingeben (100 % ließe keinen Puffer für Spread/Swap)", false);
|
||||
return;
|
||||
}
|
||||
const tok = await ensureToken();
|
||||
if (tok === null) return;
|
||||
el.blur();
|
||||
try {
|
||||
const r = await fetch("api/marginpct", { method: "POST",
|
||||
headers: { "X-Auth-Token": tok, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ value: v }) });
|
||||
if (r.status === 401) { clearToken(); throw new Error("401"); }
|
||||
const j = await r.json();
|
||||
if (j.ok === false) { toast(j.error || "abgelehnt", false); return; }
|
||||
const fest = parseFloat(($("margin-input") || {}).value || "0") > 0;
|
||||
toast(`Einsatz: ${fmt(j.value ?? v, 0)} % der freien Margin`
|
||||
+ (fest ? " — greift erst, wenn der feste Betrag links leer ist" : ""), true);
|
||||
} catch (e) {
|
||||
toast(e.message === "401" ? "Token abgelaufen — neu eingeben" : "Netzwerkfehler", false);
|
||||
}
|
||||
}
|
||||
(() => {
|
||||
const el = $("marginpct-input");
|
||||
if (!el) return; // null-sicher (Cache-Regel)
|
||||
el.addEventListener("change", setMarginPct);
|
||||
el.addEventListener("keydown", e => {
|
||||
if (e.key === "Enter") { e.preventDefault(); e.target.blur(); }
|
||||
});
|
||||
})();
|
||||
|
||||
// Notfall-Stop: manueller Verlust-Wert, bei dem der Server sofort schließt.
|
||||
// Wieder eingeblendet 2026-07-22 (Backend/Persistenz waren die ganze Zeit aktiv).
|
||||
async function setEmg() {
|
||||
|
||||
Reference in New Issue
Block a user