beast-agent 2.36.2 → 2.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/agent/engine.js +4 -3
- package/src/main.js +40 -20
- package/src/renderer/index.html +10 -1
- package/src/renderer/renderer.js +51 -3
- package/src/renderer/style.css +10 -2
package/package.json
CHANGED
package/src/agent/engine.js
CHANGED
|
@@ -2687,10 +2687,11 @@ class Engine {
|
|
|
2687
2687
|
|
|
2688
2688
|
send(sessionId, payload, opts = {}) {
|
|
2689
2689
|
const userAction = !!(opts && opts.userAction);
|
|
2690
|
-
/* /stop
|
|
2691
|
-
|
|
2690
|
+
/* /stop KİLİDİ: sistem tetikli gönderimler (rapor, kick, cron, izleyici,
|
|
2691
|
+
arka plan) kilit açılana dek bloklanır. Kullanıcının yazdığı YENİ mesaj
|
|
2692
|
+
cevaplanır ama kilidi AÇMAZ — durdurulan iş kendiliğinden devam etmez;
|
|
2693
|
+
kilit yalnız /start (clearStop) ya da açık bir "başlat" eylemiyle açılır. */
|
|
2692
2694
|
if (this._stopped && !userAction) return false;
|
|
2693
|
-
if (userAction) this._stopped = false;
|
|
2694
2695
|
const s = this._load(String(sessionId));
|
|
2695
2696
|
if (!s) return false;
|
|
2696
2697
|
|
package/src/main.js
CHANGED
|
@@ -1096,8 +1096,8 @@ function waSlashHelp() {
|
|
|
1096
1096
|
'• */beastcode* [görev] – ⚡ UZAKTAN KODLAMA: masaüstünde Beast Code paneli açılır, WhatsApp\u2019tan uygulama yazdır (örn: /beastcode hava durumu uygulaması yaz)',
|
|
1097
1097
|
'• */beastagent* – kodlama modunu kapat, masaüstünde chat ekranına dön',
|
|
1098
1098
|
'• */plan* · */build* · */auto* – BeastCode modunda çalışma modu (planla · uygula · otomatik)',
|
|
1099
|
-
'• */stop* – koşan
|
|
1100
|
-
'• */start* –
|
|
1099
|
+
'• */stop* – koşan her şeyi ANINDA durdur + kilitle (kilit yalnız */start* ile açılır; yeni mesaj durdurulan işi devam ettirmez)',
|
|
1100
|
+
'• */start* – kilidi aç; yeni istekler normal işlenir',
|
|
1101
1101
|
'• */restart* – uygulamayı yeniden başlat',
|
|
1102
1102
|
'• */change* – modelleri listele (*/change 5* ile 5.modele geç)',
|
|
1103
1103
|
'• */notes* – bu oturumun notlarını göster',
|
|
@@ -1258,6 +1258,9 @@ let servicesPaused = false;
|
|
|
1258
1258
|
function stopEverything() {
|
|
1259
1259
|
let n = 0;
|
|
1260
1260
|
try { n = engine.stopAll(); } catch {}
|
|
1261
|
+
/* BEAST FINANCE: trader + ekip + sembol işçileri de GERÇEKTEN durur
|
|
1262
|
+
(timer'ları kapanır, panel durumu kapanır; panelden ▶ ile yeniden başlar) */
|
|
1263
|
+
try { Promise.resolve(finStopAllFinanceAgents('/stop: kullanıcı tüm ajanları durdurdu')).catch(() => {}); } catch {}
|
|
1261
1264
|
/* bekleyen masaüstü/WA birleştirme kuyrukları temizlenir */
|
|
1262
1265
|
try { for (const [, q] of desktopQueue) clearTimeout(q.timer); } catch {}
|
|
1263
1266
|
desktopQueue.clear();
|
|
@@ -1268,9 +1271,10 @@ function stopEverything() {
|
|
|
1268
1271
|
return n;
|
|
1269
1272
|
}
|
|
1270
1273
|
|
|
1274
|
+
/* /stop kilidini aç (YALNIZ /start ve açık "başlat" eylemleri çağırır;
|
|
1275
|
+
normal mesajlar kilidi AÇMAZ — durdurulan iş kendiliğinden devam etmez) */
|
|
1271
1276
|
function resumeServices() {
|
|
1272
1277
|
if (!servicesPaused) {
|
|
1273
|
-
/* /stop kapısı burada da kalkar — /start VE kullanıcının kendi mesajı canlandırır */
|
|
1274
1278
|
try { engine.clearStop(); } catch {}
|
|
1275
1279
|
return;
|
|
1276
1280
|
}
|
|
@@ -1535,19 +1539,18 @@ async function tryWaSlash(jid, rawText, senderNum, payload0) {
|
|
|
1535
1539
|
const r = arg ? applyThinkLevel(arg) : null;
|
|
1536
1540
|
out = r && r.error ? r.error : r ? r.text : thinkStatusText();
|
|
1537
1541
|
} else if (cmd === 'stop') {
|
|
1538
|
-
/* /stop: koşan
|
|
1542
|
+
/* /stop: koşan her şey + KİLİT; kilit yalnız /start ile açılır */
|
|
1539
1543
|
const stopped = stopEverything();
|
|
1540
1544
|
out =
|
|
1541
1545
|
`*Durdu* — ${stopped} koşan iş kesildi.\n` +
|
|
1542
1546
|
`Sürüyen sorgular, akıştaki cevaplar ve ajan faaliyetleri ANINDA kesildi; ajan yeni sorgu da açamaz.\n` +
|
|
1543
|
-
`
|
|
1547
|
+
`Bu kilit yalnız /start ile açılır — yeni mesaj yazmak durdurulan işi devam ettirmez.`;
|
|
1544
1548
|
} else if (cmd === 'start') {
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
}
|
|
1549
|
+
const wasStopped = !!(engine && engine._stopped);
|
|
1550
|
+
resumeServices();
|
|
1551
|
+
out = wasStopped
|
|
1552
|
+
? '*Devam* — kilit açıldı; yeni istekler normal işlenir. Finans trader durduysa panelden ▶ ile yeniden başlat.'
|
|
1553
|
+
: 'Zaten çalışıyor — durdurulmuş bir şey yok.';
|
|
1551
1554
|
} else if (cmd === 'restart') {
|
|
1552
1555
|
out = '*\u21BB Yeniden başlatılıyor…* Uygulama birkaç saniye içinde kapanıp açılacak.';
|
|
1553
1556
|
setTimeout(() => {
|
|
@@ -2437,7 +2440,8 @@ async function handleWaIncoming(jid, payload, senderNum) {
|
|
|
2437
2440
|
if (senderNum) waJidPn.set(jid, String(senderNum));
|
|
2438
2441
|
}
|
|
2439
2442
|
waLog(`gate: kuyruğa geçiliyor jid=${waPrettyJid(jid)} sender=+${senderNum || '?'}`);
|
|
2440
|
-
|
|
2443
|
+
/* /stop kilidi normal mesajla AÇILMAZ — mesaj yine işlenir (engine userAction),
|
|
2444
|
+
ama durdurulan iş/kuyruk kendiliğinden devam etmez */
|
|
2441
2445
|
waQueuePush(jid, { ...payload, isGroup }, senderNum);
|
|
2442
2446
|
} catch (e) {
|
|
2443
2447
|
waLog(`handleWaIncoming KRASİ: ${String((e && e.stack) || e)}`);
|
|
@@ -2833,7 +2837,8 @@ async function handleTgIncoming(chatId, payload) {
|
|
|
2833
2837
|
tgLog(`skip: isimsiz kayıt (${hit.id}) — cevap verilmedi, Entegrasyonlar'da isim ekle`);
|
|
2834
2838
|
return;
|
|
2835
2839
|
}
|
|
2836
|
-
|
|
2840
|
+
/* /stop kilidi normal mesajla AÇILMAZ — mesaj yine işlenir (engine userAction),
|
|
2841
|
+
ama durdurulan iş/kuyruk kendiliğinden devam etmez */
|
|
2837
2842
|
tgQueuePush(String(chatId), payload);
|
|
2838
2843
|
} catch (e) {
|
|
2839
2844
|
tgLog(`handleTgIncoming KRASİ: ${String((e && e.stack) || e)}`);
|
|
@@ -3052,7 +3057,8 @@ async function handleDcIncoming(channelId, payload) {
|
|
|
3052
3057
|
dcLog(`skip: isimsiz kayıt (${hit.id}) — cevap verilmedi, Entegrasyonlar'da isim ekle`);
|
|
3053
3058
|
return;
|
|
3054
3059
|
}
|
|
3055
|
-
|
|
3060
|
+
/* /stop kilidi normal mesajla AÇILMAZ — mesaj yine işlenir (engine userAction),
|
|
3061
|
+
ama durdurulan iş/kuyruk kendiliğinden devam etmez */
|
|
3056
3062
|
dcQueuePush(String(channelId), payload);
|
|
3057
3063
|
} catch (e) {
|
|
3058
3064
|
dcLog(`handleDcIncoming KRASİ: ${String((e && e.stack) || e)}`);
|
|
@@ -5380,7 +5386,8 @@ ipcMain.handle('agent:send', (_e, { sessionId, text }) => {
|
|
|
5380
5386
|
}
|
|
5381
5387
|
return true;
|
|
5382
5388
|
}
|
|
5383
|
-
|
|
5389
|
+
/* /stop kilidi normal mesajla AÇILMAZ — mesaj yine işlenir (engine userAction),
|
|
5390
|
+
ama durdurulan iş/kuyruk kendiliğinden devam etmez */
|
|
5384
5391
|
queueDesktopMessage(sessionId, text);
|
|
5385
5392
|
return true;
|
|
5386
5393
|
});
|
|
@@ -5404,7 +5411,7 @@ function desktopSlashHelp() {
|
|
|
5404
5411
|
'**/help** – bu liste',
|
|
5405
5412
|
'**/version** – Beast Agent sürümünü göster',
|
|
5406
5413
|
'**/restart** – uygulamayı yeniden başlat',
|
|
5407
|
-
'**/stop** – koşan
|
|
5414
|
+
'**/stop** – koşan her şeyi durdur + kilitle · **/start** – kilidi aç',
|
|
5408
5415
|
'**/change [n]** – modelleri listele · n. modele geç',
|
|
5409
5416
|
'**/model [isim]** – aktif modeli göster / değiştir · **/model refresh** – tüm provider modellerini yeniden çek',
|
|
5410
5417
|
'**/think 0-5** – düşünme seviyesi (0 kapalı · 5 max)',
|
|
@@ -5538,11 +5545,13 @@ function handleGlobalStopStart(sessionId, cmd) {
|
|
|
5538
5545
|
reply =
|
|
5539
5546
|
`\u25A0 **Durdu** — ${n} koşan iş kesildi.\n` +
|
|
5540
5547
|
'Sürüyen sorgular, akıştaki cevaplar ve ajan faaliyetleri ANINDA kesildi; ajan yeni sorgu da açamaz.\n' +
|
|
5541
|
-
'
|
|
5548
|
+
'Bu kilit yalnız `/start` ile açılır — yeni mesaj yazmak durdurulan işi devam ettirmez.';
|
|
5542
5549
|
} else {
|
|
5543
|
-
const
|
|
5550
|
+
const wasStopped = !!(engine && engine._stopped);
|
|
5544
5551
|
resumeServices();
|
|
5545
|
-
reply =
|
|
5552
|
+
reply = wasStopped
|
|
5553
|
+
? '\u25B6 **Devam** — kilit açıldı; yeni istekler normal işlenir. Finans trader durduysa panelden \u25B6 ile yeniden başlat.'
|
|
5554
|
+
: 'Zaten çalışıyor — durdurulmuş bir şey yok.';
|
|
5546
5555
|
}
|
|
5547
5556
|
if (win && !win.isDestroyed()) {
|
|
5548
5557
|
win.webContents.send('agent:event', { sessionId: sid, type: 'message', message: { role: 'user', content: cmd } });
|
|
@@ -8498,6 +8507,11 @@ function finCfg() {
|
|
|
8498
8507
|
if (typeof f.notifyTarget !== 'string') f.notifyTarget = 'auto';
|
|
8499
8508
|
if (typeof f.notifyTrades !== 'boolean') f.notifyTrades = true;
|
|
8500
8509
|
if (typeof f.notifyWatchdog !== 'boolean') f.notifyWatchdog = true;
|
|
8510
|
+
/* KANAL OLAY FİLTRESİ: varsayılan true — WhatsApp/Telegram/Discord'a yalnız
|
|
8511
|
+
emir/işlem olayları (açılış, kapanış, bekleyen emir, iptal) düşer; fiyat
|
|
8512
|
+
alarmı, koruma (BE/trailing/kısmi TP), günlük limit ve rapor bildirimleri
|
|
8513
|
+
panelde kalır. false = tüm olaylar kanallara gider (eski davranış). */
|
|
8514
|
+
if (typeof f.notifyTradeOnly !== 'boolean') f.notifyTradeOnly = true;
|
|
8501
8515
|
if (!Number.isFinite(Number(f.maxDailyLossPct))) f.maxDailyLossPct = 3;
|
|
8502
8516
|
/* GÜNLÜK LİMİT AKSİYONU: warn = yalnız uyarı; stop = tüm finance ajanlarını
|
|
8503
8517
|
durdur; flatten = durdur + tüm pozisyonları kapat */
|
|
@@ -8617,6 +8631,11 @@ function financeNotify(text, kind, panel) {
|
|
|
8617
8631
|
try { cfg = finCfg(); } catch { cfg = {}; }
|
|
8618
8632
|
const target = String((cfg && cfg.notifyTarget) || 'auto');
|
|
8619
8633
|
if (target === 'off') return;
|
|
8634
|
+
/* KANAL FİLTRESİ: varsayılan olarak kanallara SADECE emir/işlem olayları
|
|
8635
|
+
gider (emir açılış/kapanış, bekleyen emir, iptal). Alarm/koruma/risk/rapor
|
|
8636
|
+
bildirimleri yalnız panelde görünür. */
|
|
8637
|
+
const kindStr = String(kind || '');
|
|
8638
|
+
if (cfg.notifyTradeOnly !== false && !['trade', 'close', 'pending', 'cancel'].includes(kindStr)) return;
|
|
8620
8639
|
const body = '💼 *Beast Finance*\n' + line;
|
|
8621
8640
|
const senders = [];
|
|
8622
8641
|
try {
|
|
@@ -9396,7 +9415,7 @@ function finTraderBrief(agent) {
|
|
|
9396
9415
|
roleDef
|
|
9397
9416
|
? 'Bulgularını agent_dm ile ANA TRADER\u2019a bildir (to: "Trader" ya da ajan başlığı anahtarı); teknik/öneri çelişkisi varsa gerekçenle yaz.'
|
|
9398
9417
|
: f.strategy ? `Sahibinin strateji notu: ${f.strategy}` : 'Strateji notu yok: trend + destek/direnç + momentum ile temel okuma yap.',
|
|
9399
|
-
|
|
9418
|
+
roleDef && f.strategy ? `Sahibinin strateji notu (bu çerçevede analiz et): ${f.strategy}` : '',
|
|
9400
9419
|
'Bu turda: mt5_status → hesap/pozisyon/fiyat verisi → mt5_rates/mt5_indicators ile teknik okuma → değerlendirme → kararlar (veya BEKLE: sebep) → kısa rapor.',
|
|
9401
9420
|
'Önemli kararların gerekçesini mt5_note ile günlüğe yaz (haftalık performans raporu bu notları kullanır).',
|
|
9402
9421
|
'Risk otomasyonu main süreçte 5 sn döngüyle çalışır (+R BE, trailing, kısmi TP) — sen yine de SL/TP seviyelerini aktif yönet.',
|
|
@@ -9678,6 +9697,7 @@ ipcMain.handle('finance:settings', async (_e, patch) => {
|
|
|
9678
9697
|
}
|
|
9679
9698
|
if (p.notifyTrades !== undefined) f.notifyTrades = !!p.notifyTrades;
|
|
9680
9699
|
if (p.notifyWatchdog !== undefined) f.notifyWatchdog = !!p.notifyWatchdog;
|
|
9700
|
+
if (p.notifyTradeOnly !== undefined) f.notifyTradeOnly = !!p.notifyTradeOnly;
|
|
9681
9701
|
if (p.maxDailyLossPct !== undefined) f.maxDailyLossPct = Math.max(0, Math.min(50, Number(p.maxDailyLossPct) || 0));
|
|
9682
9702
|
if (p.dailyLossAction !== undefined) {
|
|
9683
9703
|
const v = String(p.dailyLossAction || 'warn').toLowerCase();
|
package/src/renderer/index.html
CHANGED
|
@@ -186,6 +186,10 @@
|
|
|
186
186
|
<span>Analiz ekibi <i class="fin-hint">— sadece sayı seç, rolleri sistem otomatik atar</i></span>
|
|
187
187
|
<div id="finRoles" class="fin-roles" title="Trader'ın yanında koşacak uzman ajan SAYISI — roller otomatik atanır (Teknik → Risk → Haber); işlem açmazlar"></div>
|
|
188
188
|
</div>
|
|
189
|
+
<div class="fin-field">
|
|
190
|
+
<span>Ajan talimatı <i class="fin-hint">— 1-2 cümle; trader + tüm paralel ajanlara iletilir</i></span>
|
|
191
|
+
<textarea id="finStrategy" rows="2" maxlength="2000" placeholder="örn. Her türde scalp yap — M1/M5 hızlı gir-çık, günlük kâr hedefine ulaşınca dur" title="Buraya yazdığın talimat trade ajanına ve koşan tüm paralel ajanlara (ekip + sembol işçileri) sistem promptunda öncelikli strateji notu olarak gider; kaydetmek için alandan çık"></textarea>
|
|
192
|
+
</div>
|
|
189
193
|
<div class="fin-row fin-btn-row">
|
|
190
194
|
<button id="finTraderBtn" class="fin-start">▶︎ Ajanı Başlat</button>
|
|
191
195
|
</div>
|
|
@@ -222,7 +226,7 @@
|
|
|
222
226
|
</div>
|
|
223
227
|
<div class="fin-field">
|
|
224
228
|
<span>Bildirim kanalı</span>
|
|
225
|
-
<select id="finNotifyTarget" title="
|
|
229
|
+
<select id="finNotifyTarget" title="Emir/işlem bildirimleri bu kanala gider; panel ve masaüstü toast her zaman çalışır">
|
|
226
230
|
<option value="auto">Otomatik (bağlı olan kanallar)</option>
|
|
227
231
|
<option value="telegram">Telegram</option>
|
|
228
232
|
<option value="whatsapp">WhatsApp</option>
|
|
@@ -230,6 +234,11 @@
|
|
|
230
234
|
<option value="off">Kapalı (yalnız panel)</option>
|
|
231
235
|
</select>
|
|
232
236
|
</div>
|
|
237
|
+
<div class="fin-field fin-check">
|
|
238
|
+
<label title="İşaretliyken kanala YALNIZ emir olayları düşer: açılış, kapanış, bekleyen emir, iptal. Fiyat alarmı, BE/trailing/kısmi TP, günlük limit ve rapor bildirimleri gelmez — onlar panelde kalır">
|
|
239
|
+
<input id="finNotifyTradeOnly" type="checkbox" checked /> Kanala sadece emir/işlem olayları gelsin (alarm gelmez)
|
|
240
|
+
</label>
|
|
241
|
+
</div>
|
|
233
242
|
<div id="finAlertList" class="fin-alerts"><div class="fin-empty">Aktif fiyat alarmı yok</div></div>
|
|
234
243
|
</div>
|
|
235
244
|
<div class="fin-card" id="finPerfCard" hidden>
|
package/src/renderer/renderer.js
CHANGED
|
@@ -182,6 +182,7 @@ const els = {
|
|
|
182
182
|
finModelRefreshBtn: $('#finModelRefreshBtn'),
|
|
183
183
|
finInterval: $('#finInterval'),
|
|
184
184
|
finMaxLot: $('#finMaxLot'),
|
|
185
|
+
finStrategy: $('#finStrategy'),
|
|
185
186
|
finSymBtn: $('#finSymBtn'),
|
|
186
187
|
finRoles: $('#finRoles'),
|
|
187
188
|
finWatchClear: $('#finWatchClear'),
|
|
@@ -217,6 +218,7 @@ const els = {
|
|
|
217
218
|
finMinMarginLevel: $('#finMinMarginLevel'),
|
|
218
219
|
finDailyLossAction: $('#finDailyLossAction'),
|
|
219
220
|
finNotifyTarget: $('#finNotifyTarget'),
|
|
221
|
+
finNotifyTradeOnly: $('#finNotifyTradeOnly'),
|
|
220
222
|
finWatchDot: $('#finWatchDot'),
|
|
221
223
|
finWatchInfo: $('#finWatchInfo'),
|
|
222
224
|
finAlertList: $('#finAlertList'),
|
|
@@ -6741,7 +6743,7 @@ const SLASH_COMMANDS = [
|
|
|
6741
6743
|
{ cmd: '/new', desc: 'yeni oturum aç (kod verilir)' },
|
|
6742
6744
|
{ cmd: '/open ', desc: 'koddaki oturuma geç' },
|
|
6743
6745
|
{ cmd: '/sessions', desc: 'bu sohbetin oturumları' },
|
|
6744
|
-
{ cmd: '/stop', desc: 'çalışan
|
|
6746
|
+
{ cmd: '/stop', desc: 'çalışan her şeyi durdur + kilitle — kilit yalnız /start ile açılır' },
|
|
6745
6747
|
{ cmd: '/restart', desc: 'uygulamayı yeniden başlat' },
|
|
6746
6748
|
{ cmd: '/change', desc: 'modelleri listele · /change 5 ile geç' },
|
|
6747
6749
|
{ cmd: '/screenshot', desc: 'ekran görüntüsünü sohbete ekle' },
|
|
@@ -6750,7 +6752,7 @@ const SLASH_COMMANDS = [
|
|
|
6750
6752
|
{ cmd: '/clear', desc: 'oturum geçmişini GERÇEKTEN sil (kod korunur)' },
|
|
6751
6753
|
{ cmd: '/autodel', desc: 'tüm otomatik hatırlatmaları sil · /autodel all: cron dahil hepsi' },
|
|
6752
6754
|
{ cmd: '/deltodo', desc: 'todo listesini temizle · /deltodo all: tüm oturumlar' },
|
|
6753
|
-
{ cmd: '/start', desc: '
|
|
6755
|
+
{ cmd: '/start', desc: 'kilidi aç; yeni istekler normal işlenir' },
|
|
6754
6756
|
{ cmd: '/rule ', desc: 'kalıcı kural ekle' },
|
|
6755
6757
|
{ cmd: '/rules', desc: 'kalıcı kuralları listele' },
|
|
6756
6758
|
{ cmd: '/model', desc: 'modeli göster/değiştir' },
|
|
@@ -9128,6 +9130,7 @@ let finPollTimer = null;
|
|
|
9128
9130
|
let finModelsFilled = false;
|
|
9129
9131
|
let finLastPrices = new Map(); /* sembol → son bid (renk için) */
|
|
9130
9132
|
let finCfgCache = null; /* son snapshot cfg — rol→skill modalı bundan okur */
|
|
9133
|
+
let finStrategyDirty = false; /* textarea'da kaydedilmeyi bekleyen ajan talimatı var */
|
|
9131
9134
|
const FIN_COLOR_UP = 'fs-up';
|
|
9132
9135
|
const FIN_COLOR_DOWN = 'fs-down';
|
|
9133
9136
|
|
|
@@ -9316,6 +9319,7 @@ function finTraderInputsSet(cfg) {
|
|
|
9316
9319
|
const ae = document.activeElement;
|
|
9317
9320
|
if (els.finInterval && ae !== els.finInterval) els.finInterval.value = cfg.intervalSec || 120;
|
|
9318
9321
|
if (els.finMaxLot && ae !== els.finMaxLot) els.finMaxLot.value = cfg.maxLot || 0.1;
|
|
9322
|
+
if (els.finStrategy && ae !== els.finStrategy && !finStrategyDirty) els.finStrategy.value = cfg.strategy || '';
|
|
9319
9323
|
finSymBtnUpdate();
|
|
9320
9324
|
if (els.finTraderModel && ae !== els.finTraderModel && cfg.traderSel) els.finTraderModel.value = cfg.traderSel;
|
|
9321
9325
|
}
|
|
@@ -9431,6 +9435,7 @@ function finRenderAutomation(cfg, watch) {
|
|
|
9431
9435
|
setNum(els.finMinMarginLevel, cfg.minMarginLevel != null ? cfg.minMarginLevel : 150);
|
|
9432
9436
|
if (els.finDailyLossAction && ae !== els.finDailyLossAction) els.finDailyLossAction.value = cfg.dailyLossAction || 'stop';
|
|
9433
9437
|
if (els.finNotifyTarget && ae !== els.finNotifyTarget) els.finNotifyTarget.value = cfg.notifyTarget || 'auto';
|
|
9438
|
+
if (els.finNotifyTradeOnly && ae !== els.finNotifyTradeOnly) els.finNotifyTradeOnly.checked = cfg.notifyTradeOnly !== false;
|
|
9434
9439
|
if (els.finWatchDot) {
|
|
9435
9440
|
els.finWatchDot.classList.remove('on', 'off', 'busy');
|
|
9436
9441
|
els.finWatchDot.classList.add(watch && watch.on ? 'on' : 'off');
|
|
@@ -9658,12 +9663,33 @@ let finCfgTimer = null;
|
|
|
9658
9663
|
let finWatchDirty = false; /* picker/input değişikliği kaydedilmeyi bekliyor */
|
|
9659
9664
|
function finSaveCfg(patch) {
|
|
9660
9665
|
if (patch && patch.symbols !== undefined) finWatchDirty = true;
|
|
9666
|
+
if (patch && patch.strategy !== undefined) finStrategyDirty = true;
|
|
9661
9667
|
clearTimeout(finCfgTimer);
|
|
9668
|
+
const wasStrategy = !!(patch && patch.strategy !== undefined);
|
|
9662
9669
|
finCfgTimer = setTimeout(() => {
|
|
9663
|
-
beast.financeSettings(patch)
|
|
9670
|
+
beast.financeSettings(patch)
|
|
9671
|
+
.then(() => {
|
|
9672
|
+
if (wasStrategy) {
|
|
9673
|
+
finStrategyDirty = false;
|
|
9674
|
+
if (finCfgCache) finCfgCache.strategy = patch.strategy;
|
|
9675
|
+
}
|
|
9676
|
+
finWatchDirty = false;
|
|
9677
|
+
})
|
|
9678
|
+
.catch(() => { finWatchDirty = false; });
|
|
9664
9679
|
}, 400);
|
|
9665
9680
|
}
|
|
9666
9681
|
|
|
9682
|
+
/* Ajan talimatı: Ajanı Başlat'tan önce bekleyen değişiklik hemen yazılır ki
|
|
9683
|
+
ilk tur brief'i talimatı görsün (debounce beklemeden). */
|
|
9684
|
+
function finStrategyFlush() {
|
|
9685
|
+
if (!els.finStrategy || !finStrategyDirty) return Promise.resolve();
|
|
9686
|
+
const v = els.finStrategy.value;
|
|
9687
|
+
finStrategyDirty = false;
|
|
9688
|
+
return beast.financeSettings({ strategy: v })
|
|
9689
|
+
.then(() => { if (finCfgCache) finCfgCache.strategy = v; })
|
|
9690
|
+
.catch(() => { finStrategyDirty = true; });
|
|
9691
|
+
}
|
|
9692
|
+
|
|
9667
9693
|
/* ---------- GÖRÜNÜM AYARLARI (isteğe bağlı bölümler) ----------
|
|
9668
9694
|
RİSK OTOMASYONU + PERFORMANS + AKIŞ varsayılan GİZLİ; açmak isteğe bağlı.
|
|
9669
9695
|
Seçim localStorage'da hatırlanır. Risk otomasyonu gizliyken watchdog
|
|
@@ -9789,6 +9815,14 @@ if (els.finNotifyTarget) {
|
|
|
9789
9815
|
toast('Bildirim kanalı: ' + els.finNotifyTarget.options[els.finNotifyTarget.selectedIndex].textContent);
|
|
9790
9816
|
});
|
|
9791
9817
|
}
|
|
9818
|
+
if (els.finNotifyTradeOnly) {
|
|
9819
|
+
els.finNotifyTradeOnly.addEventListener('change', () => {
|
|
9820
|
+
finSaveCfg({ notifyTradeOnly: els.finNotifyTradeOnly.checked });
|
|
9821
|
+
toast(els.finNotifyTradeOnly.checked
|
|
9822
|
+
? 'Kanala yalnız emir/işlem olayları gidecek — alarm/koruma bildirimleri panelde kalır'
|
|
9823
|
+
: 'Tüm finance bildirimleri (alarm/koruma dahil) kanala gidecek');
|
|
9824
|
+
});
|
|
9825
|
+
}
|
|
9792
9826
|
if (els.finReportBtn) {
|
|
9793
9827
|
els.finReportBtn.addEventListener('click', async () => {
|
|
9794
9828
|
els.finReportBtn.disabled = true;
|
|
@@ -9809,6 +9843,19 @@ if (els.finTraderModel) {
|
|
|
9809
9843
|
toast('Trade ajanı modeli: ' + (els.finTraderModel.value || 'genel aktif model'));
|
|
9810
9844
|
});
|
|
9811
9845
|
}
|
|
9846
|
+
/* AJAN TALİMATI: trader + ekip + sembol işçileri sistem promptunda
|
|
9847
|
+
"öncelikli strateji notu" olarak okur; yazarken (debounce) kaydedilir */
|
|
9848
|
+
if (els.finStrategy) {
|
|
9849
|
+
els.finStrategy.addEventListener('input', () => {
|
|
9850
|
+
finSaveCfg({ strategy: els.finStrategy.value });
|
|
9851
|
+
});
|
|
9852
|
+
els.finStrategy.addEventListener('change', () => {
|
|
9853
|
+
const v = els.finStrategy.value;
|
|
9854
|
+
if (finCfgCache && String(finCfgCache.strategy || '') === v) return;
|
|
9855
|
+
finSaveCfg({ strategy: v });
|
|
9856
|
+
toast(v.trim() ? 'Ajan talimatı kaydedildi — tüm ajanlar sonraki turda uygular' : 'Ajan talimatı temizlendi');
|
|
9857
|
+
});
|
|
9858
|
+
}
|
|
9812
9859
|
/* TRADE AJANI: modelleri yeniden çek — üstteki ⟳ ile aynı mantık
|
|
9813
9860
|
(models:refresh). Eksik/yeni modeller listeye girer, seçim korunur. */
|
|
9814
9861
|
if (els.finModelRefreshBtn) {
|
|
@@ -9831,6 +9878,7 @@ if (els.finTraderBtn) {
|
|
|
9831
9878
|
if (els.finTraderBtn.classList.contains('stop')) {
|
|
9832
9879
|
await beast.financeTraderStop().catch(() => {});
|
|
9833
9880
|
} else {
|
|
9881
|
+
await finStrategyFlush(); /* yazılan talimat ilk turdan önce kaydedilsin */
|
|
9834
9882
|
const r = await beast.financeTraderStart().catch((e) => ({ ok: false, error: String((e && e.message) || e) }));
|
|
9835
9883
|
if (r && !r.ok) toast(r.error || 'Trader başlatılamadı');
|
|
9836
9884
|
else if (r && r.ok) {
|
package/src/renderer/style.css
CHANGED
|
@@ -4846,7 +4846,7 @@ body.finance-mode #composerWrap { margin-right: var(--finW, 400px); }
|
|
|
4846
4846
|
/* TRADE AJANI formu — etiket üstte, kontrol altta; tur/max lot 2 kolon */
|
|
4847
4847
|
.fin-field { display: flex; flex-direction: column; gap: 3px; min-width: 0; margin-bottom: 8px; }
|
|
4848
4848
|
.fin-field > span { font-size: 10px; color: var(--muted); }
|
|
4849
|
-
.fin-field input, .fin-field select {
|
|
4849
|
+
.fin-field input, .fin-field select, .fin-field textarea {
|
|
4850
4850
|
width: 100%;
|
|
4851
4851
|
min-width: 0;
|
|
4852
4852
|
background: var(--panel2);
|
|
@@ -4856,7 +4856,15 @@ body.finance-mode #composerWrap { margin-right: var(--finW, 400px); }
|
|
|
4856
4856
|
padding: 4px 7px;
|
|
4857
4857
|
border-radius: 6px;
|
|
4858
4858
|
}
|
|
4859
|
-
.fin-field input:focus, .fin-field select:focus { border-color: var(--accent); outline: none; }
|
|
4859
|
+
.fin-field input:focus, .fin-field select:focus, .fin-field textarea:focus { border-color: var(--accent); outline: none; }
|
|
4860
|
+
/* Ajan talimatı: çok satırlı not alanı (dikey büyütülebilir) */
|
|
4861
|
+
.fin-field textarea {
|
|
4862
|
+
resize: vertical;
|
|
4863
|
+
min-height: 46px;
|
|
4864
|
+
max-height: 140px;
|
|
4865
|
+
line-height: 1.35;
|
|
4866
|
+
font-family: inherit;
|
|
4867
|
+
}
|
|
4860
4868
|
.fin-field .fin-sym-select { width: 100%; }
|
|
4861
4869
|
.fin-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
|
|
4862
4870
|
.fin-grid2 .fin-field { margin-bottom: 8px; }
|