beast-agent 2.63.3 → 2.63.4
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 +5 -3
- package/src/main.js +93 -25
- package/src/renderer/renderer.js +4 -1
package/package.json
CHANGED
package/src/agent/engine.js
CHANGED
|
@@ -2074,13 +2074,14 @@ class Engine {
|
|
|
2074
2074
|
: '') +
|
|
2075
2075
|
' Bunları aşıp araç kullanma; sistem zaten reddeder (lot min lot altına inemez, max lot üstüne çıkamaz).\n'
|
|
2076
2076
|
: '') +
|
|
2077
|
+
'TUR RİTMİ (yalnız trader kararı): mt5_limits {action:"set", intervalSec, intervalForMin} ile tur aralığını ayarlarsın — sert hareket/haber anında geçici hızlan (ör. 45-60 sn × 10-20 dk), sakinleşince geri çek (ör. 180-300 sn); süre dolunca taban aralığa OTOMATİK dönülür. SÜREKLİ en düşük aralıkta kalma — API/maliyet limitini koru; hız modu sınırları sistemce zorlanır.\n' +
|
|
2077
2078
|
'RİSK DİSİPLİNİ:\n' +
|
|
2078
2079
|
'- SL\u2019siz pozisyon BIRAKMA: açtığın her işlemde mantıklı bir SL koy; SL\u2019siz kalan pozisyonu mt5_modify ile tamamla.\n' +
|
|
2079
2080
|
'- KÂR KORUMA (SİSTEM OTOMATİK): kâr 0.3R\'ye ulaşınca SL, görülen en iyi kârın 0.15R gerisine kilitlenir — kâr eksiye dönmez. Bu yüzden kârı erken koru; hedefe ulaşmayan işlemde bile kârı geri verme.\n' +
|
|
2080
2081
|
'- TP İÇİN RR ≥ 1.5 ŞARTI YOK: scalp/hızlı işlemlerde TP 0.3R-0.5R olabilir. Kısmi kâr alımı SERBEST ve TEŞVİK EDİLİR: 0.3-0.5R\'de pozisyonun bir kısmını mt5_close {percent, kind:"partial_tp"} ile realize et, kalanı korumalı trailing ile taşı. Amaç: sık işlem + hızlı kâr toplama; kârı masada bekletme.\n' +
|
|
2081
2082
|
'- Martingale/kademeli lot artışı YASAK; kaybı geri kovalama (revenge trade) YASAK.\n' +
|
|
2082
2083
|
'- Emin olmadığında İŞLEM YOK — "BEKLE: <sebep>" yaz. Sık işlem tek başına iyi işlem değil; ama onaylı fırsatta HIZLI gir, kârı hızlı topla.\n' +
|
|
2083
|
-
'-
|
|
2084
|
+
'- LOT KORKUSU YOK — önemli olan LOT DEĞİL, STOP YERİ ve risktir: SL yakın ve setup netse yüksek lot NORMALDİR (boyut zaten risk % + SL mesafesinden hesaplanır; sembol tavanı trader kararıdır). Tek işlemde serbest marjın tamamını riske atma; sık işlem için lotu değil, TUR RİTMİNİ (mt5_limits intervalSec) ve kısmi kâr alımını kullan.\n' +
|
|
2084
2085
|
(session && session.financeLearn ? `SEMBOL BAZLI ÖĞRENME HAFIZAN (otomatik istatistik + kendi derslerin — kararlarında kullan):\n${session.financeLearn}\n` : '') +
|
|
2085
2086
|
'ÖĞRENME DÖNGÜSÜ (SEÇİCİ — ders çıkarmak zorunlu DEĞİL): yalnız GERÇEKTEN öğrenilmiş, tekrar kullanılabilir, kanıtlı bir içgörü varsa tek KISA cümleyle kaydet: mt5_ogrenme {action:"add", symbol, text, kind}. İyi ders: "XAUUSD M5 EMA50 üstü Londra açılışı momentumu 3/4 işledi" gibi somut, sebep-sonuç içeren, en fazla ~20 kelimelik cümle. YASAK: her kapanışa ders yazmak, günlük/rapor tarzı uzun metin ("bugün şunu yaptım"), genel laf ("dikkatli olmalıyım"), tekrar. Emin değilsen HİÇ ders yazma — hafızayı çöple doldurma; günde en fazla 2-3 ders. Yeni karar öncesi mt5_ogrenme {action:"stats", symbol} ya da list ile o sembolün geçmişini oku (kalıcı özet + son dersler) — aynı hatayı tekrarlama, işleyen deseni kullan. Hafıza kendini sadeleştirir: eski dersler otomatik özetlenir ve süresi geçenler unutulur; gerekirse mt5_ogrenme {action:"compact", symbol} ile hemen özetlet, geçersiz dersi remove/clear ile sil.\n' +
|
|
2086
2087
|
(session && session.financeStrategy ? `SAHİBİNİN STRATEJİ NOTU (önceliklidir):\n${session.financeStrategy}\n` : '') +
|
|
@@ -275,7 +275,7 @@ const definitions = NAMES.map((name) => {
|
|
|
275
275
|
},
|
|
276
276
|
mt5_limits: {
|
|
277
277
|
description:
|
|
278
|
-
'LOT / POZİSYON LİMİTLERİNİ oku ve GÜNCELLE — trader karar mercii: mt5_limits {action:"get"|"set", symbol?, minLot?, maxLot?, maxPositions?, reset?}. get: genel min lot / max lot / max eşzamanlı pozisyon + SEMBOL BAZLI limitler + işlem riski %. GENEL set: minLot/maxLot/maxPositions. SEMBOL BAZLI set: symbol ver (ör. {action:"set", symbol:"XAUUSD", minLot:0.02, maxLot:0.5}) — her sembolün min/max lotunu kendi karakterine göre SEN belirle (volatilite, spread, marj); sembol limiti genel aralığın dışına çıkamaz (genel taban/tavan kelepçeler). Sembolü genele döndürmek için {action:"set", symbol:"XAUUSD", reset:true}. set: yalnız ana trader (ve finance sohbet copilot\'ı) kullanabilir — rol/işçi ajanları değiştiremez. Değişiklik ANINDA panelde ve sonraki turda geçerli olur. Kural: minLot maxLot\'u aşamaz.',
|
|
278
|
+
'LOT / POZİSYON / RİTİM LİMİTLERİNİ oku ve GÜNCELLE — trader karar mercii: mt5_limits {action:"get"|"set", symbol?, minLot?, maxLot?, maxPositions?, intervalSec?, intervalForMin?, reset?}. get: genel min lot / max lot / max eşzamanlı pozisyon + SEMBOL BAZLI limitler + efektif tur aralığı + işlem riski %. GENEL set: minLot/maxLot/maxPositions. SEMBOL BAZLI set: symbol ver (ör. {action:"set", symbol:"XAUUSD", minLot:0.02, maxLot:0.5}) — her sembolün min/max lotunu kendi karakterine göre SEN belirle (volatilite, spread, marj); sembol limiti genel aralığın dışına çıkamaz (genel taban/tavan kelepçeler). Sembolü genele döndürmek için {action:"set", symbol:"XAUUSD", reset:true}. TUR RİTMİ: intervalSec (30-3600 sn) + intervalForMin (1-240 dk) → geçici hızlanma; süre bitince taban aralığa OTOMATİK döner (ör. {action:"set", intervalSec:45, intervalForMin:15}). intervalForMin yoksa kalıcı temel aralık değişir. Sert hareket/haber anında hızlan, sakinleşince geri çek — SÜREKLİ en düşük aralıkta kalma (API/maliyet limiti); sınırlar sistemce zorlanır. set: yalnız ana trader (ve finance sohbet copilot\'ı) kullanabilir — rol/işçi ajanları değiştiremez. Değişiklik ANINDA panelde ve sonraki turda geçerli olur. Kural: minLot maxLot\'u aşamaz.',
|
|
279
279
|
parameters: {
|
|
280
280
|
type: 'object',
|
|
281
281
|
properties: {
|
|
@@ -284,6 +284,8 @@ const definitions = NAMES.map((name) => {
|
|
|
284
284
|
minLot: { type: 'number', description: 'set: yeni alt sınır (0.01-100)' },
|
|
285
285
|
maxLot: { type: 'number', description: 'set: yeni üst sınır (0.01-100)' },
|
|
286
286
|
maxPositions: { type: 'number', description: 'set: eşzamanlı pozisyon tavanı (1-20) — yalnız GENEL (sembol ile verilemez)' },
|
|
287
|
+
intervalSec: { type: 'number', description: 'set: tur aralığı saniye (30-3600) — intervalForMin ile geçici hız modu, tek başına kalıcı temel aralık' },
|
|
288
|
+
intervalForMin: { type: 'number', description: 'set: hız modu süresi dakika (1-240) — süre bitince taban aralığa otomatik döner' },
|
|
287
289
|
reset: { type: 'boolean', description: 'set + symbol: true → sembol limitini kaldır, genel aralığa dön' },
|
|
288
290
|
},
|
|
289
291
|
required: ['action'],
|
|
@@ -578,7 +580,7 @@ const handlers = {
|
|
|
578
580
|
}
|
|
579
581
|
if (action === 'set') {
|
|
580
582
|
const patch = {};
|
|
581
|
-
for (const k of ['minLot', 'maxLot', 'maxPositions']) {
|
|
583
|
+
for (const k of ['minLot', 'maxLot', 'maxPositions', 'intervalSec', 'intervalForMin']) {
|
|
582
584
|
if (args[k] !== undefined && args[k] !== null && args[k] !== '') patch[k] = Number(args[k]);
|
|
583
585
|
}
|
|
584
586
|
/* SEMBOL BAZLI LOT LİMİTİ: symbol verilirse trader o sembolün min/max
|
|
@@ -588,7 +590,7 @@ const handlers = {
|
|
|
588
590
|
const reset = args.reset === true || String(args.reset || '').toLowerCase() === 'true';
|
|
589
591
|
if (reset) patch.reset = true;
|
|
590
592
|
if (!Object.keys(patch).length || (sym && patch.minLot === undefined && patch.maxLot === undefined && !reset)) {
|
|
591
|
-
return { ok: false, error: 'set için en az bir alan ver: minLot / maxLot / maxPositions (sembol bazlıda minLot/maxLot ya da reset:true)' };
|
|
593
|
+
return { ok: false, error: 'set için en az bir alan ver: minLot / maxLot / maxPositions / intervalSec (sembol bazlıda minLot/maxLot ya da reset:true)' };
|
|
592
594
|
}
|
|
593
595
|
return await limitsApi.set(patch, ctx || {});
|
|
594
596
|
}
|
package/src/main.js
CHANGED
|
@@ -9402,6 +9402,11 @@ const financeState = {
|
|
|
9402
9402
|
reportCheckAt: 0,
|
|
9403
9403
|
flattening: false,
|
|
9404
9404
|
breachBusy: false,
|
|
9405
|
+
/* TUR RİTMİ (trader kararı): sert hareket/haber anında geçici hızlanma.
|
|
9406
|
+
pace = { sec, until, base } — süre dolunca otomatik taban aralığa döner;
|
|
9407
|
+
kalıcı değişiklik settings.finance.intervalSec'e yazılır. */
|
|
9408
|
+
pace: { sec: 0, until: 0, base: 0 },
|
|
9409
|
+
paceTimer: null,
|
|
9405
9410
|
};
|
|
9406
9411
|
|
|
9407
9412
|
function financeDir() {
|
|
@@ -11270,8 +11275,51 @@ try {
|
|
|
11270
11275
|
Ana trader / finance sohbet oturumu min lot-max lot-pozisyon tavanını
|
|
11271
11276
|
güncelleyebilir; rol/işçi ajanları yalnız okur. Değişiklik ayarlara yazılır,
|
|
11272
11277
|
koşan oturumlara ANINDA işlenir ve panele duyurulur. */
|
|
11278
|
+
/* TUR RİTMİ: trader sert harekette geçici hızlanabilir — efektif aralık (sn).
|
|
11279
|
+
Süre dolunca kendiliğinden taban aralığa döner (API/maliyet limiti korunur). */
|
|
11280
|
+
function finPaceSec() {
|
|
11281
|
+
const f = finCfg();
|
|
11282
|
+
const base = Math.max(30, Math.min(3600, Math.round(Number(f.intervalSec) || 120)));
|
|
11283
|
+
const p = financeState.pace;
|
|
11284
|
+
if (p && Number(p.until) > Date.now() && Number(p.sec) >= 30) {
|
|
11285
|
+
return Math.max(30, Math.min(3600, Math.round(Number(p.sec))));
|
|
11286
|
+
}
|
|
11287
|
+
return base;
|
|
11288
|
+
}
|
|
11289
|
+
|
|
11290
|
+
/* Koşan ajan zamanlayıcılarını efektif ritme göre yeniden kur; hız modunun
|
|
11291
|
+
bitişini de zamanla — süre dolunca taban aralığa OTOMATİK dönüş. */
|
|
11292
|
+
function finRescheduleAgents() {
|
|
11293
|
+
const iv = finPaceSec() * 1000;
|
|
11294
|
+
if (financeState.paceTimer) { clearTimeout(financeState.paceTimer); financeState.paceTimer = null; }
|
|
11295
|
+
const p = financeState.pace;
|
|
11296
|
+
if (p && Number(p.until) > Date.now() && Number(p.sec) > 0) {
|
|
11297
|
+
const left = Math.max(1000, Number(p.until) - Date.now() + 1000);
|
|
11298
|
+
financeState.paceTimer = setTimeout(() => {
|
|
11299
|
+
financeState.pace = { sec: 0, until: 0, base: 0 };
|
|
11300
|
+
try { financeLog('[ritim] hız modu bitti — taban tur aralığı ' + finPaceSec() + ' sn'); } catch {}
|
|
11301
|
+
try { finRescheduleAgents(); } catch {}
|
|
11302
|
+
try { finPush('limits', { ...finLimitsSnapshot(), note: 'hız modu bitti — taban tur aralığı ' + finPaceSec() + ' sn' }); } catch {}
|
|
11303
|
+
}, left);
|
|
11304
|
+
}
|
|
11305
|
+
if (!engine || !financeState.agents) return;
|
|
11306
|
+
const hasMain = finTeamHasMain();
|
|
11307
|
+
for (const [sid, a] of financeState.agents) {
|
|
11308
|
+
if (!a) continue;
|
|
11309
|
+
if (a.role && hasMain) continue; /* cycle modu: trader turu başlatır */
|
|
11310
|
+
if (engine.isBusy(sid)) continue; /* tur bitince finFlushOnDone yeni ritmi okur */
|
|
11311
|
+
clearTimeout(a.timer);
|
|
11312
|
+
a.timer = setTimeout(() => { try { finAgentRound(String(sid)); } catch {} }, iv);
|
|
11313
|
+
}
|
|
11314
|
+
if (financeState.traderSid) {
|
|
11315
|
+
const a = financeState.agents.get(String(financeState.traderSid));
|
|
11316
|
+
finPush('trader', { state: 'idle', round: (a && a.round) || 0, nextInSec: iv / 1000 });
|
|
11317
|
+
}
|
|
11318
|
+
}
|
|
11319
|
+
|
|
11273
11320
|
function finLimitsSnapshot() {
|
|
11274
11321
|
const f = finCfg();
|
|
11322
|
+
const paceOn = Number(financeState.pace && financeState.pace.until) > Date.now();
|
|
11275
11323
|
return {
|
|
11276
11324
|
minLot: Number(f.minLot) || 0.01,
|
|
11277
11325
|
maxLot: Number(f.maxLot) || 0.1,
|
|
@@ -11279,6 +11327,10 @@ function finLimitsSnapshot() {
|
|
|
11279
11327
|
riskPerTradePct: Number(f.riskPerTradePct) || 0,
|
|
11280
11328
|
/* SEMBOL BAZLI LOT LİMİTLERİ (trader kararı) — genel aralığı daraltır */
|
|
11281
11329
|
symbols: { ...(f.symbolLimits && typeof f.symbolLimits === 'object' ? f.symbolLimits : {}) },
|
|
11330
|
+
/* TUR RİTMİ: efektif aralık + taban + hız modu bitişi */
|
|
11331
|
+
intervalSec: finPaceSec(),
|
|
11332
|
+
intervalBase: Math.max(30, Math.min(3600, Math.round(Number(f.intervalSec) || 120))),
|
|
11333
|
+
paceUntil: paceOn ? Number(financeState.pace.until) : 0,
|
|
11282
11334
|
};
|
|
11283
11335
|
}
|
|
11284
11336
|
|
|
@@ -11295,7 +11347,7 @@ function finLimitsSessionAllowed(sid) {
|
|
|
11295
11347
|
|
|
11296
11348
|
function finSyncLimitsToSessions(extra) {
|
|
11297
11349
|
const lim = finLimitsSnapshot();
|
|
11298
|
-
const apply = { minLot: lim.minLot, maxLot: lim.maxLot, maxPositions: lim.maxPositions, symbolLimits: lim.symbols };
|
|
11350
|
+
const apply = { minLot: lim.minLot, maxLot: lim.maxLot, maxPositions: lim.maxPositions, symbolLimits: lim.symbols, intervalSec: lim.intervalSec, intervalBase: lim.intervalBase, paceUntil: lim.paceUntil };
|
|
11299
11351
|
if (engine) {
|
|
11300
11352
|
try {
|
|
11301
11353
|
for (const [sid] of financeState.agents) {
|
|
@@ -11323,8 +11375,8 @@ function finLimitsSet(patch, ctx) {
|
|
|
11323
11375
|
symbol) → sembol limiti kaldırılır, genel aralık geçerli olur. */
|
|
11324
11376
|
const sym = String(patch.symbol || '').trim().toUpperCase();
|
|
11325
11377
|
if (sym) {
|
|
11326
|
-
if (patch.maxPositions !== undefined) {
|
|
11327
|
-
return { ok: false, error: 'maxPositions sembol bazlı değil — symbol vermeden genel
|
|
11378
|
+
if (patch.maxPositions !== undefined || patch.intervalSec !== undefined || patch.intervalForMin !== undefined) {
|
|
11379
|
+
return { ok: false, error: 'maxPositions ve tur ritmi (intervalSec) sembol bazlı değil — symbol vermeden genel olarak ayarla' };
|
|
11328
11380
|
}
|
|
11329
11381
|
const hasMin = patch.minLot !== undefined && patch.minLot !== null && patch.minLot !== '';
|
|
11330
11382
|
const hasMax = patch.maxLot !== undefined && patch.maxLot !== null && patch.maxLot !== '';
|
|
@@ -11381,16 +11433,39 @@ function finLimitsSet(patch, ctx) {
|
|
|
11381
11433
|
if (!(v >= 1) || v > 20) return { ok: false, error: 'maxPositions 1-20 arasında olmalı' };
|
|
11382
11434
|
f.maxPositions = v;
|
|
11383
11435
|
}
|
|
11436
|
+
/* TUR RİTMİ (trader kararı): sert hareket/haber anında geçici hızlanma.
|
|
11437
|
+
intervalForMin > 0 → geçici (süre dolunca taban aralığa otomatik döner);
|
|
11438
|
+
yoksa kalıcı temel aralık güncellenir. Alt sınır 30 sn, hız modu ≤ 240 dk:
|
|
11439
|
+
API/maliyet limiti bilinçli — sürekli en düşük aralıkta kalmak YASAK. */
|
|
11440
|
+
let intervalChanged = false;
|
|
11441
|
+
if (patch.intervalSec !== undefined) {
|
|
11442
|
+
const base = Math.max(30, Math.min(3600, Math.round(Number(f.intervalSec) || 120)));
|
|
11443
|
+
const sec = Math.max(30, Math.min(3600, Math.round(Number(patch.intervalSec) || base)));
|
|
11444
|
+
const mins = Math.max(0, Math.min(240, Math.round(Number(patch.intervalForMin) || 0)));
|
|
11445
|
+
if (mins > 0 && sec < base) {
|
|
11446
|
+
financeState.pace = { sec, until: Date.now() + mins * 60 * 1000, base };
|
|
11447
|
+
notes.push(`hız modu: ${sec} sn × ${mins} dk (sonra taban ${base} sn'e döner)`);
|
|
11448
|
+
} else {
|
|
11449
|
+
f.intervalSec = sec;
|
|
11450
|
+
if (Number(financeState.pace && financeState.pace.until) > Date.now()) financeState.pace = { sec: 0, until: 0, base: 0 };
|
|
11451
|
+
notes.push(`temel tur aralığı: ${sec} sn`);
|
|
11452
|
+
}
|
|
11453
|
+
intervalChanged = true;
|
|
11454
|
+
} else if (patch.intervalForMin !== undefined) {
|
|
11455
|
+
notes.push('intervalForMin için intervalSec de verilmeli');
|
|
11456
|
+
}
|
|
11384
11457
|
if (f.minLot > f.maxLot) {
|
|
11385
11458
|
notes.push(`minLot (${f.minLot}) maxLot'tan (${f.maxLot}) büyüktü → minLot ${f.maxLot} yapıldı`);
|
|
11386
11459
|
f.minLot = f.maxLot;
|
|
11387
11460
|
}
|
|
11388
11461
|
try { saveSettings(); } catch {}
|
|
11462
|
+
if (intervalChanged) { try { finRescheduleAgents(); } catch {} }
|
|
11389
11463
|
finSyncLimitsToSessions();
|
|
11390
|
-
const
|
|
11464
|
+
const paceOn = Number(financeState.pace && financeState.pace.until) > Date.now();
|
|
11465
|
+
const line = `⚙️ LİMİTLER GÜNCELLENDİ: min lot ${f.minLot} · max lot ${f.maxLot} · max pozisyon ${f.maxPositions}${intervalChanged ? ` · tur ${finPaceSec()} sn${paceOn ? ' (hız modu)' : ''}` : ''}${sid ? ' (ajan kararı)' : ''}`;
|
|
11391
11466
|
financeLog('[limit] ' + line);
|
|
11392
11467
|
financeNotify(line, 'limit', true);
|
|
11393
|
-
try { finJournal({ kind: 'limits', minLot: f.minLot, maxLot: f.maxLot, maxPositions: f.maxPositions, sid }); } catch {}
|
|
11468
|
+
try { finJournal({ kind: 'limits', minLot: f.minLot, maxLot: f.maxLot, maxPositions: f.maxPositions, intervalSec: finPaceSec(), paceUntil: paceOn ? financeState.pace.until : 0, sid }); } catch {}
|
|
11394
11469
|
return { ok: true, limits: finLimitsSnapshot(), note: notes.length ? notes.join('; ') : undefined };
|
|
11395
11470
|
}
|
|
11396
11471
|
|
|
@@ -12272,7 +12347,10 @@ function finApplyTraderFields(s, symbolsOverride, role, isMain) {
|
|
|
12272
12347
|
s.financeShadow = !!f.shadowMode; /* shadow modda işlem araçları emir göndermez */
|
|
12273
12348
|
{
|
|
12274
12349
|
const lim = finLimitsSnapshot();
|
|
12275
|
-
s.financeLimits = {
|
|
12350
|
+
s.financeLimits = {
|
|
12351
|
+
minLot: lim.minLot, maxLot: lim.maxLot, maxPositions: lim.maxPositions,
|
|
12352
|
+
symbolLimits: lim.symbols, intervalSec: lim.intervalSec, intervalBase: lim.intervalBase, paceUntil: lim.paceUntil,
|
|
12353
|
+
};
|
|
12276
12354
|
}
|
|
12277
12355
|
/* ZORUNLU TEK skill: rol ajanı → roleSkills[rol], ana trader → roleSkills.trader */
|
|
12278
12356
|
const skillKey = r || (s.financePlaybook ? 'trader' : '');
|
|
@@ -12351,7 +12429,7 @@ function finAgentStop(sid, reason, opts) {
|
|
|
12351
12429
|
}
|
|
12352
12430
|
/* ANA TRADER DURDU: ekip cycle'sız kaldı — kendi timer'ıyla dönmeye devam etsin */
|
|
12353
12431
|
if (agent.main) {
|
|
12354
|
-
const iv =
|
|
12432
|
+
const iv = finPaceSec() * 1000;
|
|
12355
12433
|
for (const [tsid, ta] of financeState.agents) {
|
|
12356
12434
|
if (!ta || !ta.role) continue;
|
|
12357
12435
|
if (engine && engine.isBusy(tsid)) continue;
|
|
@@ -12374,7 +12452,7 @@ function finTraderBrief(agent) {
|
|
|
12374
12452
|
return [
|
|
12375
12453
|
`Beast Finance ${who} başlatıldı — ilk tur: strateji çerçeveni kur ve piyasa taramasını yap.`,
|
|
12376
12454
|
`Odak semboller: ${syms || '(boş — mt5_status ile terminale bak, mantıklı semboller seç)'}`,
|
|
12377
|
-
`Tur aralığı: ${f.intervalSec} sn · Lot aralığı: ${f.minLot}–${f.maxLot} (genel taban/tavan; sembol bazlı limit daraltır) · Max eşzamanlı pozisyon: ${f.maxPositions}`,
|
|
12455
|
+
`Tur aralığı: ${finPaceSec()} sn${Number(financeState.pace && financeState.pace.until) > Date.now() ? ` (HIZ MODU — taban ${f.intervalSec} sn)` : ''} · Lot aralığı: ${f.minLot}–${f.maxLot} (genel taban/tavan; sembol bazlı limit daraltır) · Max eşzamanlı pozisyon: ${f.maxPositions}`,
|
|
12378
12456
|
(() => {
|
|
12379
12457
|
const rows = Object.entries(f.symbolLimits || {}).map(([s, v]) => {
|
|
12380
12458
|
const mn = Number(v && v.minLot) > 0 ? Number(v.minLot) : Number(f.minLot);
|
|
@@ -12384,11 +12462,11 @@ function finTraderBrief(agent) {
|
|
|
12384
12462
|
return rows.length ? `SEMBOL LOT LİMİTLERİN (senin kararın): ${rows.join(' · ')}` : '';
|
|
12385
12463
|
})(),
|
|
12386
12464
|
agent && agent.main
|
|
12387
|
-
? `LİMİT YETKİN:
|
|
12465
|
+
? `LİMİT+RİTİM YETKİN: mt5_limits ile SEN güncellersin (anında geçerli): genel {action:"set", minLot?, maxLot?, maxPositions?}; SEMBOL BAZLI {action:"set", symbol:"XAUUSD", minLot?, maxLot?} — her sembolün min/max lotunu kendi karakterine göre SEN belirle (volatilite, spread, marj); sembolü genele döndürmek için {action:"set", symbol:"XAUUSD", reset:true}. TUR RİTMİ: {action:"set", intervalSec:45, intervalForMin:15} → sert hareket/haber anında geçici hızlan, süre bitince taban aralığa OTOMATİK döner; sakinleşince geri çek (ör. 180-300 sn) — SÜREKLİ en düşük aralıkta kalma (API/maliyet limiti).`
|
|
12388
12466
|
: '',
|
|
12389
12467
|
roleDef
|
|
12390
12468
|
? `UZMANLIK: ${roleDef.desc} — raporlarını bu çerçevede yaz; İŞLEM AÇMA, yalnız analiz + net öneri üret.`
|
|
12391
|
-
: 'Otomatik işlem AÇIK (daima): 6 emir tipinin HEPSİ açık — buy_market/sell_market (anlık piyasa), buy_limit/sell_limit ve buy_stop/sell_stop (bekleyen; price zorunlu). mt5_trade ya da mt5_pending İKİSİ de tüm tipleri kabul eder; ayrıca mt5_close/mt5_modify/mt5_cancel açık (limitler sistemce zorlanır). KISMİ KAPATMA yetkisi: kısmi TP (kâr al) ve kısmi stop (zarar kes) — mt5_close {percent, kind:"partial_tp"|"partial_sl"}; otomatik DEĞİL, gerek görürsen sen kullan. ALARM: mt5_alerts ile kurarken modu SEN seç — mode:"once" tek seferlik, mode:"repeat" + cooldownMin (dk) tekrarlı. Lot için mt5_risksize hesapla ya da mt5_trade’e riskPct ver; SL/TP broker stops_level mesafesine uymalı.',
|
|
12469
|
+
: 'Otomatik işlem AÇIK (daima): 6 emir tipinin HEPSİ açık — buy_market/sell_market (anlık piyasa), buy_limit/sell_limit ve buy_stop/sell_stop (bekleyen; price zorunlu). mt5_trade ya da mt5_pending İKİSİ de tüm tipleri kabul eder; ayrıca mt5_close/mt5_modify/mt5_cancel açık (limitler sistemce zorlanır). KISMİ KAPATMA yetkisi: kısmi TP (kâr al) ve kısmi stop (zarar kes) — mt5_close {percent, kind:"partial_tp"|"partial_sl"}; otomatik DEĞİL, gerek görürsen sen kullan. ALARM: mt5_alerts ile kurarken modu SEN seç — mode:"once" tek seferlik, mode:"repeat" + cooldownMin (dk) tekrarlı. Lot için mt5_risksize hesapla ya da mt5_trade’e riskPct ver; SL/TP broker stops_level mesafesine uymalı. LOT KORKUSU YOK: önemli olan lot değil SL YERİ ve risk %’sidir — yakın stoplu net setupta yüksek lot NORMALDİR (boyutu risk hesabı verir).',
|
|
12392
12470
|
roleDef
|
|
12393
12471
|
? '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.'
|
|
12394
12472
|
: f.strategy ? `Sahibinin strateji notu: ${f.strategy}` : 'Strateji notu yok: trend + destek/direnç + momentum ile temel okuma yap.',
|
|
@@ -12535,7 +12613,7 @@ function finTeamHasMain() {
|
|
|
12535
12613
|
|
|
12536
12614
|
/* Takılma valfi: ekip turu bu süreyi aşarsa trader eski raporla başlar */
|
|
12537
12615
|
function finTeamWaitMaxMs() {
|
|
12538
|
-
const iSec =
|
|
12616
|
+
const iSec = finPaceSec();
|
|
12539
12617
|
return Math.max(60, Math.min(300, iSec)) * 1000;
|
|
12540
12618
|
}
|
|
12541
12619
|
|
|
@@ -12624,7 +12702,7 @@ function finAgentRound(sid, opts) {
|
|
|
12624
12702
|
: 'İşlem açabilirsin — limitlere uy, SL\u2019siz pozisyon bırakma.';
|
|
12625
12703
|
const learnTip = roleDef
|
|
12626
12704
|
? ' İlgili sembolün geçmiş derslerini (mt5_ogrenme) oku ve önerine yansıt.'
|
|
12627
|
-
: ' Yalnız gerçekten öğretici, tekrar kullanılabilir bir içgörü varsa TEK kısa cümleyle mt5_ogrenme add ile kaydet (her kapanışa ders yazma); karar öncesi mt5_ogrenme stats/list ile o sembolün geçmişini oku' + (agent.main ? ';
|
|
12705
|
+
: ' Yalnız gerçekten öğretici, tekrar kullanılabilir bir içgörü varsa TEK kısa cümleyle mt5_ogrenme add ile kaydet (her kapanışa ders yazma); karar öncesi mt5_ogrenme stats/list ile o sembolün geçmişini oku' + (agent.main ? '; mt5_limits ile lot/pozisyon limitlerini ve TUR RİTMİNİ (intervalSec+intervalForMin) güncelleyebilirsin.' : '.');
|
|
12628
12706
|
const focus = agent.symbols.length ? `Odak: ${agent.symbols.join(', ')}. ` : '';
|
|
12629
12707
|
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}${learnTip} Önemli kararların gerekçesini mt5_note ile günlüğe yaz. Kısa rapor ver.`;
|
|
12630
12708
|
const launch = (planBlock) => {
|
|
@@ -12719,8 +12797,7 @@ function finFlushOnDone(ev) {
|
|
|
12719
12797
|
sıradaki turu trader'ın cycle'ı başlatır (rapor tazeliği). Trader yoksa
|
|
12720
12798
|
ekip kendi timer'ıyla dönmeye devam eder. */
|
|
12721
12799
|
if (agent.role && finTeamHasMain()) return;
|
|
12722
|
-
const
|
|
12723
|
-
const iv = Math.max(30, Number(f.intervalSec) || 120) * 1000;
|
|
12800
|
+
const iv = finPaceSec() * 1000;
|
|
12724
12801
|
financeState.lastRoundAt = Date.now();
|
|
12725
12802
|
if (agent.main) {
|
|
12726
12803
|
finPush('trader', { state: 'idle', round: agent.round, nextInSec: iv / 1000 });
|
|
@@ -12915,17 +12992,8 @@ ipcMain.handle('finance:settings', async (_e, patch) => {
|
|
|
12915
12992
|
}
|
|
12916
12993
|
if (p.intervalSec !== undefined) f.intervalSec = Math.max(30, Math.min(3600, Math.round(Number(p.intervalSec) || 120)));
|
|
12917
12994
|
/* TUR ARALIĞI CANLI: bekleyen zamanlayıcılar yeni aralıkla yeniden kurulur —
|
|
12918
|
-
koşan tur bitince zaten finFlushOnDone yeni
|
|
12919
|
-
if (p.intervalSec !== undefined
|
|
12920
|
-
const iv = Math.max(30, Math.round(Number(f.intervalSec) || 120)) * 1000;
|
|
12921
|
-
const hasMain = finTeamHasMain();
|
|
12922
|
-
for (const [sid, a] of financeState.agents) {
|
|
12923
|
-
if (!a || !engine || engine.isBusy(sid)) continue;
|
|
12924
|
-
if (a.role && hasMain) continue; /* cycle modu: ekip turunu trader başlatır */
|
|
12925
|
-
clearTimeout(a.timer);
|
|
12926
|
-
a.timer = setTimeout(() => { try { finAgentRound(String(sid)); } catch {} }, iv);
|
|
12927
|
-
}
|
|
12928
|
-
}
|
|
12995
|
+
koşan tur bitince zaten finFlushOnDone yeni ritmi okur. */
|
|
12996
|
+
if (p.intervalSec !== undefined) { try { finRescheduleAgents(); } catch {} }
|
|
12929
12997
|
if (p.maxLot !== undefined) f.maxLot = Math.max(0.01, Math.min(100, Number(p.maxLot) || 0.1));
|
|
12930
12998
|
if (p.minLot !== undefined) f.minLot = Math.max(0.01, Math.min(100, Number(p.minLot) || 0.01));
|
|
12931
12999
|
/* min lot max lotu aşamaz — hangisi sonra yazıldıysa diğerine kelepçelenir */
|
package/src/renderer/renderer.js
CHANGED
|
@@ -10231,16 +10231,19 @@ function finOnEvent(ev) {
|
|
|
10231
10231
|
if (ev.maxLot !== undefined) finCfgCache.maxLot = ev.maxLot;
|
|
10232
10232
|
if (ev.maxPositions !== undefined) finCfgCache.maxPositions = ev.maxPositions;
|
|
10233
10233
|
if (ev.symbols !== undefined) finCfgCache.symbolLimits = ev.symbols;
|
|
10234
|
+
if (ev.intervalBase !== undefined) finCfgCache.intervalSec = ev.intervalBase;
|
|
10234
10235
|
finTraderInputsSet(finCfgCache);
|
|
10235
10236
|
} else {
|
|
10236
10237
|
const ae2 = document.activeElement;
|
|
10237
10238
|
if (els.finMinLot && ae2 !== els.finMinLot && ev.minLot !== undefined) els.finMinLot.value = ev.minLot;
|
|
10238
10239
|
if (els.finMaxLot && ae2 !== els.finMaxLot && ev.maxLot !== undefined) els.finMaxLot.value = ev.maxLot;
|
|
10240
|
+
if (els.finInterval && ae2 !== els.finInterval && ev.intervalBase !== undefined) els.finInterval.value = ev.intervalBase;
|
|
10239
10241
|
if (ev.symbols !== undefined) finSymLimitsRender(ev.symbols);
|
|
10240
10242
|
}
|
|
10241
10243
|
finLogLine('[limit] ' + (ev.note || ('min lot ' + ev.minLot + ' · max lot ' + ev.maxLot + ' · max pozisyon ' + ev.maxPositions)));
|
|
10242
10244
|
if (ev.symbol) toast('Sembol lot limiti güncellendi: ' + ev.symbol);
|
|
10243
|
-
else toast('Trader
|
|
10245
|
+
else if (ev.paceUntil) toast('Trader hız modu: tur ' + ev.intervalSec + ' sn — süre bitince tabana döner');
|
|
10246
|
+
else toast('Trader limitleri güncelledi: min ' + ev.minLot + ' / max ' + ev.maxLot + (ev.intervalSec ? ' · tur ' + ev.intervalSec + ' sn' : ''));
|
|
10244
10247
|
} else if (ev.fn === 'install') {
|
|
10245
10248
|
finLogLine('[MT5] paket kurulumu tamamlandı (kod ' + ev.code + ')');
|
|
10246
10249
|
}
|