beast-agent 2.76.6 → 2.77.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.
Files changed (54) hide show
  1. package/package.json +1 -1
  2. package/src/agent/bots.js +669 -664
  3. package/src/agent/customtools.js +6 -19
  4. package/src/agent/engine.js +55 -307
  5. package/src/agent/seeds/tool-yazma/SKILL.md +13 -16
  6. package/src/agent/skills.js +14 -35
  7. package/src/agent/supertonic.js +622 -0
  8. package/src/agent/tools.js +3 -7
  9. package/src/main.js +77 -6164
  10. package/src/preload.js +2 -18
  11. package/src/renderer/i18n.js +14 -8
  12. package/src/renderer/index.html +0 -297
  13. package/src/renderer/renderer.js +142 -2301
  14. package/src/renderer/style.css +3 -825
  15. package/src/agent/defaulttools/mt5_barlar2/run.js +0 -188
  16. package/src/agent/defaulttools/mt5_barlar2/tool.json +0 -23
  17. package/src/agent/defaulttools/mt5_bekleyen/run.js +0 -105
  18. package/src/agent/defaulttools/mt5_bekleyen/tool.json +0 -18
  19. package/src/agent/defaulttools/mt5_durum/run.js +0 -93
  20. package/src/agent/defaulttools/mt5_durum/tool.json +0 -10
  21. package/src/agent/defaulttools/mt5_emir/run.js +0 -98
  22. package/src/agent/defaulttools/mt5_emir/tool.json +0 -17
  23. package/src/agent/defaulttools/mt5_emir_iptal/run.js +0 -90
  24. package/src/agent/defaulttools/mt5_emir_iptal/tool.json +0 -12
  25. package/src/agent/defaulttools/mt5_fiyat/run.js +0 -87
  26. package/src/agent/defaulttools/mt5_fiyat/tool.json +0 -16
  27. package/src/agent/defaulttools/mt5_gecmis/run.js +0 -87
  28. package/src/agent/defaulttools/mt5_gecmis/tool.json +0 -12
  29. package/src/agent/defaulttools/mt5_kapat/run.js +0 -108
  30. package/src/agent/defaulttools/mt5_kapat/tool.json +0 -15
  31. package/src/agent/defaulttools/mt5_m15_m5/m15m5.py +0 -60
  32. package/src/agent/defaulttools/mt5_m15_m5/run.js +0 -73
  33. package/src/agent/defaulttools/mt5_m15_m5/tool.json +0 -10
  34. package/src/agent/defaulttools/mt5_pozisyon_gecmis/run.js +0 -144
  35. package/src/agent/defaulttools/mt5_pozisyon_gecmis/tool.json +0 -12
  36. package/src/agent/defaulttools/mt5_shot/run.js +0 -649
  37. package/src/agent/defaulttools/mt5_shot/stitch.js +0 -151
  38. package/src/agent/defaulttools/mt5_shot/tool.json +0 -25
  39. package/src/agent/defaulttools/mt5_sltp/run.js +0 -92
  40. package/src/agent/defaulttools/mt5_sltp/tool.json +0 -14
  41. package/src/agent/financetools.js +0 -1025
  42. package/src/agent/finindicators.js +0 -254
  43. package/src/agent/finrisk.js +0 -289
  44. package/src/agent/finstats.js +0 -239
  45. package/src/agent/finwatch.js +0 -302
  46. package/src/agent/mt5/BeastFinance.mq5 +0 -498
  47. package/src/agent/mt5/BeastShot.tpl +0 -0
  48. package/src/agent/mt5setup.js +0 -542
  49. package/src/agent/scripts/mt5_bridge.py +0 -575
  50. package/src/agent/seeds/haber-duygu/SKILL.md +0 -49
  51. package/src/agent/seeds/mql5/SKILL.md +0 -154
  52. package/src/agent/seeds/price-action/SKILL.md +0 -60
  53. package/src/agent/seeds/risk-yonetimi/SKILL.md +0 -52
  54. package/src/mt5bridge.js +0 -215
@@ -1,151 +0,0 @@
1
- 'use strict';
2
- /* mt5_shot yardımcı: birden çok PNG'yi TEK karede birleştirir (yan yana / alt alta).
3
- - @napi-rs/canvas uygulamanın node_modules'ından yüklenir; kişisel tool çocuk
4
- prosesi uygulama klasörü dışında koştuğu için yol BEAST_APP_DIR'den gelir
5
- (customtools env olarak verir; app.asar → app.asar.unpacked otomatik denenir).
6
- - Panel başına üst köşeye "SEMBOL · PERİYOT" etiketi çizilir: görsel ajan hangi
7
- tarafın hangi zaman dilimi olduğunu görüntüden de okur.
8
- - Toplam boyut sınırı aşılırsa paneller eşit oranda küçültülür. */
9
-
10
- const path = require('path');
11
-
12
- let cached = undefined;
13
- function loadCanvas() {
14
- if (cached !== undefined) return cached || null;
15
- cached = null;
16
- const cands = [];
17
- const push = (base) => {
18
- const b = String(base || '').trim();
19
- if (!b) return;
20
- if (!cands.includes(b)) cands.push(b);
21
- const un = b.replace(/app\.asar([\\/])/i, 'app.asar.unpacked$1');
22
- if (un !== b && !cands.includes(un)) cands.push(un);
23
- };
24
- push(process.env.BEAST_APP_DIR);
25
- push(path.join(process.env.BEAST_APP_DIR || '', '..'));
26
- for (const base of cands) {
27
- try {
28
- cached = require(path.join(base, 'node_modules', '@napi-rs', 'canvas'));
29
- if (cached && typeof cached.createCanvas === 'function') break;
30
- } catch (e) { cached = null; }
31
- }
32
- return cached || null;
33
- }
34
-
35
- const MAX_W = 4800; /* birleşik tuval genişlik tavanı */
36
- const MAX_H = 3000; /* yükseklik tavanı */
37
- const MAX_PX = 9 * 1e6; /* toplam piksel tavanı (güvenlik) */
38
- const GAP = 8; /* paneller arası ayırıcı kalınlığı */
39
- const LABEL_H = 30; /* etiket şeridi yüksekliği */
40
-
41
- function pickFont(size) {
42
- return 'bold ' + size + 'px "Segoe UI", Arial, sans-serif';
43
- }
44
-
45
- /* panels: [{ path, label }] · opts: { layout: 'h'|'v' }
46
- dönüş: { ok:true, buffer, width, height } | { ok:false, error } */
47
- async function compose(panels, opts) {
48
- const cv = loadCanvas();
49
- if (!cv) return { ok: false, error: 'görüntü kütüphanesi bulunamadı (@napi-rs/canvas) — tek periyot çekimi kullanın' };
50
- const { createCanvas, loadImage } = cv;
51
- const list = (panels || []).filter((p) => p && p.path);
52
- if (list.length < 2) return { ok: false, error: 'birleştirme için en az 2 panel gerekli' };
53
-
54
- const imgs = [];
55
- for (const p of list) {
56
- const im = await loadImage(p.path);
57
- imgs.push({ img: im, label: String(p.label || ''), w: im.width, h: im.height });
58
- }
59
-
60
- const layout = String((opts && opts.layout) || 'h').toLowerCase() === 'v' ? 'v' : 'h';
61
- let cellW = 0, cellH = 0;
62
- if (layout === 'h') {
63
- cellW = Math.max(...imgs.map((i) => i.w));
64
- cellH = Math.max(...imgs.map((i) => i.h));
65
- } else {
66
- cellW = Math.max(...imgs.map((i) => i.w));
67
- cellH = Math.max(...imgs.map((i) => i.h));
68
- }
69
- const n = imgs.length;
70
- let W = layout === 'h' ? cellW * n + GAP * (n - 1) : cellW;
71
- let H = layout === 'h' ? cellH : cellH * n + GAP * (n - 1);
72
-
73
- /* boyut tavanları: eşit oranda küçült */
74
- let scale = 1;
75
- if (W > MAX_W) scale = Math.min(scale, MAX_W / W);
76
- if (H > MAX_H) scale = Math.min(scale, MAX_H / H);
77
- if (W * H * scale * scale > MAX_PX) scale = Math.min(scale, Math.sqrt(MAX_PX / (W * H)));
78
- if (scale < 1) {
79
- cellW = Math.max(320, Math.floor(cellW * scale));
80
- cellH = Math.max(200, Math.floor(cellH * scale));
81
- W = layout === 'h' ? cellW * n + GAP * (n - 1) : cellW;
82
- H = layout === 'h' ? cellH : cellH * n + GAP * (n - 1);
83
- }
84
-
85
- const canvas = createCanvas(W, H);
86
- const ctx = canvas.getContext('2d');
87
- ctx.fillStyle = '#0b0b0b';
88
- ctx.fillRect(0, 0, W, H);
89
-
90
- imgs.forEach((p, i) => {
91
- const x = layout === 'h' ? i * (cellW + GAP) : 0;
92
- const y = layout === 'h' ? 0 : i * (cellH + GAP);
93
- ctx.drawImage(p.img, x, y, cellW, cellH);
94
- /* ayırıcı çizgi */
95
- if (i > 0) {
96
- ctx.fillStyle = '#3a3a3a';
97
- if (layout === 'h') ctx.fillRect(x - GAP, 0, GAP, H);
98
- else ctx.fillRect(0, y - GAP, W, GAP);
99
- }
100
- /* etiket: SOL ÜST köşede BÜYÜK zaman dilimi (üstünde küçük sembol) —
101
- görsel ajan hangi panelin hangi periyot olduğunu bakışta okur;
102
- son mumlar sağda olduğundan etiket oraya konmaz (mumları kapatıyordu) */
103
- if (p.label) {
104
- try {
105
- const parts = String(p.label).split('·').map((s) => s.trim()).filter(Boolean);
106
- const tf = parts.length > 1 ? parts[1] : parts[0];
107
- const sym = parts.length > 1 ? parts[0] : '';
108
- const fsTf = Math.max(22, Math.round(cellW / 44)); /* 1600 px panel → 36 px */
109
- const fsSym = Math.max(12, Math.round(fsTf * 0.45));
110
- const padX = Math.round(fsTf * 0.55);
111
- const padY = Math.round(fsTf * 0.42);
112
- const lineGap = Math.round(fsSym * 0.45);
113
- ctx.textBaseline = 'middle';
114
- ctx.textAlign = 'left';
115
- ctx.font = pickFont(fsTf);
116
- const tw = ctx.measureText(tf).width;
117
- ctx.font = pickFont(fsSym);
118
- const sw = sym ? ctx.measureText(sym).width : 0;
119
- const boxW = Math.ceil(Math.max(tw, sw) + padX * 2);
120
- const boxH = Math.ceil(padY * 2 + fsTf + (sym ? fsSym + lineGap : 0));
121
- const bx = x + 10;
122
- const by = y + 10;
123
- ctx.fillStyle = 'rgba(0,0,0,0.80)';
124
- ctx.fillRect(bx, by, boxW, boxH);
125
- ctx.fillStyle = '#00e676';
126
- ctx.fillRect(bx, by, boxW, 3); /* üst aksan çizgisi */
127
- if (sym) {
128
- ctx.font = pickFont(fsSym);
129
- ctx.fillStyle = '#c9d2d9';
130
- ctx.fillText(sym, bx + padX, by + padY + fsSym / 2);
131
- }
132
- ctx.font = pickFont(fsTf);
133
- ctx.fillStyle = '#00e676';
134
- ctx.fillText(tf, bx + padX, by + padY + (sym ? fsSym + lineGap : 0) + fsTf / 2);
135
- ctx.textAlign = 'start';
136
- } catch (e) {}
137
- }
138
- });
139
-
140
- let buffer = null;
141
- try { buffer = canvas.toBuffer('image/png'); } catch (e) {
142
- return { ok: false, error: 'PNG kodlanamadı: ' + (e && e.message ? e.message : String(e)) };
143
- }
144
- return { ok: true, buffer, width: W, height: H };
145
- }
146
-
147
- function available() {
148
- return !!loadCanvas();
149
- }
150
-
151
- module.exports = { compose, available };
@@ -1,25 +0,0 @@
1
- {
2
- "name": "mt5_shot",
3
- "defaultsVersion": 7,
4
- "description": "MT5 grafiğinin GERÇEK ekran görüntüsünü alır ve GÖRSELİ ÇAĞIRAN AJANA GÖSTERİR: MT5\\MQL5\\Files\\beast_cmd.json üzerinden BeastFinance EA'ya 'shot' komutu yazar, EA ChartScreenShot ile PNG üretir; PNG hem tool klasörüne hem <kullanıcı>\\beast_shots altına kopyalanır (dönen path send_file'a verilebilir) hem de data URL olarak sonuca gömülür — engine bunu sonraki turda ajana görsel olarak enjekte eder (embed:false kapatır). ÇOKLU SEMBOL: symbols:[\"GOLD\",\"EURUSD\",\"BTCUSD\"] (2-4 sembol) verirsen her sembolden bir kare çekilip TEK PNG'de birleştirilir (izleme listesinin tamamı TEK görselle gönderilir); timeframes ile birlikte verilirse sembol × periyot ızgarası kurulur (en fazla 6 kare). ÇOKLU ZAMAN DİLİMİ: timeframes:[\"M1\",\"M15\"] verirsen aynı sembolün periyotları SIRAYLA çekilip TEK PNG'de birleştirilir (layout:\"h\" soldan sağa — varsayılan; \"v\" üstten alta; 2-3 periyot) ve her panelin SOL ÜST köşesine BÜYÜK periyot etiketi (üstünde küçük sembol) çizilir — solda/sağda hangi sembol/periyot olduğu görüntüden bakışta okunur; etiket son mumları örtmez. Aktif grafik istenen sembol/periyot ile aynıysa ondan çekilir (Beast panosu + seviye çizgileri görünür), değilse EA geçici grafik açar (ChartOpen/ChartSetSymbolPeriod + BeastShot.tpl açık tema); çoklu sembolde her sembol için sırayla. Çekim öncesi grafiğe sağ boşluk payı (chart shift %12) uygulanır — SON MUM sağ kenara yapışmaz; aktif grafikte önceki ayar çekimden sonra geri yazılır. Komut id/ts ile yazılır, ack poll edilir ve PNG MQL5\\Files'ta belirene kadar beklenir; hata halinde gövde şu kodu taşır: err = no_terminal|ea_offline|cmd_write_fail|ea_no_ack|ea_error|png_yok|timeout|stitch_fail (+ cmdId, filesDir, diagnostic, ping). Grafik analizi/raporu ve ekip paylaşımı için birincil screenshot aracıdır.",
5
- "parameters": {
6
- "type": "object",
7
- "properties": {
8
- "symbol": { "type": "string", "description": "Tek sembol (örn GOLD); boş = aktif grafik sembolü. Çoklu sembol için symbols kullan" },
9
- "symbols": { "type": "array", "items": { "type": "string" }, "description": "ÇOKLU SEMBOL TEK GÖRÜNTÜ: örn [\"GOLD\",\"EURUSD\",\"BTCUSD\"] — her sembolden bir kare çekilip etiketli tek PNG'de birleştirilir (2-4 sembol; timeframes ile birlikte sembol × periyot ızgarası, en fazla 6 kare)" },
10
- "timeframe": { "type": "string", "description": "M1|M5|M15|M30|H1|H4|D1 (boş = aktif periyot)" },
11
- "timeframes": { "type": "array", "items": { "type": "string" }, "description": "ÇOKLU PERİYOT TEK GÖRÜNTÜ: örn [\"M1\",\"M15\"] — sırayla çekilip tek PNG'de birleştirilir (2-3 adet; soldan sağa); symbols ile birlikte ızgara" },
12
- "tf2": { "type": "string", "description": "İkinci periyot kısayolu (timeframe ile birlikte): örn timeframe M1 + tf2 M15" },
13
- "layout": { "type": "string", "description": "Çoklu kare yerleşimi: h = yan yana (varsayılan), v = alt alta" },
14
- "width": { "type": "number", "description": "Panel başına görüntü genişliği (varsayılan 1600)" },
15
- "height": { "type": "number", "description": "Panel başına görüntü yüksekliği (varsayılan 900)" },
16
- "file": { "type": "string", "description": "Opsiyonel dosya adı (varsayılan beast_shot_<id>.png; çoklu karede birleşik dosyanın adı)" },
17
- "timeoutSec": { "type": "number", "description": "Ack/PNG bekleme süresi sn (varsayılan 20, 5-70; çoklu karede panel başına 15 sn tavan)" },
18
- "outdir": { "type": "string", "description": "PNG'nin kopyalanacağı klasör (varsayılan <kullanıcı>\\beast_shots — send_file buradan gönderebilir)" },
19
- "diag": { "type": "boolean", "description": "Ack gelmezse teşhis amaçlı ping at (varsayılan true)" },
20
- "embed": { "type": "boolean", "description": "PNG'yi ajana görsel olarak enjekte et (varsayılan true; false = yalnız dosya yolu döner)" }
21
- },
22
- "required": []
23
- },
24
- "updatedAt": "2026-09-15T00:00:00.000Z"
25
- }
@@ -1,92 +0,0 @@
1
- 'use strict';
2
- // MT5 SL/TP GUNCELLE — stdin: JSON args · stdout: JSON sonuç
3
- const { spawn } = require('child_process');
4
- const fs = require('fs');
5
- const path = require('path');
6
-
7
- /* TAŞINABİLİR YOL ÇÖZÜMÜ: Beast gömülü python → sistem python'ları → PATH.
8
- Köprü dosyası %APPDATA%\beast\finance\mt5_bridge.py'den (veya BEAST_FINANCE_DIR)
9
- okunur; ortam değişkenleriyle geçersiz kılınabilir. */
10
- function resolvePython() {
11
- const cands = [];
12
- if (process.env.BEAST_PYTHON) cands.push({ exe: String(process.env.BEAST_PYTHON), args: [] });
13
- if (process.env.APPDATA) cands.push({ exe: path.join(process.env.APPDATA, 'beast', 'py', 'python.exe'), args: [] });
14
- for (const v of ['314', '313', '312', '311', '310']) cands.push({ exe: 'C:\\Python' + v + '\\python.exe', args: [] });
15
- cands.push({ exe: 'python', args: [] }, { exe: 'py', args: ['-3'] });
16
- for (const c of cands) {
17
- if (c.exe === 'python' || c.exe === 'py') return c;
18
- try { if (fs.existsSync(c.exe)) return c; } catch (e) {}
19
- }
20
- return { exe: 'python', args: [] };
21
- }
22
- function resolveBridge() {
23
- const cands = [];
24
- if (process.env.BEAST_BRIDGE) cands.push(String(process.env.BEAST_BRIDGE));
25
- if (process.env.BEAST_FINANCE_DIR) cands.push(path.join(String(process.env.BEAST_FINANCE_DIR), 'mt5_bridge.py'));
26
- if (process.env.APPDATA) cands.push(path.join(process.env.APPDATA, 'beast', 'finance', 'mt5_bridge.py'));
27
- for (const p of cands) { try { if (p && fs.existsSync(p)) return p; } catch (e) {} }
28
- return cands[0] || '';
29
- }
30
- const PYSPEC = resolvePython();
31
- const PY = PYSPEC.exe;
32
- const PY_ARGS = PYSPEC.args;
33
- const BRIDGE = resolveBridge();
34
-
35
- const TIMEOUT = 35000;
36
-
37
- function call(requests) {
38
- return new Promise((resolve) => {
39
- let py;
40
- try { py = spawn(PY, [...PY_ARGS, BRIDGE], { windowsHide: true, stdio: ['pipe', 'pipe', 'pipe'] }); }
41
- catch (e) { return resolve({ ok: false, error: 'python baslatilamadi: ' + e.message }); }
42
- const results = {};
43
- let buf = '';
44
- let errTail = '';
45
- let settled = false;
46
- const finish = (obj) => { if (!settled) { settled = true; clearTimeout(timer); try { py.kill(); } catch (e) {} resolve(obj); } };
47
- const timer = setTimeout(() => finish({ ok: false, error: 'zaman asimi: MT5 terminali acik ve yanit veriyor mu?' }), TIMEOUT);
48
- py.stdout.on('data', (d) => {
49
- buf += d.toString('utf8');
50
- let i;
51
- while ((i = buf.indexOf('\n')) >= 0) {
52
- const line = buf.slice(0, i).trim(); buf = buf.slice(i + 1);
53
- if (!line) continue;
54
- let o = null;
55
- try { o = JSON.parse(line); } catch (e) { continue; }
56
- if (o && o.event) continue;
57
- if (o && typeof o.id === 'number' && Object.prototype.hasOwnProperty.call(o, 'ok')) {
58
- results[o.id] = o;
59
- if (Object.keys(results).length >= requests.length) {
60
- const arr = requests.map((_, k) => results[k + 1]);
61
- finish(arr.length === 1 ? arr[0] : { ok: true, results: arr });
62
- }
63
- }
64
- }
65
- });
66
- py.stderr.on('data', (d) => { errTail = (errTail + d.toString('utf8')).slice(-800); });
67
- py.on('error', (e) => finish({ ok: false, error: 'python baslatilamadi: ' + e.message }));
68
- py.on('close', (code) => { if (Object.keys(results).length < requests.length) finish({ ok: false, error: 'bridge erken cikti code=' + code + ' ' + errTail }); });
69
- requests.forEach((r, k) => py.stdin.write(JSON.stringify({ id: k + 1, method: r.method, params: r.params || {} }) + '\n'));
70
- py.stdin.end();
71
- });
72
- }
73
-
74
- (async function main() {
75
- let args = {};
76
- try { args = JSON.parse(fs.readFileSync(0, 'utf8') || '{}'); } catch (e) {}
77
- const ticket = Number(args.ticket || 0);
78
- if (!ticket) return console.log(JSON.stringify({ ok: false, error: 'ticket zorunlu' }));
79
- if (args.sl === undefined && args.tp === undefined) return console.log(JSON.stringify({ ok: false, error: 'sl veya tp vermelisin' }));
80
- const params = { ticket: ticket, sl: Number(args.sl || 0), tp: Number(args.tp || 0) };
81
- const r = await call([{ method: 'modify', params: params }]);
82
- if (r.ok && r.data && r.data.result) {
83
- const res = r.data.result;
84
- console.log(JSON.stringify({ ok: true, retcode: res.retcode, comment: res.comment, detay: r.data }));
85
- } else {
86
- console.log(JSON.stringify({ ok: false, error: r.error || 'SL/TP guncelleme reddedildi' }));
87
- }
88
- })();
89
-
90
- /* PATCH 2026-09-10b: electron app-mode cocuk prosesi kapanmiyordu (90sn timeout).
91
- stdout'un boruya bosalmasi icin kisa bekleme, sonra zorla cik. */
92
- setTimeout(() => process.exit(0), 1500);
@@ -1,14 +0,0 @@
1
- {
2
- "name": "mt5_sltp",
3
- "description": "Açık pozisyonun STOP LOSS / TAKE PROFIT seviyelerini günceller: ticket zorunlu, sl ve/veya tp verilir (0 = o seviyeyi kaldir). SL'siz pozisyon bırakmamak için risk yönetiminde kullanılır.",
4
- "parameters": {
5
- "type": "object",
6
- "properties": {
7
- "ticket": { "type": "number", "description": "Pozisyonun ticket numarasi" },
8
- "sl": { "type": "number", "description": "Yeni stop loss fiyati (0 = kaldir)" },
9
- "tp": { "type": "number", "description": "Yeni take profit fiyati (0 = kaldir)" }
10
- },
11
- "required": ["ticket"]
12
- },
13
- "updatedAt": "2026-09-09T18:48:00.000Z"
14
- }