beast-agent 2.59.0 → 2.61.0
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 +2 -1
- package/src/agent/financetools.js +9 -7
- package/src/main.js +121 -4
- package/src/renderer/renderer.js +1 -0
package/package.json
CHANGED
package/src/agent/engine.js
CHANGED
|
@@ -2032,8 +2032,9 @@ class Engine {
|
|
|
2032
2032
|
modeBlock2 + '\n' +
|
|
2033
2033
|
(roleBlockFull ? roleBlockFull + '\n' : '') +
|
|
2034
2034
|
(teamLine || '') +
|
|
2035
|
-
'MT5 ARAÇLARI: mt5_status (bağlantı), mt5_account (hesap), mt5_market (canlı fiyat), mt5_positions (açık pozisyonlar), mt5_orders (bekleyen emirler), mt5_history (kapanan işlemler), mt5_alerts (fiyat alarmı: kur/listele/sil — modu SEN seçersin: once/repeat), mt5_ea (BeastFinance grafik panosu: status/ping/chart/note), mt5_trade (
|
|
2035
|
+
'MT5 ARAÇLARI: mt5_status (bağlantı), mt5_account (hesap), mt5_market (canlı fiyat), mt5_positions (açık pozisyonlar), mt5_orders (bekleyen emirler), mt5_history (kapanan işlemler), mt5_alerts (fiyat alarmı: kur/listele/sil — modu SEN seçersin: once/repeat), mt5_ea (BeastFinance grafik panosu: status/ping/chart/note), mt5_trade (⚡PİYASA EMRİ: side:"buy"|"sell" ile ANLIK gir — bekleyen emir ZORUNLU DEĞİL; lot için volume yerine riskPct+sl ver, sistem hesaplar; limit/stop tipleri de kabul eder), mt5_close (TAM ya da KISMİ kapat: percent ile kısmi TP & kısmi stop — karar ajanın), mt5_modify (SL/TP), mt5_pending (BEKLEYEN emir: limit/stop + price — fiyatın seviyeye gelmesini beklemek için; anlık giriş için mt5_trade kullan), mt5_cancel (emir iptal).\n' +
|
|
2036
2036
|
'EMİR TİPLERİ (6 tip — HEPSİ AÇIK): buy_market/sell_market = anlık piyasa emri (fiyat beklenmez), buy_limit/sell_limit = bekleyen limit (price zorunlu), buy_stop/sell_stop = bekleyen stop (price zorunlu). mt5_trade ve mt5_pending İKİSİ DE 6 tipi kabul eder; emir tipini net söyle (ör. type:"sell_limit").\n' +
|
|
2037
|
+
'⚡HIZLI AKSİYON (ZORUNLU ZİHNİYET): piyasa emri (market buy/sell) HER ZAMAN elinde ve bekleyen emir vermek ZORUNDA DEĞİLSİN. Fırsat anıksa / teyitli kırılım, momentum, haber veya seviye reddi anında mt5_trade {symbol, side:"buy"|"sell", sl, tp, riskPct ya da volume, reason} ile ANINDA market gir — type bile yazmana gerek yok. Bekleyen emir YALNIZ fiyatın seviyeye gelmesini beklemek gerçekten mantıklıysa kurulur (ör. geri çekilme limiti); "emir" diye her şeyi bekleyen emirle yapma. Hızlı girişte tek çağrı yeter: volume yerine riskPct+sl ver → lot otomatik hesaplanır.\n' +
|
|
2037
2038
|
'ALARM KARARI SENDE: mt5_alerts ile alarm kurarken mode ZORUNLU — "once" (tek seferlik; ilk tetiklemede kapanır) ya da "repeat" (tekrarlı; alarm açık kalır, koşul sürdükçe cooldownMin dakikada bir tekrar uyarır + seni uyandırır; cooldownMin varsayılan 5). Tekrarlı mı tek seferlik mi olacağını sen seç, varsayılana bırakma; seviyenin önemine göre cooldownMin belirle (ör. 5/15/60).\n' +
|
|
2038
2039
|
'ALARM TEMİZLİĞİ (ZORUNLU DİSİPLİN): alarm bir BEKÇİDİR, süs değil — gereksiz alarm biriktirme. Her turda (ya da en az birkaç turda bir) mt5_alerts action:"list" ile alarmları gör; listede "mine:true" senin kurduklarındır. Tezi/geçerliliği biten alarmı SİL: seviye kırıldı ve artık anlamsız, pozisyon kapandı, plan/hedef değişti, tetiklendi ve işlevi kalmadı. Silme: tekil kayıt action:"remove" {id} · kendi gereksizlerini toplu action:"clear" (varsayılan yalnız SENİN alarmların; symbol ile daralt; tümünü temizlemek için all:true — bunu başka ajanların alarmlarını da sileceği için YALNIZ açıkça gerekliyse kullan). Akan fiyatta işe yaramayan, üst üste aynı bölgeye kurulmuş alarmları temiz tut.\n' +
|
|
2039
2040
|
'KISMİ KAPATMA YETKİSİ (TÜM finance ajanlarında): açık pozisyonda kısmi kapatma — kısmi TP (kâr al) ve kısmi stop (zarar kes) — TAMAMEN SENİN KARARIN, OTOMATİK DEĞİLDİR; mt5_close {ticket, percent, kind:"partial_tp"|"partial_sl", reason}. Gerek gördüğünde kullan; kalan pozisyon SL/TP ile devam eder. Kısmi TP fırsatı bildirimi gelirse (fiyat seviyeye ulaştı) kapatıp kapatmamak sana bağlı.\n' +
|
|
@@ -262,25 +262,26 @@ const definitions = NAMES.map((name) => {
|
|
|
262
262
|
},
|
|
263
263
|
mt5_trade: {
|
|
264
264
|
description:
|
|
265
|
-
'
|
|
265
|
+
'ANLIK PİYASA EMRİ AÇAR — ⚡HIZLI AKSİYON; bekleyen emir vermek ZORUNLU DEĞİL: mt5_trade {symbol, side:"buy"|"sell", volume?|riskPct?, sl?, tp?, type?, comment?, reason?}. Fırsat anıksa / teyitli kırılım-momentum-haber anında market buy/sell ile HEMEN gir — side:"buy"|"sell" yeter (type gerekmez; type:"market"|"buy_market"|"sell_market" de anlıktır). BEKLEYEN emir yalnız fiyatın bir seviyeye gelmesini beklemek gerçekten mantıklıysa kurulur: type:"buy_limit"|"sell_limit"|"buy_stop"|"sell_stop" + price (bu tipler otomatik mt5_pending hattına gider). LOT: volume ver ya da volume yerine riskPct + sl ver — sistem SL mesafesinden lotu hesaplar (tek çağrıda giriş; ayardaki işlem riski % varsayılan). Lot limiti, max pozisyon, marj ve yoğunluk sistemce zorlanır. SL vermek ŞİDDETLİ önerilir. reason: kararın tek cümlelik tezi (günlüğe yazılır).',
|
|
266
266
|
parameters: {
|
|
267
267
|
type: 'object',
|
|
268
268
|
properties: {
|
|
269
269
|
symbol: { type: 'string', description: 'Örn: EURUSD' },
|
|
270
|
-
side: { type: 'string', enum: ['buy', 'sell'], description: 'Yön
|
|
270
|
+
side: { type: 'string', enum: ['buy', 'sell'], description: 'Yön — piyasa emri için tek başına yeterli (type gerekmez)' },
|
|
271
271
|
type: {
|
|
272
272
|
type: 'string',
|
|
273
273
|
enum: ['market', 'buy_market', 'sell_market', 'buy_limit', 'sell_limit', 'buy_stop', 'sell_stop'],
|
|
274
|
-
description: 'Emir tipi. Boş/side verilirse piyasa
|
|
274
|
+
description: 'Emir tipi. Boş/side verilirse piyasa (anlık); limit/stop verilirse bekleyen emir (price zorunlu olur).',
|
|
275
275
|
},
|
|
276
|
-
volume: { type: 'number', description: 'Lot (max lot sınırına tabi)' },
|
|
276
|
+
volume: { type: 'number', description: 'Lot (max lot sınırına tabi) — boşsa riskPct + sl ile OTOMATİK hesaplanır' },
|
|
277
|
+
riskPct: { type: 'number', description: 'İşlem riski % (ör. 0.5-2) — volume yerine ver: SL mesafesinden lot hesaplanır (sl zorunlu)' },
|
|
277
278
|
price: { type: 'number', description: 'Limit/stop emirlerinde tetik fiyatı (piyasa emrinde gerekmez)' },
|
|
278
|
-
sl: { type: 'number', description: 'Stop loss fiyatı (0 = yok)' },
|
|
279
|
+
sl: { type: 'number', description: 'Stop loss fiyatı (0 = yok) — şiddetle önerilir' },
|
|
279
280
|
tp: { type: 'number', description: 'Take profit fiyatı (0 = yok)' },
|
|
280
281
|
comment: { type: 'string', description: 'Kısa işlem notu' },
|
|
281
282
|
reason: { type: 'string', description: 'Kararın tezi/gerekçesi (tek cümle)' },
|
|
282
283
|
},
|
|
283
|
-
required: ['symbol'
|
|
284
|
+
required: ['symbol'],
|
|
284
285
|
},
|
|
285
286
|
},
|
|
286
287
|
mt5_close: {
|
|
@@ -312,7 +313,7 @@ const definitions = NAMES.map((name) => {
|
|
|
312
313
|
},
|
|
313
314
|
mt5_pending: {
|
|
314
315
|
description:
|
|
315
|
-
'EMİR
|
|
316
|
+
'BEKLEYEN EMİR (limit/stop) AÇAR: mt5_pending {symbol, type:"buy_limit"|"sell_limit"|"buy_stop"|"sell_stop", volume, price, sl?, tp?, reason?}. Fiyatın seviyeye gelmesini beklemek için kullanılır. ⚡ANLIK giriş (hızlı aksiyon) için bunu kullanma — mt5_trade {symbol, side} ile market gir (buy_market/sell_market tipleri burada da kabul edilir ve anlık emre yönlenir). Otomatik işlem anahtarına tabidir. reason: kararın tezi (günlüğe yazılır).',
|
|
316
317
|
parameters: {
|
|
317
318
|
type: 'object',
|
|
318
319
|
properties: {
|
|
@@ -320,6 +321,7 @@ const definitions = NAMES.map((name) => {
|
|
|
320
321
|
type: {
|
|
321
322
|
type: 'string',
|
|
322
323
|
enum: ['buy_limit', 'sell_limit', 'buy_stop', 'sell_stop', 'buy_market', 'sell_market'],
|
|
324
|
+
description: 'Limit/stop = bekleyen (price zorunlu); buy_market/sell_market = anlık piyasa emri',
|
|
323
325
|
},
|
|
324
326
|
volume: { type: 'number' },
|
|
325
327
|
price: { type: 'number', description: 'Tetik fiyatı — limit/stop için zorunlu, market tiplerinde gerekmez' },
|
package/src/main.js
CHANGED
|
@@ -11446,6 +11446,9 @@ function finAgentStop(sid, reason) {
|
|
|
11446
11446
|
const agent = financeState.agents.get(sid);
|
|
11447
11447
|
if (!agent) return false;
|
|
11448
11448
|
clearTimeout(agent.timer);
|
|
11449
|
+
if (agent.waitPoll) { clearTimeout(agent.waitPoll); agent.waitPoll = null; }
|
|
11450
|
+
agent.waitingTeam = false;
|
|
11451
|
+
agent.consultPromise = null;
|
|
11449
11452
|
financeState.agents.delete(sid);
|
|
11450
11453
|
if (sid === String(financeState.traderSid || '')) financeState.traderSid = null;
|
|
11451
11454
|
try {
|
|
@@ -11465,6 +11468,22 @@ function finAgentStop(sid, reason) {
|
|
|
11465
11468
|
/* AJAN DM: duran ajanın birebir sohbetleri kapanır; grupta KOŞAN üye
|
|
11466
11469
|
kalmadıysa ekip sohbeti de GEÇMİŞE düşer (aktif listede kalmaz) */
|
|
11467
11470
|
try { if (engine && engine._agentDmClose) engine._agentDmClose(sid); } catch {}
|
|
11471
|
+
/* EKİP AJANI DURDU: bekleyen trader varsa hemen değerlendir (deadlock yok) */
|
|
11472
|
+
if (agent.role) {
|
|
11473
|
+
for (const [msid, ma] of financeState.agents) {
|
|
11474
|
+
if (ma && ma.main && ma.waitingTeam) { try { finTeamWaitTick(msid); } catch {} break; }
|
|
11475
|
+
}
|
|
11476
|
+
}
|
|
11477
|
+
/* ANA TRADER DURDU: ekip cycle'sız kaldı — kendi timer'ıyla dönmeye devam etsin */
|
|
11478
|
+
if (agent.main) {
|
|
11479
|
+
const iv = Math.max(30, Number(finCfg().intervalSec) || 120) * 1000;
|
|
11480
|
+
for (const [tsid, ta] of financeState.agents) {
|
|
11481
|
+
if (!ta || !ta.role) continue;
|
|
11482
|
+
if (engine && engine.isBusy(tsid)) continue;
|
|
11483
|
+
clearTimeout(ta.timer);
|
|
11484
|
+
ta.timer = setTimeout(() => { try { finAgentRound(String(tsid)); } catch {} }, iv);
|
|
11485
|
+
}
|
|
11486
|
+
}
|
|
11468
11487
|
finPush('trader', { state: 'idle', rounds: financeState.traderRounds });
|
|
11469
11488
|
return true;
|
|
11470
11489
|
}
|
|
@@ -11493,6 +11512,7 @@ function finTraderBrief(agent) {
|
|
|
11493
11512
|
'Bu turda: mt5_status → hesap/pozisyon/fiyat verisi → mt5_rates/mt5_indicators ile teknik okuma → değerlendirme → kararlar (veya BEKLE: sebep) → kısa rapor.',
|
|
11494
11513
|
'Önemli kararların gerekçesini mt5_note ile günlüğe yaz (haftalık performans raporu bu notları kullanır).',
|
|
11495
11514
|
'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.',
|
|
11515
|
+
'⚡HIZLI AKSİYON: onaylı fırsatta market buy/sell ile ANINDA gir (mt5_trade {symbol, side, sl, tp, riskPct}); bekleyen emir vermek ZORUNLU DEĞİL — limit/stop yalnız seviye beklemede kurulur.',
|
|
11496
11516
|
'Diğer finance/paralel ajanlarla koordinasyon için agent_dm aracı var (to: ajan başlığı anahtar kelimesi).',
|
|
11497
11517
|
agent && agent.main && !roleDef ? `İŞLEM GEÇMİŞİN:\n${finBuildDigest()}` : '',
|
|
11498
11518
|
].filter(Boolean).join('\n');
|
|
@@ -11603,8 +11623,57 @@ async function finConsultPlan(f, agent, sid) {
|
|
|
11603
11623
|
}
|
|
11604
11624
|
}
|
|
11605
11625
|
|
|
11626
|
+
/* ---------- CYCLE ORKESTRASYONU: trader turu ekip raporlarını BEKLER ----------
|
|
11627
|
+
Ana trader kendi turuna başlamadan önce koşan analiz ekibi ajanlarını
|
|
11628
|
+
(teknik/risk/macro/visual) tura sokar ve O ANKİ turları bitene kadar bekler —
|
|
11629
|
+
böylece finTeamDigest her zaman TAZE rapor taşır. Sembol işçileri beklenmez.
|
|
11630
|
+
Ekip ajanları ana trader koşarken kendi başına tur planlamaz
|
|
11631
|
+
(finFlushOnDone); sıradaki turlarını cycle başlatır. */
|
|
11632
|
+
function finTeamAgents() {
|
|
11633
|
+
const out = [];
|
|
11634
|
+
try {
|
|
11635
|
+
for (const [sid, a] of financeState.agents) {
|
|
11636
|
+
if (a && a.role) out.push({ sid: String(sid), agent: a, def: finRoleDef(a.role) });
|
|
11637
|
+
}
|
|
11638
|
+
} catch {}
|
|
11639
|
+
return out;
|
|
11640
|
+
}
|
|
11641
|
+
|
|
11642
|
+
function finTeamHasMain() {
|
|
11643
|
+
try {
|
|
11644
|
+
for (const [, a] of financeState.agents) if (a && a.main) return true;
|
|
11645
|
+
} catch {}
|
|
11646
|
+
return false;
|
|
11647
|
+
}
|
|
11648
|
+
|
|
11649
|
+
/* Takılma valfi: ekip turu bu süreyi aşarsa trader eski raporla başlar */
|
|
11650
|
+
function finTeamWaitMaxMs() {
|
|
11651
|
+
const iSec = Math.max(30, Number(finCfg().intervalSec) || 120);
|
|
11652
|
+
return Math.max(60, Math.min(300, iSec)) * 1000;
|
|
11653
|
+
}
|
|
11654
|
+
|
|
11655
|
+
/* Ekip ajanı bittiğinde/durduğunda ya da 2 sn'lik yoklamada çağrılır:
|
|
11656
|
+
bekleyen trader'ın turunu açar (rapor taze) ya da beklemeye devam eder. */
|
|
11657
|
+
function finTeamWaitTick(sid) {
|
|
11658
|
+
const agent = financeState.agents.get(String(sid));
|
|
11659
|
+
if (!agent || !agent.main || !agent.waitingTeam) return;
|
|
11660
|
+
if (agent.waitPoll) { clearTimeout(agent.waitPoll); agent.waitPoll = null; }
|
|
11661
|
+
const busy = finTeamAgents().filter((t) => engine && engine.isBusy(t.sid));
|
|
11662
|
+
const expired = Date.now() >= Number(agent.waitDeadline || 0);
|
|
11663
|
+
if (busy.length && !expired) {
|
|
11664
|
+
agent.waitPoll = setTimeout(() => { try { finTeamWaitTick(sid); } catch {} }, 2000);
|
|
11665
|
+
return;
|
|
11666
|
+
}
|
|
11667
|
+
agent.waitingTeam = false;
|
|
11668
|
+
/* MAKS BEKLEME AŞILDI: geç kalanlar rapor prefix'ine açıkça notlanır */
|
|
11669
|
+
agent.waitLateNames = expired && busy.length
|
|
11670
|
+
? busy.map((t) => (t.def ? t.def.label : t.agent.role || t.sid))
|
|
11671
|
+
: [];
|
|
11672
|
+
finAgentRound(sid, { noTeamWait: true });
|
|
11673
|
+
}
|
|
11674
|
+
|
|
11606
11675
|
/* Bir ajanın TEK turu: (opsiyonel) ana ajan planı + tur emri */
|
|
11607
|
-
function finAgentRound(sid) {
|
|
11676
|
+
function finAgentRound(sid, opts) {
|
|
11608
11677
|
const agent = financeState.agents.get(String(sid));
|
|
11609
11678
|
if (!agent || !engine) return;
|
|
11610
11679
|
/* TRADE SAATLERİ KAPISI: aralık dışında YENİ TUR BAŞLATILMAZ — ajan askıya
|
|
@@ -11620,9 +11689,36 @@ function finAgentRound(sid) {
|
|
|
11620
11689
|
/* hâlâ çalışıyor — done eventinde tekrar planlanır */
|
|
11621
11690
|
return;
|
|
11622
11691
|
}
|
|
11692
|
+
const f = finCfg();
|
|
11693
|
+
/* EKİP BEKLEMESİ SÜRÜYOR: DM uyandırması vb. turu erkene çekemez — tick açar */
|
|
11694
|
+
if (agent.main && agent.waitingTeam && !(opts && opts.noTeamWait)) return;
|
|
11695
|
+
/* CYCLE KAPISI: karar turundan ÖNCE ekip ajanlarını tura sok, O ANKİ
|
|
11696
|
+
turları bitmeden trader'ı başlatma (rapor tazeliği garantisi). */
|
|
11697
|
+
if (agent.main && !(opts && opts.noTeamWait)) {
|
|
11698
|
+
const team = finTeamAgents();
|
|
11699
|
+
if (team.length) {
|
|
11700
|
+
for (const t of team) {
|
|
11701
|
+
if (engine.isBusy(t.sid)) continue;
|
|
11702
|
+
clearTimeout(t.agent.timer);
|
|
11703
|
+
t.agent.timer = null;
|
|
11704
|
+
try { finAgentRound(t.sid); } catch {}
|
|
11705
|
+
}
|
|
11706
|
+
const busy = team.filter((t) => engine.isBusy(t.sid));
|
|
11707
|
+
if (busy.length) {
|
|
11708
|
+
agent.waitingTeam = true;
|
|
11709
|
+
agent.waitDeadline = Date.now() + finTeamWaitMaxMs();
|
|
11710
|
+
/* danışma planı bekleme SIRASINDA üretilir — tur gecikmesi gizlenir */
|
|
11711
|
+
if (!agent.consultPromise && f.consultChat !== false) {
|
|
11712
|
+
agent.consultPromise = finConsultPlan(f, agent, String(sid)).catch(() => '');
|
|
11713
|
+
}
|
|
11714
|
+
finPush('trader', { state: 'team', round: (Number(agent.round) || 0) + 1, waiting: busy.length, maxSec: Math.round(finTeamWaitMaxMs() / 1000) });
|
|
11715
|
+
agent.waitPoll = setTimeout(() => { try { finTeamWaitTick(sid); } catch {} }, 2000);
|
|
11716
|
+
return;
|
|
11717
|
+
}
|
|
11718
|
+
}
|
|
11719
|
+
}
|
|
11623
11720
|
agent.round += 1;
|
|
11624
11721
|
if (agent.main) financeState.traderRounds = agent.round;
|
|
11625
|
-
const f = finCfg();
|
|
11626
11722
|
const roleDef = finRoleDef(agent.role);
|
|
11627
11723
|
let shadow = false;
|
|
11628
11724
|
try {
|
|
@@ -11640,7 +11736,7 @@ function finAgentRound(sid) {
|
|
|
11640
11736
|
? 'SHADOW MOD AÇIK: emir GÖNDERİLMEZ — kararını teziyle raporla (günlüğe yazılır).'
|
|
11641
11737
|
: 'İşlem açabilirsin — limitlere uy, SL\u2019siz pozisyon bırakma.';
|
|
11642
11738
|
const focus = agent.symbols.length ? `Odak: ${agent.symbols.join(', ')}. ` : '';
|
|
11643
|
-
const round = `FINANCE TUR #${agent.round}: ${focus}hesap + pozisyonlar + fiyatları çek; ${roleDef ? 'rolüne uygun analiz yap (mt5_rates/mt5_indicators ile) ve öneri ver.' : 'açık pozisyonları yönet (SL/TP güncelle, hedefe ulaşanı kapat); mt5_rates/mt5_indicators ile yeni fırsatları değerlendir.'} ${auto} Önemli kararların gerekçesini mt5_note ile günlüğe yaz. Kısa rapor ver.`;
|
|
11739
|
+
const round = `FINANCE TUR #${agent.round}: ${focus}hesap + pozisyonlar + fiyatları çek; ${roleDef ? 'rolüne uygun analiz yap (mt5_rates/mt5_indicators ile) ve öneri ver.' : 'açık pozisyonları yönet (SL/TP güncelle, hedefe ulaşanı kapat); mt5_rates/mt5_indicators ile yeni fırsatları değerlendir. ⚡Onaylı fırsatta market buy/sell ile ANINDA gir (bekleyen emir ZORUNLU DEĞİL); lot için volume yerine riskPct+sl yeter.'} ${auto} Önemli kararların gerekçesini mt5_note ile günlüğe yaz. Kısa rapor ver.`;
|
|
11644
11740
|
const launch = (planBlock) => {
|
|
11645
11741
|
if (!financeState.agents.has(String(sid))) return;
|
|
11646
11742
|
const ok = engine.send(sid, planBlock + round, { userAction: false });
|
|
@@ -11659,14 +11755,23 @@ function finAgentRound(sid) {
|
|
|
11659
11755
|
if (agent.main) {
|
|
11660
11756
|
const team = finTeamDigest();
|
|
11661
11757
|
if (team) teamPrefix = '[EKİP RAPORLARI — koşan uzman ajanların son raporları; kararında dikkate al]\n' + team + '\n\n';
|
|
11758
|
+
/* MAKS BEKLEME AŞILDI: geç kalan ajanlar açıkça işaretlenir */
|
|
11759
|
+
const late = Array.isArray(agent.waitLateNames) ? agent.waitLateNames.filter(Boolean) : [];
|
|
11760
|
+
if (late.length) {
|
|
11761
|
+
teamPrefix = `[EKİP NOTU] Şu ajanlar hâlâ analizde — raporları BİR ÖNCEKİ turdan: ${late.join(', ')}. Gecikmeyi kararında dikkate al.\n\n` + teamPrefix;
|
|
11762
|
+
agent.waitLateNames = [];
|
|
11763
|
+
}
|
|
11662
11764
|
}
|
|
11663
11765
|
if (f.consultChat === false || roleDef) {
|
|
11664
11766
|
/* danışma kapalı ya da rol ajanı (plan trader'a yöneliktir): tur doğrudan başlar */
|
|
11665
11767
|
launch(teamPrefix);
|
|
11666
11768
|
return;
|
|
11667
11769
|
}
|
|
11770
|
+
/* Danışma planı ekip beklemesi SIRASINDA üretildiyse hazır olanı kullan */
|
|
11771
|
+
const consult = agent.consultPromise || finConsultPlan(f, agent, String(sid));
|
|
11772
|
+
agent.consultPromise = null;
|
|
11668
11773
|
if (agent.main) finPush('trader', { state: 'consult', round: agent.round });
|
|
11669
|
-
|
|
11774
|
+
consult
|
|
11670
11775
|
.then((plan) => launch(teamPrefix + (plan ? `[ANA AJAN PLANI — bu turun varsayılan stratejisi; strateji notuyla çelişirse not önceliklidir]\n${plan}\n\n` : '')))
|
|
11671
11776
|
.catch(() => launch(teamPrefix));
|
|
11672
11777
|
}
|
|
@@ -11705,6 +11810,12 @@ function finFlushOnDone(ev) {
|
|
|
11705
11810
|
finAgentStop(sid, String(ev.reason || 'kullanıcı durdurdu'));
|
|
11706
11811
|
return;
|
|
11707
11812
|
}
|
|
11813
|
+
/* EKİP TURU BİTTİ: bekleyen trader varsa ANINDA değerlendir (rapor taze) */
|
|
11814
|
+
if (agent.role) {
|
|
11815
|
+
for (const [msid, ma] of financeState.agents) {
|
|
11816
|
+
if (ma && ma.main && ma.waitingTeam) { try { finTeamWaitTick(msid); } catch {} break; }
|
|
11817
|
+
}
|
|
11818
|
+
}
|
|
11708
11819
|
clearTimeout(agent.timer);
|
|
11709
11820
|
/* TUR SIRASINDA GELEN OLAY/DM: tur bitti → interval BEKLENMEDEN yeni tur
|
|
11710
11821
|
(dmInbox'taki olay mesajı bu turda okunur) */
|
|
@@ -11714,6 +11825,10 @@ function finFlushOnDone(ev) {
|
|
|
11714
11825
|
agent.timer = setTimeout(() => { try { finAgentRound(sid); } catch {} }, 800);
|
|
11715
11826
|
return;
|
|
11716
11827
|
}
|
|
11828
|
+
/* CYCLE MODU: ana trader koşarken ekip ajanı KENDİ turunu planlamaz —
|
|
11829
|
+
sıradaki turu trader'ın cycle'ı başlatır (rapor tazeliği). Trader yoksa
|
|
11830
|
+
ekip kendi timer'ıyla dönmeye devam eder. */
|
|
11831
|
+
if (agent.role && finTeamHasMain()) return;
|
|
11717
11832
|
const f = finCfg();
|
|
11718
11833
|
const iv = Math.max(30, Number(f.intervalSec) || 120) * 1000;
|
|
11719
11834
|
financeState.lastRoundAt = Date.now();
|
|
@@ -11883,8 +11998,10 @@ ipcMain.handle('finance:settings', async (_e, patch) => {
|
|
|
11883
11998
|
koşan tur bitince zaten finFlushOnDone yeni aralığı okur. */
|
|
11884
11999
|
if (p.intervalSec !== undefined && financeState.agents) {
|
|
11885
12000
|
const iv = Math.max(30, Math.round(Number(f.intervalSec) || 120)) * 1000;
|
|
12001
|
+
const hasMain = finTeamHasMain();
|
|
11886
12002
|
for (const [sid, a] of financeState.agents) {
|
|
11887
12003
|
if (!a || !engine || engine.isBusy(sid)) continue;
|
|
12004
|
+
if (a.role && hasMain) continue; /* cycle modu: ekip turunu trader başlatır */
|
|
11888
12005
|
clearTimeout(a.timer);
|
|
11889
12006
|
a.timer = setTimeout(() => { try { finAgentRound(String(sid)); } catch {} }, iv);
|
|
11890
12007
|
}
|
package/src/renderer/renderer.js
CHANGED
|
@@ -10162,6 +10162,7 @@ function finOnEvent(ev) {
|
|
|
10162
10162
|
finSetDot(ev.connected ? true : 'busy', { error: ev.error });
|
|
10163
10163
|
} else if (ev.fn === 'trader') {
|
|
10164
10164
|
if (ev.state === 'running') finLogLine('[trader] tur #' + (ev.round || 0) + ' başladı');
|
|
10165
|
+
else if (ev.state === 'team') finLogLine('[trader] ekip raporları bekleniyor — ' + (ev.waiting || 0) + ' ajan turunu bitirsin (max ' + (ev.maxSec || '?') + ' sn)');
|
|
10165
10166
|
else if (ev.state === 'idle') finLogLine('[trader] tur #' + (ev.round || 0) + ' bitti — sıradaki tur ~' + (ev.nextInSec || '?') + ' sn');
|
|
10166
10167
|
else if (ev.state === 'hours') finLogLine('[trader] trade saatleri dışı — ajan askıda (kontrol ~' + (ev.nextInSec || 60) + ' sn)');
|
|
10167
10168
|
else if (ev.state === 'stopped') finLogLine('[trader] durduruldu');
|