beast-agent 2.63.1 → 2.63.3
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/bots.js +19 -1
- package/src/agent/engine.js +74 -14
- package/src/agent/financetools.js +60 -18
- package/src/agent/finrisk.js +16 -6
- package/src/agent/seeds/risk-yonetimi/SKILL.md +52 -52
- package/src/main.js +442 -22
- package/src/preload.js +1 -0
- package/src/renderer/i18n.js +2 -0
- package/src/renderer/index.html +18 -1
- package/src/renderer/renderer.js +344 -1
- package/src/renderer/style.css +115 -0
package/package.json
CHANGED
package/src/agent/bots.js
CHANGED
|
@@ -130,7 +130,25 @@ function ensureDefaultBots() {
|
|
|
130
130
|
loadRegistry();
|
|
131
131
|
let created = false;
|
|
132
132
|
for (const def of DEFAULT_BOT_SEEDS) {
|
|
133
|
-
|
|
133
|
+
const existing = REG.bots.find((b) => b && b.id === def.id);
|
|
134
|
+
if (existing) {
|
|
135
|
+
/* VARSAYILAN PROMPT GÜNCELLEMESİ (tek seferlik ek): eski sürümde
|
|
136
|
+
oluşmuş Tool botunun promptunda mql5/edit_file/skill vurgusu yoksa
|
|
137
|
+
eksik parçalar EKLENİR — kullanıcı düzenlemesi ezilmez. */
|
|
138
|
+
if (def.id === 'tool') {
|
|
139
|
+
const p = String(existing.prompt || '');
|
|
140
|
+
const add = [];
|
|
141
|
+
if (!/skill\(["']mql5["']\)/.test(p)) add.push('MQL5/gösterge/EA işlerinde ÖNCE skill("mql5") oku ve prosedürüne uy.');
|
|
142
|
+
if (!/edit_file/.test(p)) add.push('Var olan dosyayı edit_file ile GÜNCELLE; yeniyi write_file ile yaz; içerik aramada grep, dosya adı aramada glob kullan.');
|
|
143
|
+
if (!/skill\(["']tool-yazma["']\)/.test(p)) add.push('Tool yazmadan önce skill("tool-yazma") oku ve sözleşmeye birebir uy.');
|
|
144
|
+
if (add.length) {
|
|
145
|
+
existing.prompt = (p ? p + ' ' : '') + add.join(' ');
|
|
146
|
+
created = true;
|
|
147
|
+
logChange(def.id, 'varsayılan prompt ekleri eklendi (mql5/edit_file/skill)');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
134
152
|
if (REG.bots.length >= MAX_BOTS) break;
|
|
135
153
|
const bot = {
|
|
136
154
|
id: def.id,
|
package/src/agent/engine.js
CHANGED
|
@@ -2032,7 +2032,7 @@ 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_ogrenme (SEMBOL BAZLI ÖĞRENME: işlem istatistiği + dersler —
|
|
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_ogrenme (SEMBOL BAZLI ÖĞRENME: işlem istatistiği + dersler — yalnız gerçekten öğretici kısa içgörüyü yaz, karar öncesi oku), mt5_limits (lot/pozisyon limitlerini gör/GÜNCELLE — yalnız trader; symbol ile SEMBOL BAZLI min/max lot — sembolün karakterine göre karar senin), 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
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' +
|
|
2038
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' +
|
|
@@ -2064,7 +2064,15 @@ class Engine {
|
|
|
2064
2064
|
lim.maxLot ? `max lot ${lim.maxLot}` : null,
|
|
2065
2065
|
lim.maxPositions ? `max eşzamanlı pozisyon ${lim.maxPositions}` : null,
|
|
2066
2066
|
].filter(Boolean).join(' · ') +
|
|
2067
|
-
'
|
|
2067
|
+
' (genel).' +
|
|
2068
|
+
(lim.symbolLimits && Object.keys(lim.symbolLimits).length
|
|
2069
|
+
? ' SEMBOL BAZLI: ' +
|
|
2070
|
+
Object.entries(lim.symbolLimits)
|
|
2071
|
+
.map(([s, v]) => `${s} ${Number(v && v.minLot) > 0 ? Number(v.minLot) : lim.minLot}–${Number(v && v.maxLot) > 0 ? Number(v.maxLot) : lim.maxLot}`)
|
|
2072
|
+
.join(' · ') +
|
|
2073
|
+
' — sembol limiti önceliklidir.'
|
|
2074
|
+
: '') +
|
|
2075
|
+
' Bunları aşıp araç kullanma; sistem zaten reddeder (lot min lot altına inemez, max lot üstüne çıkamaz).\n'
|
|
2068
2076
|
: '') +
|
|
2069
2077
|
'RİSK DİSİPLİNİ:\n' +
|
|
2070
2078
|
'- SL\u2019siz pozisyon BIRAKMA: açtığın her işlemde mantıklı bir SL koy; SL\u2019siz kalan pozisyonu mt5_modify ile tamamla.\n' +
|
|
@@ -2074,7 +2082,7 @@ class Engine {
|
|
|
2074
2082
|
'- 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' +
|
|
2075
2083
|
'- Hesap kaldıracı ve serbest marja göre pozisyon boyutunu düşük tut; tek işlemde serbest marjın büyük kısmını riske atma. Sık işlem için lotu değil, TUR SIKLIĞINI ve kısmi kâr alımını kullan.\n' +
|
|
2076
2084
|
(session && session.financeLearn ? `SEMBOL BAZLI ÖĞRENME HAFIZAN (otomatik istatistik + kendi derslerin — kararlarında kullan):\n${session.financeLearn}\n` : '') +
|
|
2077
|
-
'ÖĞRENME DÖNGÜSÜ (
|
|
2085
|
+
'ÖĞ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' +
|
|
2078
2086
|
(session && session.financeStrategy ? `SAHİBİNİN STRATEJİ NOTU (önceliklidir):\n${session.financeStrategy}\n` : '') +
|
|
2079
2087
|
(session && session.financeShadow ? 'SHADOW MOD AKTİF: mt5_trade/mt5_pending emir GÖNDERMEZ — kararını teziyle raporla; gerçek işlem açılmaz (karar günlüğe yazılır).\n' : '') +
|
|
2080
2088
|
(session && session.financeDigest ? `İŞLEM PERFORMANS GEÇMİŞİN (kendi kayıtların — kararlarında ders çıkar):\n${session.financeDigest}\n` : '') +
|
|
@@ -3845,15 +3853,17 @@ class Engine {
|
|
|
3845
3853
|
/* KİŞİSEL TOOLLAR: %APPDATA%\beast\tools\<ad>\ — kullanıcı yazmışsa
|
|
3846
3854
|
TÜM oturumlara (BEAST FINANCE dahil) tool__<ad> olarak açılır */
|
|
3847
3855
|
toolsList = [...toolsList, ...customtools.definitions()];
|
|
3848
|
-
/*
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
if (session && session.finance) {
|
|
3856
|
+
/* SKILL ARACI: kurulu SKILL.md gövdesini modele açar — finance oturumları
|
|
3857
|
+
kadar BOT oturumları (Tool botu: tool-yazma/mql5) ve arka plan ajanları
|
|
3858
|
+
da promptlarında skill() kullanır. Tanım yalnız finance'a verilince bot
|
|
3859
|
+
skill çağrısı yapamıyor, tur rapor üretmeden boşa düşüyordu. */
|
|
3860
|
+
if (session && (session.finance || session.botId || session.bgJob)) {
|
|
3853
3861
|
const skillDef = (opencode.toolmap.definitions() || []).find(
|
|
3854
3862
|
(d) => d && d.function && d.function.name === 'skill'
|
|
3855
3863
|
);
|
|
3856
|
-
if (skillDef
|
|
3864
|
+
if (skillDef && !toolsList.some((t) => t && t.function && t.function.name === 'skill')) {
|
|
3865
|
+
toolsList = [...toolsList, skillDef];
|
|
3866
|
+
}
|
|
3857
3867
|
}
|
|
3858
3868
|
/* AJAN DM: koşan ajanlara (arka plan işleri + finance), ana sohbete VE
|
|
3859
3869
|
bot sohbetlerine verilir — botlar birbirine iş atar/cevap verir
|
|
@@ -4913,6 +4923,7 @@ const skills = require('./skills');
|
|
|
4913
4923
|
requesterTitle: who,
|
|
4914
4924
|
responderTitle: target.name || 'Tool botu',
|
|
4915
4925
|
task: task.slice(0, 300),
|
|
4926
|
+
text,
|
|
4916
4927
|
before,
|
|
4917
4928
|
at: Date.now(),
|
|
4918
4929
|
});
|
|
@@ -4964,14 +4975,16 @@ const skills = require('./skills');
|
|
|
4964
4975
|
}
|
|
4965
4976
|
|
|
4966
4977
|
/* Tool botunun turu bitti: bekleyen isteklerin raporunu AJAN DM paneline
|
|
4967
|
-
ve isteyen oturuma düşür. _run finally'den çağrılır (tüm bitiş yolları).
|
|
4978
|
+
ve isteyen oturuma düşür. _run finally'den çağrılır (tüm bitiş yolları).
|
|
4979
|
+
Tur metin rapor üretmeden öldüyse: (1) tur hiç iş yapmadıysa TEK kez
|
|
4980
|
+
sessizce yeniden dene (geçici model/ağ hatası), (2) yine olmazsa araç
|
|
4981
|
+
izini + hata mesajını rapora koy ki isteyen NE olduğunu anlasın. */
|
|
4968
4982
|
_toolRequestFinished(sid) {
|
|
4969
4983
|
try {
|
|
4970
4984
|
const key = String(sid || '');
|
|
4971
4985
|
if (!this._toolPending || !this._toolPending.size) return;
|
|
4972
4986
|
const list = this._toolPending.get(key);
|
|
4973
4987
|
if (!list || !list.length) return;
|
|
4974
|
-
this._toolPending.delete(key);
|
|
4975
4988
|
const s = this.cache.get(key) || this._load(key);
|
|
4976
4989
|
const reply = (() => {
|
|
4977
4990
|
for (let i = s.messages.length - 1; i >= 0; i--) {
|
|
@@ -4983,10 +4996,51 @@ const skills = require('./skills');
|
|
|
4983
4996
|
}
|
|
4984
4997
|
return '';
|
|
4985
4998
|
})();
|
|
4999
|
+
/* TEST/İZ: isteğin başladığı noktadan sonra araç çağrısı/sonucu var mı? */
|
|
5000
|
+
const activity = (from) => {
|
|
5001
|
+
let n = 0;
|
|
5002
|
+
for (let i = Math.max(0, Number(from) || 0); i < s.messages.length; i++) {
|
|
5003
|
+
const m = s.messages[i];
|
|
5004
|
+
if (m && ((m.role === 'assistant' && Array.isArray(m.tool_calls) && m.tool_calls.length) || m.role === 'tool')) n++;
|
|
5005
|
+
}
|
|
5006
|
+
return n;
|
|
5007
|
+
};
|
|
5008
|
+
/* GEÇİCİ ÖLÜM: tek istek + hiç araç izi + metin yok → tek kez yeniden dene */
|
|
5009
|
+
if (!reply && list.length === 1 && !list[0].retried && list[0].text && activity(list[0].before) === 0) {
|
|
5010
|
+
list[0].retried = true;
|
|
5011
|
+
this._toolPending.set(key, list);
|
|
5012
|
+
try {
|
|
5013
|
+
const ok = this.send(key, { text: '[YENİDEN DENEME — önceki tur iş yapmadan düştü; isteği baştan yürüt]\n' + String(list[0].text) });
|
|
5014
|
+
if (ok) return;
|
|
5015
|
+
} catch {}
|
|
5016
|
+
}
|
|
5017
|
+
this._toolPending.delete(key);
|
|
5018
|
+
/* METİN RAPOR YOKSA: son turun araç izini özetle — teşhis kaybolmasın */
|
|
5019
|
+
const failDetail = (() => {
|
|
5020
|
+
if (reply) return '';
|
|
5021
|
+
const L = [];
|
|
5022
|
+
for (let i = s.messages.length - 1; i >= 0 && L.length < 8; i--) {
|
|
5023
|
+
const m = s.messages[i];
|
|
5024
|
+
if (!m) continue;
|
|
5025
|
+
if (m.role === 'tool') {
|
|
5026
|
+
const t = typeof m.content === 'string' ? m.content : '';
|
|
5027
|
+
if (t.trim()) L.unshift('araç sonucu: ' + t.replace(/\s+/g, ' ').slice(0, 180));
|
|
5028
|
+
} else if (m.role === 'assistant' && Array.isArray(m.tool_calls) && m.tool_calls.length) {
|
|
5029
|
+
L.unshift('çağrılan araçlar: ' + m.tool_calls.map((c) => (c && c.function && c.function.name) || '?').join(', '));
|
|
5030
|
+
} else if (m.role === 'assistant' && typeof m.content === 'string' && m.content.trim()) {
|
|
5031
|
+
L.unshift('son metin: ' + stripAiDashes(m.content.trim()).replace(/\s+/g, ' ').slice(0, 180));
|
|
5032
|
+
} else if (m.role === 'user') {
|
|
5033
|
+
break;
|
|
5034
|
+
}
|
|
5035
|
+
}
|
|
5036
|
+
return L.join('\n');
|
|
5037
|
+
})();
|
|
4986
5038
|
for (const req of list) {
|
|
4987
5039
|
const body = reply
|
|
4988
5040
|
? `[TOOL BOTU RAPORU — ${req.id}]\n${reply}`
|
|
4989
|
-
: `[TOOL BOTU] ${req.id} numaralı istek tamamlanamadı (tur yarıda kesildi ya da metin rapor üretilemedi)
|
|
5041
|
+
: `[TOOL BOTU] ${req.id} numaralı istek tamamlanamadı (tur yarıda kesildi ya da metin rapor üretilemedi).\n` +
|
|
5042
|
+
(failDetail ? 'Ne oldu:\n' + failDetail + '\n' : '') +
|
|
5043
|
+
'Tool botu sohbetinden ayrıntıya bakabilirsin.';
|
|
4990
5044
|
const dm = {
|
|
4991
5045
|
at: new Date().toISOString(),
|
|
4992
5046
|
from: key,
|
|
@@ -7081,8 +7135,14 @@ Engine.prototype._agentDmDeliver = function (dm, target, opts = {}) {
|
|
|
7081
7135
|
dm: true,
|
|
7082
7136
|
wake: !!opts.wake,
|
|
7083
7137
|
};
|
|
7084
|
-
/* bot↔bot sigorta: boş bot oturumunu her DM'de yeni turla uyandırma
|
|
7085
|
-
|
|
7138
|
+
/* bot↔bot sigorta: boş bot oturumunu her DM'de yeni turla uyandırma.
|
|
7139
|
+
TOOL BOTU İSTİSNA (yalnız bot OLMAYAN gönderenden): ajan (finance/paralel
|
|
7140
|
+
sohbet) → Tool DM'i gerçek görevdir, beklemeden uyandırılır; bot↔bot
|
|
7141
|
+
ping-pong'u ise bütçeye tabidir (sonsuz tur fırtınası korunur). */
|
|
7142
|
+
const fromSess = this.cache.get(String(dm.from)) || null;
|
|
7143
|
+
const fromIsBot = !!(fromSess && fromSess.botId);
|
|
7144
|
+
const isToolBot = sess && String(sess.botId || '') === 'tool' && !fromIsBot;
|
|
7145
|
+
if (sess && sess.botId && !isToolBot && !this.isBusy(m) && !this._agentDmWakeAllowed(dm.from, m)) {
|
|
7086
7146
|
this._agentDmBacklog = this._agentDmBacklog || new Map();
|
|
7087
7147
|
const q = this._agentDmBacklog.get(m) || [];
|
|
7088
7148
|
q.push({ text, ...(dm.image ? { image: String(dm.image) } : {}) });
|
|
@@ -101,6 +101,19 @@ function tickPrice(row, side) {
|
|
|
101
101
|
return Number(row && row.bid) || Number(row && row.ask) || 0;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
/* SEMBOL BAZLI LOT ARALIĞI (trader mt5_limits ile koyar): sembol limiti
|
|
105
|
+
varsa genel aralığın yerine geçer — yoksa genel minLot/maxLot kullanılır.
|
|
106
|
+
İki değer de broker normalizasyonuna girer (adım/min/max sembolden gelir). */
|
|
107
|
+
function lotRange(cfg, symbol) {
|
|
108
|
+
const sym = String(symbol || '').trim().toUpperCase();
|
|
109
|
+
const o = (cfg && cfg.symbolLimits && cfg.symbolLimits[sym]) || null;
|
|
110
|
+
let minLot = Number(o && o.minLot) > 0 ? Number(o.minLot) : Number(cfg && cfg.minLot) || 0.01;
|
|
111
|
+
let maxLot = Number(o && o.maxLot) > 0 ? Number(o.maxLot) : Number(cfg && cfg.maxLot) || 0.1;
|
|
112
|
+
if (minLot > maxLot) minLot = maxLot;
|
|
113
|
+
if (maxLot < minLot) maxLot = minLot;
|
|
114
|
+
return { minLot, maxLot };
|
|
115
|
+
}
|
|
116
|
+
|
|
104
117
|
/* İşlem öncesi risk katmanı: stops_level + yoğunluk + marj kalkanı.
|
|
105
118
|
Hata metni ya da null döner. positions çağıran tarafından verilir. */
|
|
106
119
|
async function preTradeCheck(cfg, side, symbol, info, price, volume, sl, tp, positions) {
|
|
@@ -262,32 +275,35 @@ const definitions = NAMES.map((name) => {
|
|
|
262
275
|
},
|
|
263
276
|
mt5_limits: {
|
|
264
277
|
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:
|
|
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.',
|
|
266
279
|
parameters: {
|
|
267
280
|
type: 'object',
|
|
268
281
|
properties: {
|
|
269
282
|
action: { type: 'string', enum: ['get', 'set'], description: 'get: mevcut limitler · set: güncelle' },
|
|
283
|
+
symbol: { type: 'string', description: 'set: sembol bazlı lot limiti (ör. XAUUSD) — genel set için boş bırak' },
|
|
270
284
|
minLot: { type: 'number', description: 'set: yeni alt sınır (0.01-100)' },
|
|
271
285
|
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)' },
|
|
286
|
+
maxPositions: { type: 'number', description: 'set: eşzamanlı pozisyon tavanı (1-20) — yalnız GENEL (sembol ile verilemez)' },
|
|
287
|
+
reset: { type: 'boolean', description: 'set + symbol: true → sembol limitini kaldır, genel aralığa dön' },
|
|
273
288
|
},
|
|
274
289
|
required: ['action'],
|
|
275
290
|
},
|
|
276
291
|
},
|
|
277
292
|
mt5_ogrenme: {
|
|
278
293
|
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
|
|
294
|
+
'SEMBOL BAZLI ÖĞRENME HAFIZASI — Beast Finance sürekli öğrenir: mt5_ogrenme {action:"list"|"add"|"remove"|"clear"|"stats"|"compact"|"forget", symbol?, text?, kind?, tags?, id?, ids?, all?, limit?}. Her sembolün KENDİ istatistiği (işlem/kazanç/kayıp, net, kâr yakalama, kâr geri verme) OTOMATİK birikir; ayrıca gerçekten öğrendiğin dersleri sen kaydedersin. DERS KURALLARI (SEÇİCİ): (1) Her kapanışa ders YAZMA — yalnız gerçekten öğrenilmiş, tekrar kullanılabilir, kanıtlı içgörüyü TEK KISA cümleyle kaydet (en fazla ~20 kelime / 200 karakter); ör. "XAUUSD M5 EMA50 üstü Londra açılışı momentumu 3/4 işledi". YASAK: günlük/rapor tarzı uzun metin ("bugün şunu yaptım"), genel laf ("dikkatli olmalıyım"), her turda ders, tekrar. Emin değilsen HİÇ kaydetme. (2) Yeni işlem kararından ÖNCE ilgili sembolün stats (kompakt: istatistik + kalıcı özet + son 3 ders) ya da list (son 8 ders; limit ile artır) çıktısını oku; aynı hatayı tekrarlama, işleyen deseni kullan. (3) Yanlış çıkan/genel geçersiz dersi remove/clear ile sil. Aynı ders tekrar yazılamaz; sembol başına 24 saatte en fazla 3 ders kabul edilir (kalite kapısı: çok kısa/uzun, günlük tarzı ve genel tavsiye metinleri reddedilir). HAFIZA KENDİNİ SADELEŞTİRİR (opencode tarzı compaction): ham dersler birikince (24+) ESKİ dersler OTOMATİK olarak modele özetlettirilir ve tek KALICI ÖZETE sıkıştırılır — ham yalnız son dersler kalır; 30 günden eski dersler, 90 günden eski işlem kayıtları ve 120 gün hareketsiz semboller otomatik unutulur. Gerekirse compact {symbol} ile hemen özetlet, forget ile süresi geçenleri temizle. action:"list" symbol verilmezse tüm sembollerin özetini döner (kalıcı özet dahil).',
|
|
280
295
|
parameters: {
|
|
281
296
|
type: 'object',
|
|
282
297
|
properties: {
|
|
283
|
-
action: { type: 'string', enum: ['list', 'add', 'remove', 'clear', 'stats'] },
|
|
298
|
+
action: { type: 'string', enum: ['list', 'add', 'remove', 'clear', 'stats', 'compact', 'forget'] },
|
|
284
299
|
symbol: { type: 'string', description: 'Sembol (ör. XAUUSD) — öğrenme sembol bazlıdır' },
|
|
285
|
-
text: { type: 'string', description: 'add: öğrenilen ders
|
|
300
|
+
text: { type: 'string', description: 'add: öğrenilen ders — TEK kısa cümle (en fazla ~20 kelime/200 karakter), somut ve tekrar kullanılabilir; günlük/uzun metin kaydetme' },
|
|
286
301
|
kind: { type: 'string', enum: ['pattern', 'mistake', 'rule', 'observation'], description: 'add: kayıt türü (varsayılan observation)' },
|
|
287
302
|
tags: { type: 'array', items: { type: 'string' }, description: 'add: etiketler (ör. ["scalp","london"])' },
|
|
288
303
|
id: { type: 'string', description: 'remove: kayıt id' },
|
|
289
304
|
ids: { type: 'array', items: { type: 'string' }, description: 'clear: silinecek kayıt id listesi' },
|
|
290
305
|
all: { type: 'boolean', description: 'clear: true → tüm öğrenme kayıtları (dikkatli)' },
|
|
306
|
+
limit: { type: 'number', description: 'list: döndürülecek son ders sayısı (varsayılan 8, en fazla 25)' },
|
|
291
307
|
},
|
|
292
308
|
required: ['action'],
|
|
293
309
|
},
|
|
@@ -565,8 +581,14 @@ const handlers = {
|
|
|
565
581
|
for (const k of ['minLot', 'maxLot', 'maxPositions']) {
|
|
566
582
|
if (args[k] !== undefined && args[k] !== null && args[k] !== '') patch[k] = Number(args[k]);
|
|
567
583
|
}
|
|
568
|
-
|
|
569
|
-
|
|
584
|
+
/* SEMBOL BAZLI LOT LİMİTİ: symbol verilirse trader o sembolün min/max
|
|
585
|
+
lotunu ayarlar (reset:true → genel aralığa döndürür) */
|
|
586
|
+
const sym = String(args.symbol || '').trim().toUpperCase();
|
|
587
|
+
if (sym) patch.symbol = sym;
|
|
588
|
+
const reset = args.reset === true || String(args.reset || '').toLowerCase() === 'true';
|
|
589
|
+
if (reset) patch.reset = true;
|
|
590
|
+
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)' };
|
|
570
592
|
}
|
|
571
593
|
return await limitsApi.set(patch, ctx || {});
|
|
572
594
|
}
|
|
@@ -575,7 +597,12 @@ const handlers = {
|
|
|
575
597
|
async mt5_ogrenme(args, ctx) {
|
|
576
598
|
const action = String(args.action || 'list').toLowerCase();
|
|
577
599
|
const symbol = String(args.symbol || '').trim().toUpperCase();
|
|
578
|
-
if (action === 'list')
|
|
600
|
+
if (action === 'list') {
|
|
601
|
+
/* kompakt okuma: varsayılan son 8 ders (limit ile artırılır, max 25) —
|
|
602
|
+
hafızanın tamamı ajana gönderilmez */
|
|
603
|
+
const limit = Math.round(Number(args.limit) || 0);
|
|
604
|
+
return learningApi.list({ symbol, limit: limit > 0 ? limit : 8 });
|
|
605
|
+
}
|
|
579
606
|
if (action === 'stats') return learningApi.stats({ symbol });
|
|
580
607
|
if (action === 'add') {
|
|
581
608
|
const text = String(args.text || '').replace(/\s+/g, ' ').trim();
|
|
@@ -584,9 +611,11 @@ const handlers = {
|
|
|
584
611
|
const kindRaw = String(args.kind || 'observation').toLowerCase();
|
|
585
612
|
const kind = ['pattern', 'mistake', 'rule', 'observation'].includes(kindRaw) ? kindRaw : 'observation';
|
|
586
613
|
const tags = Array.isArray(args.tags) ? args.tags.map((t) => String(t || '').trim()).filter(Boolean).slice(0, 6) : [];
|
|
587
|
-
|
|
614
|
+
/* metin AYNEN geçer: kalite kapısı (kısa+somut) main tarafında çalışır —
|
|
615
|
+
uzun/günlük metin sessizce kırpılmaz, ajan net hata alıp kısaltır */
|
|
616
|
+
const res = learningApi.add({ symbol, text, kind, tags, sid: (ctx && ctx.sessionId) || '' });
|
|
588
617
|
if (res && res.ok) {
|
|
589
|
-
noteTrade('learn', { symbol, text: text.slice(0,
|
|
618
|
+
noteTrade('learn', { symbol, text: text.slice(0, 200), kind }, ctx || {});
|
|
590
619
|
}
|
|
591
620
|
return res;
|
|
592
621
|
}
|
|
@@ -600,7 +629,18 @@ const handlers = {
|
|
|
600
629
|
const all = args.all === true || String(args.all || '').toLowerCase() === 'true';
|
|
601
630
|
return learningApi.clear({ ids, symbol, all });
|
|
602
631
|
}
|
|
603
|
-
|
|
632
|
+
if (action === 'compact') {
|
|
633
|
+
/* OPENCODE TARZI ÖZETLEME: eski dersler modele özetlettirilir, ham yalnız
|
|
634
|
+
son dersler kalır — bellek sadeleşir (normalde otomatik de çalışır) */
|
|
635
|
+
if (!symbol) return { ok: false, error: 'compact için symbol gerekli' };
|
|
636
|
+
if (typeof learningApi.compact !== 'function') return { ok: false, error: 'özetleme kullanılamıyor' };
|
|
637
|
+
return await learningApi.compact({ symbol });
|
|
638
|
+
}
|
|
639
|
+
if (action === 'forget') {
|
|
640
|
+
if (typeof learningApi.forget !== 'function') return { ok: false, error: 'temizleme kullanılamıyor' };
|
|
641
|
+
return learningApi.forget();
|
|
642
|
+
}
|
|
643
|
+
return { ok: false, error: 'action: list|add|remove|clear|stats|compact|forget' };
|
|
604
644
|
},
|
|
605
645
|
async mt5_ea(args) {
|
|
606
646
|
if (!mt5.running) return notConnected();
|
|
@@ -667,7 +707,8 @@ const handlers = {
|
|
|
667
707
|
const balance = Number(acct && acct.account && acct.account.balance) || 0;
|
|
668
708
|
if (!(balance > 0)) return { ok: false, error: 'bakiye okunamadı' };
|
|
669
709
|
const riskAmount = (balance * riskPct) / 100;
|
|
670
|
-
const
|
|
710
|
+
const range = lotRange(cfg, symbol);
|
|
711
|
+
const res = finrisk.calcRiskLot(info, entry, sl, riskAmount, range.maxLot, range.minLot);
|
|
671
712
|
if (res.error) return { ok: false, error: res.error, raw: res.raw, lossPerLot: res.lossPerLot, riskAmount: Math.round(riskAmount * 100) / 100 };
|
|
672
713
|
const digits = Number(info.digits) || 5;
|
|
673
714
|
const dist = Math.abs(entry - sl);
|
|
@@ -688,8 +729,8 @@ const handlers = {
|
|
|
688
729
|
capped: !!res.capped,
|
|
689
730
|
raised: !!res.raised,
|
|
690
731
|
warning: closeErr || undefined,
|
|
691
|
-
minLot:
|
|
692
|
-
maxLot:
|
|
732
|
+
minLot: range.minLot,
|
|
733
|
+
maxLot: range.maxLot,
|
|
693
734
|
};
|
|
694
735
|
},
|
|
695
736
|
async mt5_trade(args, ctx) {
|
|
@@ -709,7 +750,7 @@ const handlers = {
|
|
|
709
750
|
const side = t.side;
|
|
710
751
|
const symbol = String(args.symbol || '').trim().toUpperCase();
|
|
711
752
|
if (!symbol) return { ok: false, error: 'symbol gerekli' };
|
|
712
|
-
const
|
|
753
|
+
const range = lotRange(cfg, symbol);
|
|
713
754
|
const sl = Number(args.sl) || 0;
|
|
714
755
|
const tp = Number(args.tp) || 0;
|
|
715
756
|
const info = await symInfoRow(symbol);
|
|
@@ -727,12 +768,12 @@ const handlers = {
|
|
|
727
768
|
const acct = await bcall('account', {}, 8000);
|
|
728
769
|
const balance = Number(acct && acct.account && acct.account.balance) || 0;
|
|
729
770
|
const riskAmount = (balance * riskPct) / 100;
|
|
730
|
-
const rr = finrisk.calcRiskLot(info, price, sl, riskAmount, maxLot,
|
|
771
|
+
const rr = finrisk.calcRiskLot(info, price, sl, riskAmount, range.maxLot, range.minLot);
|
|
731
772
|
if (rr.error) return { ok: false, error: rr.error };
|
|
732
773
|
vol = rr.volume;
|
|
733
774
|
riskInfo = { riskPct, riskAmount: Math.round(riskAmount * 100) / 100, lossPerLot: rr.lossPerLot, raised: !!rr.raised };
|
|
734
775
|
} else {
|
|
735
|
-
const norm = finrisk.normalizeVolume(info, wantVolume, maxLot,
|
|
776
|
+
const norm = finrisk.normalizeVolume(info, wantVolume, range.maxLot, range.minLot);
|
|
736
777
|
if (norm.error) return { ok: false, error: norm.error };
|
|
737
778
|
vol = norm.volume;
|
|
738
779
|
}
|
|
@@ -849,7 +890,8 @@ const handlers = {
|
|
|
849
890
|
if (!symbol) return { ok: false, error: 'symbol gerekli' };
|
|
850
891
|
const info = await symInfoRow(symbol);
|
|
851
892
|
if (!info) return { ok: false, error: 'sembol bulunamadı: ' + symbol + ' (MT5 Market Watch?)' };
|
|
852
|
-
const
|
|
893
|
+
const range = lotRange(cfg, symbol);
|
|
894
|
+
const norm = finrisk.normalizeVolume(info, args.volume, range.maxLot, range.minLot);
|
|
853
895
|
if (norm.error) return { ok: false, error: norm.error };
|
|
854
896
|
const vol = norm.volume;
|
|
855
897
|
const ptype = t.type;
|
package/src/agent/finrisk.js
CHANGED
|
@@ -24,7 +24,9 @@ function stepCeil(v, step) {
|
|
|
24
24
|
|
|
25
25
|
/* info: MT5 symbol_info satırı. wanted: istenen lot. hardMax: kullanıcı üst
|
|
26
26
|
limiti (max lot). hardMin: kullanıcı alt limiti (min lot) — istenen lot bu
|
|
27
|
-
tabanın altındaysa adıma yukarı yuvarlanır (raised).
|
|
27
|
+
tabanın altındaysa adıma yukarı yuvarlanır (raised). Taban/tavan broker
|
|
28
|
+
adımına OTURMUYORSA (ör. min 0.15–max 0.19, adım 0.1) sessizce limit dışına
|
|
29
|
+
düşmek yerine net hata döner — aralığı mt5_limits ile düzelt. */
|
|
28
30
|
function normalizeVolume(info, wanted, hardMax, hardMin) {
|
|
29
31
|
const vmin = num(info && info.volume_min, 0.01);
|
|
30
32
|
const vmax = num(info && info.volume_max, 100);
|
|
@@ -33,24 +35,32 @@ function normalizeVolume(info, wanted, hardMax, hardMin) {
|
|
|
33
35
|
if (!(v > 0)) return { error: 'volume gerekli (pozitif sayı)' };
|
|
34
36
|
const cap = Math.min(vmax > 0 ? vmax : Infinity, num(hardMax, 0) > 0 ? num(hardMax, 0) : Infinity);
|
|
35
37
|
const floor = num(hardMin, 0) > 0 ? num(hardMin, 0) : 0;
|
|
38
|
+
const align = (x) => Math.round(x * 1e8) / 1e8;
|
|
39
|
+
const mismatch = () => ({
|
|
40
|
+
error: `lot aralığı broker adımıyla uyuşmuyor (min ${floor}, max ${cap === Infinity ? '∞' : cap}, adım ${step}) — mt5_limits ile aralığı düzelt`,
|
|
41
|
+
});
|
|
42
|
+
if (floor > cap + 1e-9) return mismatch();
|
|
36
43
|
let capped = false;
|
|
37
44
|
let raised = false;
|
|
38
45
|
if (v > cap) {
|
|
39
|
-
v = stepFloor(cap, step);
|
|
46
|
+
v = align(stepFloor(cap, step));
|
|
40
47
|
capped = true;
|
|
48
|
+
if (floor > 0 && v < floor - 1e-9) return mismatch();
|
|
41
49
|
}
|
|
42
50
|
if (v < floor - 1e-9) {
|
|
43
|
-
v = stepCeil(floor, step);
|
|
51
|
+
v = align(stepCeil(floor, step));
|
|
44
52
|
raised = true;
|
|
53
|
+
if (v > cap + 1e-9) return mismatch();
|
|
45
54
|
}
|
|
46
|
-
v =
|
|
55
|
+
v = align(stepFloor(v, step));
|
|
56
|
+
if (floor > 0 && v < floor - 1e-9) { v = align(stepCeil(floor, step)); raised = true; }
|
|
47
57
|
if (!(v > 0) || v < vmin - 1e-9) {
|
|
48
58
|
return { error: `hacim broker minimumunun altında (min ${vmin} lot)` };
|
|
49
59
|
}
|
|
50
60
|
if (v > cap + 1e-9) {
|
|
51
|
-
|
|
52
|
-
v = Math.round(stepFloor(cap, step) * 1e8) / 1e8;
|
|
61
|
+
v = align(stepFloor(cap, step));
|
|
53
62
|
capped = true;
|
|
63
|
+
if (floor > 0 && v < floor - 1e-9) return mismatch();
|
|
54
64
|
if (!(v > 0) || v < vmin - 1e-9) {
|
|
55
65
|
return { error: `hacim broker minimumunun altında (min ${vmin} lot)` };
|
|
56
66
|
}
|
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: risk-yonetimi
|
|
3
|
-
description: Pozisyon boyutlandırma ve risk disiplini rehberi — hesap yüzdesiyle lot hesabı, marj/kaldıraç denetimi, max eşzamanlı pozisyon, korelasyon/tek yön birikme, günlük kayıp limiti, SL/BE/trailing kuralları. Risk ajanı veya trader her turda ve her işlemden önce bu skill'e göre kontrol yapar.
|
|
4
|
-
version: 1.0.0
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Risk Yönetimi
|
|
8
|
-
|
|
9
|
-
## TEMEL KURAL
|
|
10
|
-
|
|
11
|
-
Önce kaybı sınırla, kârı piyasa versin. İşlem başına risk sabittir; lot, SL mesafesine göre hesaplanır.
|
|
12
|
-
|
|
13
|
-
## 1) POZİSYON BOYUTU
|
|
14
|
-
|
|
15
|
-
- İşlem başına risk: hesabın **%0.5–1'i** (agresif değilse %0.25–0.5).
|
|
16
|
-
- Lot hesabı: `lot = (bakiye × risk%) / (SL_mesafesi × sembolün pip değeri)`.
|
|
17
|
-
- SL mesafesi ATR/yapıdan gelir; önce SL belirle, sonra lotu küçült — tersini yapma.
|
|
18
|
-
- Broker limitleri: panel `max lot` ve `max eşzamanlı pozisyon` ayarlarına uy; sistem reddederse zorlama.
|
|
19
|
-
|
|
20
|
-
## 2) MARJ / KALDIRAÇ
|
|
21
|
-
|
|
22
|
-
- Serbest marjın tamamını tek işleme bağlama; toplam açık risk serbest marjın küçük bir kısmı olsun.
|
|
23
|
-
- Kaldıraç yüksekse lotu düşür; kaldıraç = risk değil, imkândır.
|
|
24
|
-
- Marj seviyesi düşerken yeni pozisyon AÇMA; önce riski azalt.
|
|
25
|
-
|
|
26
|
-
## 3) PORTFÖY DENETİMİ (her turda)
|
|
27
|
-
|
|
28
|
-
- Açık pozisyonların toplam riskini hesapla (SL'lere göre kayıp potansiyeli).
|
|
29
|
-
- **Tek yön birikme**: aynı yönde üst üste pozisyon = tek işlem gibi davranır; toplam riski tek işlem limiti gibi say.
|
|
30
|
-
- **Korelasyon**: XAUUSD/EURUSD ile DXY ters koreledir; aynı yönde iki korelasyonlu pozisyon riski katlar.
|
|
31
|
-
- SL'siz pozisyon varsa ilk iş: SL tamamla veya kapat.
|
|
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
|
|
35
|
-
|
|
36
|
-
## 4) KAYIP LİMİTLERİ
|
|
37
|
-
|
|
38
|
-
- Günlük kayıp limiti belirle (ör. hesabın %2–3'ü). Limit dolduysa **o gün yeni işlem yok**; raporla.
|
|
39
|
-
- Üst üste 2-3 kayıptan sonra lotu artırma (revenge trade YASAK); aksine küçült veya dur.
|
|
40
|
-
- Drawdown artıyorsa tur sıklığını/agresifliği azalt, sadece A+ setuplara gir.
|
|
41
|
-
|
|
42
|
-
## 5) YASAKLAR
|
|
43
|
-
|
|
44
|
-
- Martingale / kademeli lot artışı.
|
|
45
|
-
- SL taşımayı kaybı büyütecek yönde yapmak (SL genişletme).
|
|
46
|
-
- Marjı zorlayan "son işlem" kumarı.
|
|
47
|
-
- Aynı anda korelasyonlu 3+ pozisyonla tek yön yığmak.
|
|
48
|
-
|
|
49
|
-
## 6) RAPOR FORMATI
|
|
50
|
-
|
|
51
|
-
`Risk: toplam açık R%X | marj kullanımı %Y | en riskli pozisyon: ... | öneri: SL/BE/küçült/kapat`
|
|
52
|
-
Sınır aşımı varsa öncelikli ve net yaz.
|
|
1
|
+
---
|
|
2
|
+
name: risk-yonetimi
|
|
3
|
+
description: Pozisyon boyutlandırma ve risk disiplini rehberi — hesap yüzdesiyle lot hesabı, marj/kaldıraç denetimi, max eşzamanlı pozisyon, korelasyon/tek yön birikme, günlük kayıp limiti, SL/BE/trailing kuralları. Risk ajanı veya trader her turda ve her işlemden önce bu skill'e göre kontrol yapar.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Risk Yönetimi
|
|
8
|
+
|
|
9
|
+
## TEMEL KURAL
|
|
10
|
+
|
|
11
|
+
Önce kaybı sınırla, kârı piyasa versin. İşlem başına risk sabittir; lot, SL mesafesine göre hesaplanır.
|
|
12
|
+
|
|
13
|
+
## 1) POZİSYON BOYUTU
|
|
14
|
+
|
|
15
|
+
- İşlem başına risk: hesabın **%0.5–1'i** (agresif değilse %0.25–0.5).
|
|
16
|
+
- Lot hesabı: `lot = (bakiye × risk%) / (SL_mesafesi × sembolün pip değeri)`.
|
|
17
|
+
- SL mesafesi ATR/yapıdan gelir; önce SL belirle, sonra lotu küçült — tersini yapma.
|
|
18
|
+
- Broker limitleri: panel `max lot` ve `max eşzamanlı pozisyon` ayarlarına uy; sistem reddederse zorlama.
|
|
19
|
+
|
|
20
|
+
## 2) MARJ / KALDIRAÇ
|
|
21
|
+
|
|
22
|
+
- Serbest marjın tamamını tek işleme bağlama; toplam açık risk serbest marjın küçük bir kısmı olsun.
|
|
23
|
+
- Kaldıraç yüksekse lotu düşür; kaldıraç = risk değil, imkândır.
|
|
24
|
+
- Marj seviyesi düşerken yeni pozisyon AÇMA; önce riski azalt.
|
|
25
|
+
|
|
26
|
+
## 3) PORTFÖY DENETİMİ (her turda)
|
|
27
|
+
|
|
28
|
+
- Açık pozisyonların toplam riskini hesapla (SL'lere göre kayıp potansiyeli).
|
|
29
|
+
- **Tek yön birikme**: aynı yönde üst üste pozisyon = tek işlem gibi davranır; toplam riski tek işlem limiti gibi say.
|
|
30
|
+
- **Korelasyon**: XAUUSD/EURUSD ile DXY ters koreledir; aynı yönde iki korelasyonlu pozisyon riski katlar.
|
|
31
|
+
- SL'siz pozisyon varsa ilk iş: SL tamamla veya kapat.
|
|
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 (seçici):** her kapanışa ders YAZMA — yalnız gerçekten öğretici, tekrar kullanılabilir içgörüyü TEK kısa cümleyle (≈20 kelime) mt5_ogrenme add ile kaydet; yeni işlem öncesi o sembolün stats/list geçmişini oku — aynı hatayı tekrarlama.
|
|
35
|
+
|
|
36
|
+
## 4) KAYIP LİMİTLERİ
|
|
37
|
+
|
|
38
|
+
- Günlük kayıp limiti belirle (ör. hesabın %2–3'ü). Limit dolduysa **o gün yeni işlem yok**; raporla.
|
|
39
|
+
- Üst üste 2-3 kayıptan sonra lotu artırma (revenge trade YASAK); aksine küçült veya dur.
|
|
40
|
+
- Drawdown artıyorsa tur sıklığını/agresifliği azalt, sadece A+ setuplara gir.
|
|
41
|
+
|
|
42
|
+
## 5) YASAKLAR
|
|
43
|
+
|
|
44
|
+
- Martingale / kademeli lot artışı.
|
|
45
|
+
- SL taşımayı kaybı büyütecek yönde yapmak (SL genişletme).
|
|
46
|
+
- Marjı zorlayan "son işlem" kumarı.
|
|
47
|
+
- Aynı anda korelasyonlu 3+ pozisyonla tek yön yığmak.
|
|
48
|
+
|
|
49
|
+
## 6) RAPOR FORMATI
|
|
50
|
+
|
|
51
|
+
`Risk: toplam açık R%X | marj kullanımı %Y | en riskli pozisyon: ... | öneri: SL/BE/küçült/kapat`
|
|
52
|
+
Sınır aşımı varsa öncelikli ve net yaz.
|