beast-agent 2.62.1 → 2.63.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.
@@ -23,6 +23,8 @@ const NAMES = [
23
23
  'mt5_history',
24
24
  'mt5_alerts',
25
25
  'mt5_note',
26
+ 'mt5_ogrenme',
27
+ 'mt5_limits',
26
28
  'mt5_ea',
27
29
  'mt5_trade',
28
30
  'mt5_close',
@@ -43,6 +45,19 @@ let alertsApi = {
43
45
  set: () => null,
44
46
  remove: () => false,
45
47
  };
48
+ /* LIMIT API (main enjekte eder): trader lot/pozisyon limitlerini okuyup yazar */
49
+ let limitsApi = {
50
+ get: () => ({ minLot: 0.01, maxLot: 0.1, maxPositions: 3 }),
51
+ set: () => ({ ok: false, error: 'limit güncelleme kullanılamıyor' }),
52
+ };
53
+ /* ÖĞRENME API (main enjekte eder): sembol bazlı öğrenme deposu */
54
+ let learningApi = {
55
+ list: () => ({ ok: false, error: 'öğrenme deposu kullanılamıyor' }),
56
+ add: () => ({ ok: false, error: 'öğrenme deposu kullanılamıyor' }),
57
+ remove: () => ({ ok: false, error: 'öğrenme deposu kullanılamıyor' }),
58
+ clear: () => ({ ok: false, error: 'öğrenme deposu kullanılamıyor' }),
59
+ stats: () => ({ ok: false, error: 'öğrenme deposu kullanılamıyor' }),
60
+ };
46
61
 
47
62
  function setConfig(fn) {
48
63
  if (typeof fn === 'function') getCfg = fn;
@@ -60,6 +75,14 @@ function setDiscipline(fn) {
60
75
  if (typeof fn === 'function') discipline = fn;
61
76
  }
62
77
 
78
+ function setLimits(api) {
79
+ if (api && typeof api === 'object') limitsApi = { ...limitsApi, ...api };
80
+ }
81
+
82
+ function setLearning(api) {
83
+ if (api && typeof api === 'object') learningApi = { ...learningApi, ...api };
84
+ }
85
+
63
86
  async function bcall(method, params, timeoutMs) {
64
87
  const r = await mt5.call(method, params, timeoutMs);
65
88
  if (!r || r.ok !== true) throw new Error((r && r.error) || 'MT5 hatası');
@@ -237,6 +260,38 @@ const definitions = NAMES.map((name) => {
237
260
  required: ['symbol', 'note'],
238
261
  },
239
262
  },
263
+ mt5_limits: {
264
+ description:
265
+ 'LOT / POZİSYON LİMİTLERİNİ oku ve GÜNCELLE — trader karar mercii: mt5_limits {action:"get"|"set", minLot?, maxLot?, maxPositions?}. get: yürürlükteki min lot / max lot / max eşzamanlı pozisyon ve işlem riski %. set: yalnız ana trader (ve finance sohbet copilot\'ı) kullanabilir — rol/işçi ajanları değiştiremez. Volatilite rejimine göre limitleri sen ayarla (ör. sakin piyasada max lot artır, haber anında düşür); değişiklik ANINDA panelde ve sonraki turda geçerli olur. Kural: minLot maxLot\'u aşamaz.',
266
+ parameters: {
267
+ type: 'object',
268
+ properties: {
269
+ action: { type: 'string', enum: ['get', 'set'], description: 'get: mevcut limitler · set: güncelle' },
270
+ minLot: { type: 'number', description: 'set: yeni alt sınır (0.01-100)' },
271
+ maxLot: { type: 'number', description: 'set: yeni üst sınır (0.01-100)' },
272
+ maxPositions: { type: 'number', description: 'set: eşzamanlı pozisyon tavanı (1-20)' },
273
+ },
274
+ required: ['action'],
275
+ },
276
+ },
277
+ mt5_ogrenme: {
278
+ description:
279
+ 'SEMBOL BAZLI ÖĞRENME HAFIZASI — Beast Finance sürekli öğrenir: mt5_ogrenme {action:"list"|"add"|"remove"|"clear"|"stats", symbol?, text?, kind?, tags?, id?, ids?, all?}. Her sembolün KENDİ istatistiği (işlem/kazanç/kayıp, net, kâr yakalama, kâr geri verme) OTOMATİK birikir; ayrıca işlemlerden çıkardığın DERSLERİ sen kaydedersin. KURALLAR: (1) Her kapanıştan sonra (özellikle stop/tp sonrası) sembol için tek cümle ders yaz: hangi setup işe yaradı/yaramadı, saat/seans, SL yeri, hata mı hata yok mu — kind:"pattern"|"mistake"|"rule"|"observation". (2) Yeni işlem kararından ÖNCE ilgili sembolün list/stats çıktısını oku; aynı hatayı tekrarlama, işleyen deseni kullan. (3) Yanlış çıkan/genel geçersiz dersi remove/clear ile sil. action:"list" symbol verilmezse tüm sembollerin özetini döner. Ör: {action:"add", symbol:"XAUUSD", text:"Londra açılışında M5 EMA50 üstü momentum girişleri iyi çalışıyor", kind:"pattern"}.',
280
+ parameters: {
281
+ type: 'object',
282
+ properties: {
283
+ action: { type: 'string', enum: ['list', 'add', 'remove', 'clear', 'stats'] },
284
+ symbol: { type: 'string', description: 'Sembol (ör. XAUUSD) — öğrenme sembol bazlıdır' },
285
+ text: { type: 'string', description: 'add: öğrenilen ders/desen (kısa, net, tek cümle)' },
286
+ kind: { type: 'string', enum: ['pattern', 'mistake', 'rule', 'observation'], description: 'add: kayıt türü (varsayılan observation)' },
287
+ tags: { type: 'array', items: { type: 'string' }, description: 'add: etiketler (ör. ["scalp","london"])' },
288
+ id: { type: 'string', description: 'remove: kayıt id' },
289
+ ids: { type: 'array', items: { type: 'string' }, description: 'clear: silinecek kayıt id listesi' },
290
+ all: { type: 'boolean', description: 'clear: true → tüm öğrenme kayıtları (dikkatli)' },
291
+ },
292
+ required: ['action'],
293
+ },
294
+ },
240
295
  mt5_ea: {
241
296
  description:
242
297
  'BEASTFINANCE EA KÖPRÜSÜ (grafikte çalışan uzman danışman): action:"status" → EA heartbeat (yüklü mü, AutoTrading/EA izni, equity, pozisyon, son ack); "ping" → EA canlı yanıt; "chart" → aktif grafiğin sembol/periyot/fiyat/spread bilgisi; "note" → {symbol?, text, levels:[{price,label}]} grafik panosuna not + yatay seviye çizgileri yazar. NOT: yazdığın pano ve çizgiler görsel ajanın screenshot\'ında GÖRÜNÜR — GERÇEK grafik PNG\'si için varsayılan kurulu tool__mt5_shot kullan (EA "shot" komutu; görsel ajanın gözüne gelir), seviyeleri çizdikten sonra tool__mt5_shot ile görsel doğrula; grafiği agent_dm image ile ekibe paylaş.',
@@ -500,6 +555,53 @@ const handlers = {
500
555
  }, ctx || {});
501
556
  return { ok: true, saved: true };
502
557
  },
558
+ async mt5_limits(args, ctx) {
559
+ const action = String(args.action || 'get').toLowerCase();
560
+ if (action === 'get') {
561
+ return { ok: true, ...limitsApi.get() };
562
+ }
563
+ if (action === 'set') {
564
+ const patch = {};
565
+ for (const k of ['minLot', 'maxLot', 'maxPositions']) {
566
+ if (args[k] !== undefined && args[k] !== null && args[k] !== '') patch[k] = Number(args[k]);
567
+ }
568
+ if (!Object.keys(patch).length) {
569
+ return { ok: false, error: 'set için en az bir alan ver: minLot / maxLot / maxPositions' };
570
+ }
571
+ return await limitsApi.set(patch, ctx || {});
572
+ }
573
+ return { ok: false, error: 'action: get|set' };
574
+ },
575
+ async mt5_ogrenme(args, ctx) {
576
+ const action = String(args.action || 'list').toLowerCase();
577
+ const symbol = String(args.symbol || '').trim().toUpperCase();
578
+ if (action === 'list') return learningApi.list({ symbol });
579
+ if (action === 'stats') return learningApi.stats({ symbol });
580
+ if (action === 'add') {
581
+ const text = String(args.text || '').replace(/\s+/g, ' ').trim();
582
+ if (!symbol) return { ok: false, error: 'symbol gerekli — öğrenme sembol bazlıdır' };
583
+ if (!text) return { ok: false, error: 'text gerekli (öğrenilen ders)' };
584
+ const kindRaw = String(args.kind || 'observation').toLowerCase();
585
+ const kind = ['pattern', 'mistake', 'rule', 'observation'].includes(kindRaw) ? kindRaw : 'observation';
586
+ const tags = Array.isArray(args.tags) ? args.tags.map((t) => String(t || '').trim()).filter(Boolean).slice(0, 6) : [];
587
+ const res = learningApi.add({ symbol, text: text.slice(0, 600), kind, tags, sid: (ctx && ctx.sessionId) || '' });
588
+ if (res && res.ok) {
589
+ noteTrade('learn', { symbol, text: text.slice(0, 300), kind }, ctx || {});
590
+ }
591
+ return res;
592
+ }
593
+ if (action === 'remove') {
594
+ const id = String(args.id || '').trim();
595
+ if (!id) return { ok: false, error: 'remove için id gerekli' };
596
+ return learningApi.remove({ id, symbol });
597
+ }
598
+ if (action === 'clear') {
599
+ const ids = Array.isArray(args.ids) ? args.ids.map((x) => String(x || '').trim()).filter(Boolean) : [];
600
+ const all = args.all === true || String(args.all || '').toLowerCase() === 'true';
601
+ return learningApi.clear({ ids, symbol, all });
602
+ }
603
+ return { ok: false, error: 'action: list|add|remove|clear|stats' };
604
+ },
503
605
  async mt5_ea(args) {
504
606
  if (!mt5.running) return notConnected();
505
607
  const action = String(args.action || 'status').toLowerCase();
@@ -786,4 +888,4 @@ const handlers = {
786
888
  },
787
889
  };
788
890
 
789
- module.exports = { definitions, handlers, NAMES, setConfig, setNotify, setAlerts, setDiscipline };
891
+ module.exports = { definitions, handlers, NAMES, setConfig, setNotify, setAlerts, setDiscipline, setLimits, setLearning };
@@ -53,8 +53,15 @@ function plan(pos, meta, st, cfg) {
53
53
  const trailDist = num(cfg && cfg.trailR, 0.5);
54
54
  const partialR = num(cfg && cfg.partialR, 0);
55
55
  const partialPct = num(cfg && cfg.partialPct, 50);
56
+ /* KÂR KORUMA (erken trailing): kâr protectStartR'ye ulaşınca SL, GÖRÜLEN EN
57
+ İYİ kârın protectDistR gerisine kilitlenir — spike dönüşlerinde kâr
58
+ eksiye dönmez (0 = kapalı; varsayılan main finCfg'de verilir). */
59
+ const protectStart = num(cfg && cfg.protectStartR, 0);
60
+ const protectDist = num(cfg && cfg.protectDistR, 0);
56
61
 
57
62
  const profit = isBuy ? ref - entry : entry - ref;
63
+ /* en iyi kâr: tick'ler arası spike'lar kaybolmasın — main st.bestProfit yazar */
64
+ const bestProfit = Math.max(profit, num(st && st.bestProfit, profit));
58
65
 
59
66
  /* ---- BE + trailing: hedef SL'yi birleştir, asla geriye taşıma ---- */
60
67
  if (r > 0) {
@@ -70,10 +77,21 @@ function plan(pos, meta, st, cfg) {
70
77
  if (!(desired > 0) || (isBuy ? trailSl > desired : trailSl < desired)) desired = trailSl;
71
78
  want = true;
72
79
  }
80
+ /* kâr kilidi: ulaşılan EN İYİ kârın bir kısmı garantiye alınır */
81
+ if (protectStart > 0 && protectDist > 0 && bestProfit >= protectStart * r) {
82
+ const locked = bestProfit - protectDist * r;
83
+ const lockSl = isBuy ? entry + locked : entry - locked;
84
+ if (locked > 0 && (!(desired > 0) || (isBuy ? lockSl > desired : lockSl < desired))) desired = lockSl;
85
+ want = true;
86
+ }
73
87
  if (want && desired > 0) {
74
88
  /* broker stop mesafesi: SL fiyata çok yakınsa geçersiz — kırp */
75
89
  desired = isBuy ? Math.min(desired, ref - minDist) : Math.max(desired, ref + minDist);
76
- const improved = isBuy ? desired > sl + point * 0.5 : (sl === 0 || desired < sl - point * 0.5);
90
+ /* KIRPMA KİLİDİ BOZDU: fiyat geri çekildi, hedef SL girişin kaybına
91
+ indi — kâr kilidini kaybı kilitleyen SL'e çevirme; hiç yazma
92
+ (fiyat toparlayınca kilit yeniden uygulanır). */
93
+ const lockBroken = isBuy ? desired < entry : desired > entry;
94
+ const improved = !lockBroken && (isBuy ? desired > sl + point * 0.5 : (sl === 0 || desired < sl - point * 0.5));
77
95
  if (improved && desired > 0) {
78
96
  out.actions.push({ kind: 'modify', sl: roundTo(desired, digits) });
79
97
  }
@@ -1,24 +1,23 @@
1
1
  //+------------------------------------------------------------------+
2
- //| BeastFinance.mq5 — Beast Finance köprü EA'sı (v1.21) |
2
+ //| BeastFinance.mq5 — Beast Finance köprü EA'sı (v1.22) |
3
3
  //| - Heartbeat: MQL5\Files\beast_ea.json (durum + izinler + equity) |
4
4
  //| - Komut köprüsü: beast_cmd.json (Beast yazar) → beast_cmd_ack.json|
5
5
  //| - Entegrasyon/Screenshot: grafik üstü pano (Comment) + seviye |
6
6
  //| çizgileri — Beast beast_note.json ile besler; görsel ajan |
7
7
  //| computer_look ile chart screenshot'ında bu panoyu görür. |
8
+ //| NOT: Trade işlemleri Python köprüsünden yürür — bu EA emir AÇMAZ;|
9
+ //| bu yüzden <Trade\Trade.mqh> bağımlılığı YOKTUR (standart |
10
+ //| include klasörü eksik kurulumlarda EA derlenemiyordu). |
8
11
  //+------------------------------------------------------------------+
9
12
  #property copyright "Beast Agent"
10
13
  #property link "https://github.com/algokodcom/beast-agent"
11
- #property version "1.21"
14
+ #property version "1.22"
12
15
  #property description "Beast Finance köprü EA'sı — heartbeat + komut köprüsü + grafik panosu."
13
16
 
14
- #include <Trade\Trade.mqh>
15
-
16
17
  input string InpTag = "BeastFinance"; // Etiket
17
18
  input int InpHeartbeat = 5; // Kalp atışı (sn)
18
19
  input bool InpVerbose = true; // Grafik panosunu yaz
19
- input long InpMagic = 20260910; // Magic number
20
-
21
- CTrade gTrade;
20
+ input long InpMagic = 20260910; // Magic number (Python köprüsü kullanır)
22
21
 
23
22
  string BeatFile = "beast_ea.json";
24
23
  string CmdFile = "beast_cmd.json";
@@ -29,10 +28,33 @@ string LvlPrefix = "BeastLvl_";
29
28
  string gNoteText = "";
30
29
  string gNoteSymbol = "";
31
30
 
31
+ /* BEKLEYEN GÖRSEL İŞLERİ: ChartScreenShot ASENKRON üretir — komut bitince
32
+ hemen grafiği kapatmak/boyamak çekimi iptal edebiliyor. Bu yüzden geçici
33
+ grafiğin kapatılması ve aktif grafiğin shift ayarının geri yazılması bir
34
+ sonraki timer turuna ertelenir (PNG'nin diske yazılmasına süre tanınır). */
35
+ long gPendCloseChart = 0;
36
+ long gPendRestoreChart = 0;
37
+ long gPendShiftPrev = 0;
38
+ double gPendShiftSizePrev = 0;
39
+
40
+ void FlushPendingShot()
41
+ {
42
+ if(gPendCloseChart != 0)
43
+ {
44
+ ChartClose(gPendCloseChart); /* kapanmışsa zararsız (false döner) */
45
+ gPendCloseChart = 0;
46
+ }
47
+ if(gPendRestoreChart != 0)
48
+ {
49
+ ChartSetInteger(gPendRestoreChart, CHART_SHIFT, gPendShiftPrev != 0);
50
+ ChartSetDouble(gPendRestoreChart, CHART_SHIFT_SIZE, gPendShiftSizePrev);
51
+ ChartRedraw(gPendRestoreChart);
52
+ gPendRestoreChart = 0;
53
+ }
54
+ }
55
+
32
56
  int OnInit()
33
57
  {
34
- gTrade.SetExpertMagicNumber(InpMagic);
35
- gTrade.SetTypeFillingBySymbol(_Symbol);
36
58
  EventSetTimer(MathMax(1, InpHeartbeat));
37
59
  WriteBeat("init");
38
60
  RefreshPanel();
@@ -43,6 +65,7 @@ int OnInit()
43
65
  void OnDeinit(const int reason)
44
66
  {
45
67
  EventKillTimer();
68
+ FlushPendingShot();
46
69
  WriteBeat("deinit");
47
70
  ClearLevels();
48
71
  Comment("");
@@ -50,6 +73,11 @@ void OnDeinit(const int reason)
50
73
 
51
74
  void OnTimer()
52
75
  {
76
+ /* ÖNEMLİ SIRA: önce ÖNCEKİ shot'un artıkları toparlanır (geçici grafik
77
+ kapatılır, aktif grafiğin shift'i geri yazılır); sonra yeni komut işlenir.
78
+ Ters sırada olsaydı yeni açılan geçici grafik aynı turda kapatılıp
79
+ screenshot kaybolurdu. */
80
+ FlushPendingShot();
53
81
  ReadNote();
54
82
  WriteBeat("beat");
55
83
  ProcessCommands();
@@ -72,7 +100,7 @@ void WriteBeat(const string stage)
72
100
  {
73
101
  int h = FileOpen(BeatFile, FILE_WRITE|FILE_TXT|FILE_UNICODE);
74
102
  if(h == INVALID_HANDLE) return;
75
- string js = StringFormat("{\"ok\":true,\"ea\":\"BeastFinance\",\"version\":\"1.21\",\"tag\":\"%s\",\"stage\":\"%s\",\"time\":%d,\"server_time\":\"%s\",\"symbol\":\"%s\",\"period\":%d,\"equity\":%.2f,\"balance\":%.2f,\"terminal_trade_allowed\":%s,\"mql_trade_allowed\":%s,\"positions\":%d,\"note\":\"%s\"}",
103
+ string js = StringFormat("{\"ok\":true,\"ea\":\"BeastFinance\",\"version\":\"1.22\",\"tag\":\"%s\",\"stage\":\"%s\",\"time\":%d,\"server_time\":\"%s\",\"symbol\":\"%s\",\"period\":%d,\"equity\":%.2f,\"balance\":%.2f,\"terminal_trade_allowed\":%s,\"mql_trade_allowed\":%s,\"positions\":%d,\"note\":\"%s\"}",
76
104
  JStr(InpTag), stage, (int)TimeCurrent(), TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS),
77
105
  _Symbol, (int)Period(),
78
106
  AccountInfoDouble(ACCOUNT_EQUITY), AccountInfoDouble(ACCOUNT_BALANCE),
@@ -93,7 +121,7 @@ void RefreshPanel()
93
121
  Comment("");
94
122
  return;
95
123
  }
96
- string lines = "Beast Finance — BeastFinance v1.21\n";
124
+ string lines = "Beast Finance — BeastFinance v1.22\n";
97
125
  lines += _Symbol + " · " + EnumToString((ENUM_TIMEFRAMES)Period()) + " · " + TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS) + "\n";
98
126
  lines += StringFormat("Equity: %.2f · Balance: %.2f · Acik pozisyon: %d\n",
99
127
  AccountInfoDouble(ACCOUNT_EQUITY), AccountInfoDouble(ACCOUNT_BALANCE), PositionsTotal());
@@ -198,6 +226,7 @@ void ApplyLevels(const string raw)
198
226
  }
199
227
  if(price > 0)
200
228
  {
229
+ if(n >= ArraySize(names)) break; /* taşma koruması: sınırı aşan seviye atlanır */
201
230
  string name = LvlPrefix + IntegerToString(n);
202
231
  names[n] = name;
203
232
  if(ObjectFind(0, name) < 0) ObjectCreate(0, name, OBJ_HLINE, 0, 0, price);
@@ -240,6 +269,22 @@ void WriteAck(const string id, const string cmd, const bool ok, const string err
240
269
  FileClose(h);
241
270
  }
242
271
 
272
+ /* Komut dosyasını YALNIZ hâlâ bizim id'mizi taşıyorsa sil — EA işlerken
273
+ yazılmış YENİ bir komutun yanlışlıkla silinmesi komut kaybı (ea_no_ack)
274
+ üretiyordu. */
275
+ void DeleteCmdIfId(const string id)
276
+ {
277
+ if(!FileIsExist(CmdFile)) return;
278
+ int h = FileOpen(CmdFile, FILE_READ|FILE_TXT|FILE_UNICODE);
279
+ if(h == INVALID_HANDLE) return;
280
+ string raw = "";
281
+ while(!FileIsEnding(h)) raw += FileReadString(h);
282
+ FileClose(h);
283
+ if(StringLen(raw) == 0) return;
284
+ string cur = JsonGet(raw, "id");
285
+ if(StringLen(cur) == 0 || StringCompare(cur, id) == 0) FileDelete(CmdFile);
286
+ }
287
+
243
288
  void ProcessCommands()
244
289
  {
245
290
  if(!FileIsExist(CmdFile)) return;
@@ -352,15 +397,17 @@ void ProcessCommands()
352
397
  }
353
398
 
354
399
  /* SON MUM SAĞ KENARA YAPIŞMASIN: grafik "shift" payı (%12 sağ boşluk).
400
+ CHART_SHIFT integer, CHART_SHIFT_SIZE ise DOUBLE özelliktir (10-50) —
401
+ yanlış API (ChartGet/SetInteger) EA'yı derlenmez hale getiriyordu.
355
402
  Aktif grafikte önceki ayar çekimden SONRA geri yazılır — kullanıcının
356
- grafiği kalıcı değişmez; geçici grafik zaten kapanır. */
357
- long shiftPrev = ChartGetInteger(cid, CHART_SHIFT);
358
- long shiftSizePrev = ChartGetInteger(cid, CHART_SHIFT_SIZE);
403
+ grafiği kalıcı değişmez; geçici grafik PNG yazılana kadar AÇIK kalır. */
404
+ long shiftPrev = ChartGetInteger(cid, CHART_SHIFT);
405
+ double shiftSizePrev = ChartGetDouble(cid, CHART_SHIFT_SIZE);
359
406
 
360
407
  if(ok)
361
408
  {
362
409
  ChartSetInteger(cid, CHART_SHIFT, true);
363
- ChartSetInteger(cid, CHART_SHIFT_SIZE, 12);
410
+ ChartSetDouble(cid, CHART_SHIFT_SIZE, 12.0);
364
411
  ChartRedraw(cid);
365
412
  Sleep(1200); /* mumlar/olcek otursun */
366
413
  ChartRedraw(cid);
@@ -375,14 +422,24 @@ void ProcessCommands()
375
422
  result = StringFormat("{\"file\":\"%s\",\"width\":%d,\"height\":%d,\"symbol\":\"%s\",\"period\":%d,\"temp_chart\":%s,\"template_applied\":%s,\"theme_ok\":%s,\"bg\":%d}",
376
423
  JStr(file), w, hh, symWant, (int)tfUse, (tempChart ? "true" : "false"), (tplApplied ? "true" : "false"), (themeOk ? "true" : "false"), bgNow);
377
424
  }
378
- if(!tempChart)
379
- {
380
- ChartSetInteger(cid, CHART_SHIFT, shiftPrev != 0);
381
- ChartSetInteger(cid, CHART_SHIFT_SIZE, shiftSizePrev);
382
- ChartRedraw(cid);
383
- }
384
425
  }
385
- if(tempChart) ChartClose(cid);
426
+ /* ACK GARANTİSİ: ChartScreenShot görüntüyü ASENKRON üretir; ack'i
427
+ geciktirmek tool tarafında sahte "ea_no_ack" hatalarına yol açıyordu.
428
+ Ack burada hemen yazılır; PNG'yi tool ayrıca bekler. Geçici grafik ve
429
+ aktif grafiğin shift ayarı bir sonraki timer turunda toparlanır. */
430
+ WriteAck(id, cmd, ok, err, result);
431
+ DeleteCmdIfId(id);
432
+ if(tempChart)
433
+ {
434
+ gPendCloseChart = cid;
435
+ }
436
+ else
437
+ {
438
+ gPendRestoreChart = cid;
439
+ gPendShiftPrev = shiftPrev;
440
+ gPendShiftSizePrev = shiftSizePrev;
441
+ }
442
+ return; /* ack bu yolda yazıldı — ortak kuyruğa tekrar girmesin */
386
443
  }
387
444
  else
388
445
  {
@@ -390,7 +447,7 @@ void ProcessCommands()
390
447
  err = "bilinmeyen komut: " + cmd;
391
448
  }
392
449
  WriteAck(id, cmd, ok, err, result);
393
- FileDelete(CmdFile);
450
+ DeleteCmdIfId(id);
394
451
  }
395
452
 
396
453
  /* BeastFinance.tpl acik tema renklerini grafige uygular (sablon bulunamazsa da garanti) */
@@ -43,7 +43,8 @@ Kural: LTF sinyali HTF yönüne tersse işlem açma.
43
43
  - Giriş: BOS sonrası geri çekilme (pullback) + retest teyidi; kovalama yok.
44
44
  - SL: yapının arkasına (son swing low/high'ın ötesi) + spread/ATR payı. Yapının İÇİNE SL koyma.
45
45
  - Geniş SL tercih ediliyorsa: ~4×ATR SL, ~2×ATR'de BE (break-even) taşıma.
46
- - TP: bir sonraki HTF bölgesi; R:R en az 1.5–2. Kısmi kâr alımı serbest.
46
+ - TP: bir sonraki HTF bölgesi. R:R ESNEKTİR — scalp/hızlı işlemlerde TP 0.3R–0.5R olabilir; R:R ≥ 1.5 ŞART DEĞİL. Kısmi kâr alımı serbest ve teşvik edilir: 0.3-0.5R'de pozisyonun bir kısmını realize et, kalanı korumalı trailing ile taşı.
47
+ - KÂR KORUMA: +0.3R'de sistem SL'yi kilitler (en iyi kârın 0.15R gerisi); kârın eksiye dönmesine izin verme — gerekiyorsa 0.3-0.5R'de kısmi TP ile kârı cebe al.
47
48
  - BE'e çekmeden SL'siz/işlemsiz kalma; her pozisyonun SL'si olsun.
48
49
 
49
50
  ## 6) YASAKLAR
@@ -30,6 +30,8 @@ version: 1.0.0
30
30
  - **Korelasyon**: XAUUSD/EURUSD ile DXY ters koreledir; aynı yönde iki korelasyonlu pozisyon riski katlar.
31
31
  - SL'siz pozisyon varsa ilk iş: SL tamamla veya kapat.
32
32
  - Hedefine ulaşan/kâra geçen pozisyonda BE veya kısmi kâr; trailing ATR bazlı.
33
+ - **Kâr koruma:** +0.3R'de sistem SL'yi en iyi kârın 0.15R gerisine kilitler; +0.3-0.5R'de kısmi TP (ör. %50) ile kârı cebe al, kalanı trailing'e bırak. TP için R:R ≥ 1.5 şartı YOK — hızlı kâr toplama (scalp) serbest; ama kârı kale verme.
34
+ - **Sembol bazlı öğrenme:** her kapanıştan sonra mt5_ogrenme add ile dersi yaz (ne işe yaradı/yaramadı); yeni işlem öncesi o sembolün stats/list geçmişini oku — aynı hatayı tekrarlama.
33
35
 
34
36
  ## 4) KAYIP LİMİTLERİ
35
37