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.
- package/package.json +1 -1
- package/src/agent/defaulttools/mt5_shot/run.js +31 -23
- package/src/agent/defaulttools/mt5_shot/tool.json +1 -1
- package/src/agent/engine.js +163 -64
- package/src/agent/financetools.js +103 -1
- package/src/agent/finwatch.js +19 -1
- package/src/agent/mt5/BeastFinance.mq5 +80 -23
- package/src/agent/seeds/price-action/SKILL.md +2 -1
- package/src/agent/seeds/risk-yonetimi/SKILL.md +2 -0
- package/src/main.js +378 -5
- package/src/renderer/index.html +3 -1
- package/src/renderer/renderer.js +48 -11
|
@@ -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 };
|
package/src/agent/finwatch.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
357
|
-
long
|
|
358
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|