beast-agent 2.76.5 → 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.
- package/package.json +1 -1
- package/src/agent/bots.js +669 -664
- package/src/agent/customtools.js +6 -19
- package/src/agent/engine.js +55 -307
- package/src/agent/seeds/tool-yazma/SKILL.md +13 -16
- package/src/agent/skills.js +14 -35
- package/src/agent/supertonic.js +622 -0
- package/src/agent/tools.js +3 -7
- package/src/main.js +77 -6068
- package/src/preload.js +2 -17
- package/src/renderer/i18n.js +14 -8
- package/src/renderer/index.html +0 -297
- package/src/renderer/renderer.js +142 -2280
- package/src/renderer/style.css +3 -825
- package/src/agent/defaulttools/mt5_barlar2/run.js +0 -188
- package/src/agent/defaulttools/mt5_barlar2/tool.json +0 -23
- package/src/agent/defaulttools/mt5_bekleyen/run.js +0 -105
- package/src/agent/defaulttools/mt5_bekleyen/tool.json +0 -18
- package/src/agent/defaulttools/mt5_durum/run.js +0 -93
- package/src/agent/defaulttools/mt5_durum/tool.json +0 -10
- package/src/agent/defaulttools/mt5_emir/run.js +0 -98
- package/src/agent/defaulttools/mt5_emir/tool.json +0 -17
- package/src/agent/defaulttools/mt5_emir_iptal/run.js +0 -90
- package/src/agent/defaulttools/mt5_emir_iptal/tool.json +0 -12
- package/src/agent/defaulttools/mt5_fiyat/run.js +0 -87
- package/src/agent/defaulttools/mt5_fiyat/tool.json +0 -16
- package/src/agent/defaulttools/mt5_gecmis/run.js +0 -87
- package/src/agent/defaulttools/mt5_gecmis/tool.json +0 -12
- package/src/agent/defaulttools/mt5_kapat/run.js +0 -108
- package/src/agent/defaulttools/mt5_kapat/tool.json +0 -15
- package/src/agent/defaulttools/mt5_m15_m5/m15m5.py +0 -60
- package/src/agent/defaulttools/mt5_m15_m5/run.js +0 -73
- package/src/agent/defaulttools/mt5_m15_m5/tool.json +0 -10
- package/src/agent/defaulttools/mt5_pozisyon_gecmis/run.js +0 -144
- package/src/agent/defaulttools/mt5_pozisyon_gecmis/tool.json +0 -12
- package/src/agent/defaulttools/mt5_shot/run.js +0 -649
- package/src/agent/defaulttools/mt5_shot/stitch.js +0 -151
- package/src/agent/defaulttools/mt5_shot/tool.json +0 -25
- package/src/agent/defaulttools/mt5_sltp/run.js +0 -92
- package/src/agent/defaulttools/mt5_sltp/tool.json +0 -14
- package/src/agent/financetools.js +0 -1025
- package/src/agent/finindicators.js +0 -254
- package/src/agent/finrisk.js +0 -289
- package/src/agent/finstats.js +0 -239
- package/src/agent/finwatch.js +0 -302
- package/src/agent/mt5/BeastFinance.mq5 +0 -498
- package/src/agent/mt5/BeastShot.tpl +0 -0
- package/src/agent/mt5setup.js +0 -542
- package/src/agent/scripts/mt5_bridge.py +0 -575
- package/src/agent/seeds/haber-duygu/SKILL.md +0 -49
- package/src/agent/seeds/mql5/SKILL.md +0 -154
- package/src/agent/seeds/price-action/SKILL.md +0 -60
- package/src/agent/seeds/risk-yonetimi/SKILL.md +0 -52
- package/src/mt5bridge.js +0 -215
|
@@ -1,498 +0,0 @@
|
|
|
1
|
-
//+------------------------------------------------------------------+
|
|
2
|
-
//| BeastFinance.mq5 — Beast Finance köprü EA'sı (v1.22) |
|
|
3
|
-
//| - Heartbeat: MQL5\Files\beast_ea.json (durum + izinler + equity) |
|
|
4
|
-
//| - Komut köprüsü: beast_cmd.json (Beast yazar) → beast_cmd_ack.json|
|
|
5
|
-
//| - Entegrasyon/Screenshot: grafik üstü pano (Comment) + seviye |
|
|
6
|
-
//| çizgileri — Beast beast_note.json ile besler; görsel ajan |
|
|
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). |
|
|
11
|
-
//+------------------------------------------------------------------+
|
|
12
|
-
#property copyright "Beast Agent"
|
|
13
|
-
#property link "https://github.com/algokodcom/beast-agent"
|
|
14
|
-
#property version "1.22"
|
|
15
|
-
#property description "Beast Finance köprü EA'sı — heartbeat + komut köprüsü + grafik panosu."
|
|
16
|
-
|
|
17
|
-
input string InpTag = "BeastFinance"; // Etiket
|
|
18
|
-
input int InpHeartbeat = 5; // Kalp atışı (sn)
|
|
19
|
-
input bool InpVerbose = true; // Grafik panosunu yaz
|
|
20
|
-
input long InpMagic = 20260910; // Magic number (Python köprüsü kullanır)
|
|
21
|
-
|
|
22
|
-
string BeatFile = "beast_ea.json";
|
|
23
|
-
string CmdFile = "beast_cmd.json";
|
|
24
|
-
string AckFile = "beast_cmd_ack.json";
|
|
25
|
-
string NoteFile = "beast_note.json";
|
|
26
|
-
string LvlPrefix = "BeastLvl_";
|
|
27
|
-
|
|
28
|
-
string gNoteText = "";
|
|
29
|
-
string gNoteSymbol = "";
|
|
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
|
-
|
|
56
|
-
int OnInit()
|
|
57
|
-
{
|
|
58
|
-
EventSetTimer(MathMax(1, InpHeartbeat));
|
|
59
|
-
WriteBeat("init");
|
|
60
|
-
RefreshPanel();
|
|
61
|
-
Print("BeastFinance EA başlatıldı: ", _Symbol, " period=", (int)Period());
|
|
62
|
-
return(INIT_SUCCEEDED);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
void OnDeinit(const int reason)
|
|
66
|
-
{
|
|
67
|
-
EventKillTimer();
|
|
68
|
-
FlushPendingShot();
|
|
69
|
-
WriteBeat("deinit");
|
|
70
|
-
ClearLevels();
|
|
71
|
-
Comment("");
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
void OnTimer()
|
|
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();
|
|
81
|
-
ReadNote();
|
|
82
|
-
WriteBeat("beat");
|
|
83
|
-
ProcessCommands();
|
|
84
|
-
RefreshPanel();
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
void OnTick()
|
|
88
|
-
{
|
|
89
|
-
// Fiyat bazlı ek işler ileride buraya eklenecek (sinyal/uyarı üretimi).
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
string JStr(string s)
|
|
93
|
-
{
|
|
94
|
-
StringReplace(s, "\\", "\\\\");
|
|
95
|
-
StringReplace(s, "\"", "\\\"");
|
|
96
|
-
return s;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
void WriteBeat(const string stage)
|
|
100
|
-
{
|
|
101
|
-
int h = FileOpen(BeatFile, FILE_WRITE|FILE_TXT|FILE_UNICODE);
|
|
102
|
-
if(h == INVALID_HANDLE) return;
|
|
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\"}",
|
|
104
|
-
JStr(InpTag), stage, (int)TimeCurrent(), TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS),
|
|
105
|
-
_Symbol, (int)Period(),
|
|
106
|
-
AccountInfoDouble(ACCOUNT_EQUITY), AccountInfoDouble(ACCOUNT_BALANCE),
|
|
107
|
-
(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) ? "true" : "false"),
|
|
108
|
-
(MQLInfoInteger(MQL_TRADE_ALLOWED) ? "true" : "false"),
|
|
109
|
-
PositionsTotal(),
|
|
110
|
-
JStr(StringSubstr(gNoteText, 0, 120)));
|
|
111
|
-
FileWriteString(h, js);
|
|
112
|
-
FileClose(h);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/* ---------- grafik panosu (screenshot'larda görünür) ---------- */
|
|
116
|
-
|
|
117
|
-
void RefreshPanel()
|
|
118
|
-
{
|
|
119
|
-
if(!InpVerbose)
|
|
120
|
-
{
|
|
121
|
-
Comment("");
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
string lines = "Beast Finance — BeastFinance v1.22\n";
|
|
125
|
-
lines += _Symbol + " · " + EnumToString((ENUM_TIMEFRAMES)Period()) + " · " + TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS) + "\n";
|
|
126
|
-
lines += StringFormat("Equity: %.2f · Balance: %.2f · Acik pozisyon: %d\n",
|
|
127
|
-
AccountInfoDouble(ACCOUNT_EQUITY), AccountInfoDouble(ACCOUNT_BALANCE), PositionsTotal());
|
|
128
|
-
lines += "AutoTrading: " + (TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) ? "ACIK" : "KAPALI");
|
|
129
|
-
lines += " · EA izni: " + (MQLInfoInteger(MQL_TRADE_ALLOWED) ? "ACIK" : "KAPALI") + "\n";
|
|
130
|
-
if(StringLen(gNoteText) > 0)
|
|
131
|
-
{
|
|
132
|
-
lines += "------ BEAST NOTU ------\n";
|
|
133
|
-
lines += gNoteText;
|
|
134
|
-
}
|
|
135
|
-
Comment(lines);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/* Beast tarafından yazılan beast_note.json:
|
|
139
|
-
{"symbol":"XAUUSD","text":"...","levels":[{"price":2400,"label":"Direnc"}]}
|
|
140
|
-
symbol boş ya da bu grafiğin sembolüyse uygulanır. */
|
|
141
|
-
void ReadNote()
|
|
142
|
-
{
|
|
143
|
-
if(!FileIsExist(NoteFile)) return;
|
|
144
|
-
int h = FileOpen(NoteFile, FILE_READ|FILE_TXT|FILE_UNICODE);
|
|
145
|
-
if(h == INVALID_HANDLE) return;
|
|
146
|
-
string raw = "";
|
|
147
|
-
while(!FileIsEnding(h)) raw += FileReadString(h);
|
|
148
|
-
FileClose(h);
|
|
149
|
-
if(StringLen(raw) == 0) return;
|
|
150
|
-
|
|
151
|
-
string sym = JsonGet(raw, "symbol");
|
|
152
|
-
if(StringLen(sym) > 0 && StringCompare(sym, _Symbol) != 0) return;
|
|
153
|
-
gNoteSymbol = sym;
|
|
154
|
-
gNoteText = JsonUnescape(JsonGet(raw, "text"));
|
|
155
|
-
ApplyLevels(raw);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
string JsonGet(const string js, const string key)
|
|
159
|
-
{
|
|
160
|
-
string pat = "\"" + key + "\"";
|
|
161
|
-
int i = StringFind(js, pat);
|
|
162
|
-
if(i < 0) return "";
|
|
163
|
-
i = StringFind(js, ":", i + StringLen(pat));
|
|
164
|
-
if(i < 0) return "";
|
|
165
|
-
i++;
|
|
166
|
-
while(i < StringLen(js) && (StringGetCharacter(js, i) == ' ' || StringGetCharacter(js, i) == '\t')) i++;
|
|
167
|
-
if(i >= StringLen(js)) return "";
|
|
168
|
-
if(StringGetCharacter(js, i) == '"')
|
|
169
|
-
{
|
|
170
|
-
int j = StringFind(js, "\"", i + 1);
|
|
171
|
-
if(j < 0) return "";
|
|
172
|
-
return StringSubstr(js, i + 1, j - i - 1);
|
|
173
|
-
}
|
|
174
|
-
int e = i;
|
|
175
|
-
while(e < StringLen(js) && StringGetCharacter(js, e) != ',' && StringGetCharacter(js, e) != '}') e++;
|
|
176
|
-
string v = StringSubstr(js, i, e - i);
|
|
177
|
-
StringTrimLeft(v);
|
|
178
|
-
StringTrimRight(v);
|
|
179
|
-
return v;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
string JsonUnescape(string s)
|
|
183
|
-
{
|
|
184
|
-
StringReplace(s, "\\n", "\n");
|
|
185
|
-
StringReplace(s, "\\\"", "\"");
|
|
186
|
-
StringReplace(s, "\\\\", "\\");
|
|
187
|
-
return s;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/* levels dizisindeki her {price,label} için yatay çizgi çizer; eskileri siler */
|
|
191
|
-
void ApplyLevels(const string raw)
|
|
192
|
-
{
|
|
193
|
-
int li = StringFind(raw, "\"levels\"");
|
|
194
|
-
if(li < 0) return;
|
|
195
|
-
int arr = StringFind(raw, "[", li);
|
|
196
|
-
if(arr < 0) return;
|
|
197
|
-
int end = StringFind(raw, "]", arr);
|
|
198
|
-
if(end < 0) return;
|
|
199
|
-
string body = StringSubstr(raw, arr + 1, end - arr - 1);
|
|
200
|
-
|
|
201
|
-
string names[];
|
|
202
|
-
ArrayResize(names, 64); /* FIX: dizi boyutlandirilmadan atama EA'yi dusuruyordu */
|
|
203
|
-
int n = 0;
|
|
204
|
-
int pos = 0;
|
|
205
|
-
while(pos < StringLen(body))
|
|
206
|
-
{
|
|
207
|
-
int p = StringFind(body, "\"price\"", pos);
|
|
208
|
-
if(p < 0) break;
|
|
209
|
-
int c = StringFind(body, ":", p);
|
|
210
|
-
if(c < 0) break;
|
|
211
|
-
int pe = c + 1;
|
|
212
|
-
while(pe < StringLen(body) && StringGetCharacter(body, pe) != ',' && StringGetCharacter(body, pe) != '}') pe++;
|
|
213
|
-
string priceStr = StringSubstr(body, c + 1, pe - (c + 1));
|
|
214
|
-
StringTrimLeft(priceStr);
|
|
215
|
-
StringTrimRight(priceStr);
|
|
216
|
-
double price = StringToDouble(priceStr);
|
|
217
|
-
string label = "";
|
|
218
|
-
int lq = StringFind(body, "\"label\"", pe);
|
|
219
|
-
int nq = StringFind(body, "\"price\"", pe);
|
|
220
|
-
if(lq >= 0 && (nq < 0 || lq < nq))
|
|
221
|
-
{
|
|
222
|
-
int lc = StringFind(body, ":", lq);
|
|
223
|
-
int q1 = StringFind(body, "\"", lc + 1);
|
|
224
|
-
int q2 = q1 >= 0 ? StringFind(body, "\"", q1 + 1) : -1;
|
|
225
|
-
if(q1 >= 0 && q2 > q1) label = StringSubstr(body, q1 + 1, q2 - q1 - 1);
|
|
226
|
-
}
|
|
227
|
-
if(price > 0)
|
|
228
|
-
{
|
|
229
|
-
if(n >= ArraySize(names)) break; /* taşma koruması: sınırı aşan seviye atlanır */
|
|
230
|
-
string name = LvlPrefix + IntegerToString(n);
|
|
231
|
-
names[n] = name;
|
|
232
|
-
if(ObjectFind(0, name) < 0) ObjectCreate(0, name, OBJ_HLINE, 0, 0, price);
|
|
233
|
-
ObjectSetDouble(0, name, OBJPROP_PRICE, price);
|
|
234
|
-
ObjectSetInteger(0, name, OBJPROP_COLOR, clrDodgerBlue);
|
|
235
|
-
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT);
|
|
236
|
-
ObjectSetString(0, name, OBJPROP_TEXT, StringLen(label) > 0 ? label : "Beast");
|
|
237
|
-
n++;
|
|
238
|
-
}
|
|
239
|
-
pos = pe;
|
|
240
|
-
}
|
|
241
|
-
/* bu turda üretilmeyen eski Beast çizgilerini sil */
|
|
242
|
-
for(int i = n; i < n + 20; i++)
|
|
243
|
-
{
|
|
244
|
-
string old = LvlPrefix + IntegerToString(i);
|
|
245
|
-
if(ObjectFind(0, old) >= 0) ObjectDelete(0, old);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
void ClearLevels()
|
|
250
|
-
{
|
|
251
|
-
for(int i = 0; i < 40; i++)
|
|
252
|
-
{
|
|
253
|
-
string old = LvlPrefix + IntegerToString(i);
|
|
254
|
-
if(ObjectFind(0, old) >= 0) ObjectDelete(0, old);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/* ---------- komut köprüsü ---------- */
|
|
259
|
-
|
|
260
|
-
void WriteAck(const string id, const string cmd, const bool ok, const string err, const string result)
|
|
261
|
-
{
|
|
262
|
-
int h = FileOpen(AckFile, FILE_WRITE|FILE_TXT|FILE_UNICODE);
|
|
263
|
-
if(h == INVALID_HANDLE) return;
|
|
264
|
-
string js = "{\"ok\":" + (ok ? "true" : "false") + ",\"id\":\"" + JStr(id) + "\",\"cmd\":\"" + JStr(cmd) + "\",\"at\":" + (string)(int)TimeCurrent();
|
|
265
|
-
if(!ok) js += ",\"error\":\"" + JStr(err) + "\"";
|
|
266
|
-
if(StringLen(result) > 0) js += ",\"result\":" + result;
|
|
267
|
-
js += "}";
|
|
268
|
-
FileWriteString(h, js);
|
|
269
|
-
FileClose(h);
|
|
270
|
-
}
|
|
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
|
-
|
|
288
|
-
void ProcessCommands()
|
|
289
|
-
{
|
|
290
|
-
if(!FileIsExist(CmdFile)) return;
|
|
291
|
-
int h = FileOpen(CmdFile, FILE_READ|FILE_TXT|FILE_UNICODE);
|
|
292
|
-
if(h == INVALID_HANDLE) return;
|
|
293
|
-
string raw = "";
|
|
294
|
-
while(!FileIsEnding(h)) raw += FileReadString(h);
|
|
295
|
-
FileClose(h);
|
|
296
|
-
if(StringLen(raw) == 0) return;
|
|
297
|
-
|
|
298
|
-
string id = JsonGet(raw, "id");
|
|
299
|
-
string cmd = JsonGet(raw, "cmd");
|
|
300
|
-
bool ok = true;
|
|
301
|
-
string err = "";
|
|
302
|
-
string result = "";
|
|
303
|
-
if(cmd == "ping")
|
|
304
|
-
{
|
|
305
|
-
result = "{\"pong\":true}";
|
|
306
|
-
}
|
|
307
|
-
else if(cmd == "chart")
|
|
308
|
-
{
|
|
309
|
-
result = StringFormat("{\"symbol\":\"%s\",\"period\":%d,\"bid\":%.5f,\"ask\":%.5f,\"spread\":%d}",
|
|
310
|
-
_Symbol, (int)Period(),
|
|
311
|
-
SymbolInfoDouble(_Symbol, SYMBOL_BID), SymbolInfoDouble(_Symbol, SYMBOL_ASK),
|
|
312
|
-
(int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD));
|
|
313
|
-
}
|
|
314
|
-
else if(cmd == "status")
|
|
315
|
-
{
|
|
316
|
-
result = StringFormat("{\"equity\":%.2f,\"balance\":%.2f,\"positions\":%d,\"terminal_trade_allowed\":%s,\"mql_trade_allowed\":%s}",
|
|
317
|
-
AccountInfoDouble(ACCOUNT_EQUITY), AccountInfoDouble(ACCOUNT_BALANCE), PositionsTotal(),
|
|
318
|
-
(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) ? "true" : "false"),
|
|
319
|
-
(MQLInfoInteger(MQL_TRADE_ALLOWED) ? "true" : "false"));
|
|
320
|
-
}
|
|
321
|
-
else if(cmd == "note")
|
|
322
|
-
{
|
|
323
|
-
/* gövde zaten beast_note.json'dan okunur; sadece yenileme tetikle */
|
|
324
|
-
ReadNote();
|
|
325
|
-
RefreshPanel();
|
|
326
|
-
result = "{\"note\":true}";
|
|
327
|
-
}
|
|
328
|
-
else if(cmd == "shot")
|
|
329
|
-
{
|
|
330
|
-
/* ChartScreenShot -> MQL5\Files\<file> (png/gif/bmp). params:
|
|
331
|
-
file, width, height, timeframe (M15/H1/...), symbol (bos=aktif grafik)
|
|
332
|
-
Aktif grafik zaten istenen sembol+periyot ise ondan cekilir
|
|
333
|
-
(Beast panosu + seviye cizgileri gorunur); degilse gecici grafik acilir. */
|
|
334
|
-
string file = JsonGet(raw, "file");
|
|
335
|
-
if(StringLen(file) == 0) file = "beast_shot.png";
|
|
336
|
-
int w = (int)StringToInteger(JsonGet(raw, "width"));
|
|
337
|
-
int hh = (int)StringToInteger(JsonGet(raw, "height"));
|
|
338
|
-
if(w <= 0) w = 1600;
|
|
339
|
-
if(hh <= 0) hh = 900;
|
|
340
|
-
|
|
341
|
-
string symTxt = JsonGet(raw, "symbol");
|
|
342
|
-
string tfTxt = JsonGet(raw, "timeframe");
|
|
343
|
-
|
|
344
|
-
long cid = ChartID();
|
|
345
|
-
string symNow = ChartSymbol(cid);
|
|
346
|
-
ENUM_TIMEFRAMES tfNow = (ENUM_TIMEFRAMES)ChartPeriod(cid);
|
|
347
|
-
|
|
348
|
-
string symWant = symNow;
|
|
349
|
-
if(StringLen(symTxt) > 0 && StringCompare(symTxt, symNow) != 0)
|
|
350
|
-
{
|
|
351
|
-
if(SymbolSelect(symTxt, true)) symWant = symTxt;
|
|
352
|
-
}
|
|
353
|
-
if(SymbolSelect(symWant, true) == false)
|
|
354
|
-
{
|
|
355
|
-
ok = false;
|
|
356
|
-
err = "sembol bulunamadi: " + symWant;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
ENUM_TIMEFRAMES tfWant = TfFromText(tfTxt);
|
|
360
|
-
ENUM_TIMEFRAMES tfUse = (tfWant == PERIOD_CURRENT) ? tfNow : tfWant;
|
|
361
|
-
bool tempChart = false;
|
|
362
|
-
bool tplApplied = false;
|
|
363
|
-
bool themeOk = false;
|
|
364
|
-
int bgNow = -1;
|
|
365
|
-
|
|
366
|
-
if(ok && (symWant != symNow || tfUse != tfNow))
|
|
367
|
-
{
|
|
368
|
-
long newId = ChartOpen(symWant, tfUse);
|
|
369
|
-
if(newId == 0)
|
|
370
|
-
{
|
|
371
|
-
ok = false;
|
|
372
|
-
err = "gecici grafik acilamadi: " + symWant;
|
|
373
|
-
}
|
|
374
|
-
else
|
|
375
|
-
{
|
|
376
|
-
cid = newId;
|
|
377
|
-
tempChart = true;
|
|
378
|
-
/* temiz gorunum: BeastFinance.tpl temasi (EA blogu cikarilmis BeastShot.tpl) */
|
|
379
|
-
string tpl = JsonGet(raw, "template");
|
|
380
|
-
if(StringLen(tpl) == 0) tpl = "BeastShot";
|
|
381
|
-
if(StringFind(tpl, ".") < 0) tpl = tpl + ".tpl";
|
|
382
|
-
bool tplOk = false;
|
|
383
|
-
if(StringCompare(tpl, "none.tpl") != 0)
|
|
384
|
-
{
|
|
385
|
-
tplOk = ChartApplyTemplate(cid, tpl);
|
|
386
|
-
ChartRedraw(cid);
|
|
387
|
-
Sleep(700);
|
|
388
|
-
}
|
|
389
|
-
/* sablon sembol/periyot degistirdiyse geri al */
|
|
390
|
-
if(StringCompare(ChartSymbol(cid), symWant) != 0 || (ENUM_TIMEFRAMES)ChartPeriod(cid) != tfUse)
|
|
391
|
-
ChartSetSymbolPeriod(cid, symWant, tfUse);
|
|
392
|
-
/* sablon bulunamasa da gorunum ayni olsun -> acik tema renklerini zorla */
|
|
393
|
-
themeOk = ApplyLightTheme(cid);
|
|
394
|
-
bgNow = (int)ChartGetInteger(cid, CHART_COLOR_BACKGROUND);
|
|
395
|
-
tplApplied = tplOk;
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
|
|
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.
|
|
402
|
-
Aktif grafikte önceki ayar çekimden SONRA geri yazılır — kullanıcının
|
|
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);
|
|
406
|
-
|
|
407
|
-
if(ok)
|
|
408
|
-
{
|
|
409
|
-
ChartSetInteger(cid, CHART_SHIFT, true);
|
|
410
|
-
ChartSetDouble(cid, CHART_SHIFT_SIZE, 12.0);
|
|
411
|
-
ChartRedraw(cid);
|
|
412
|
-
Sleep(1200); /* mumlar/olcek otursun */
|
|
413
|
-
ChartRedraw(cid);
|
|
414
|
-
Sleep(200);
|
|
415
|
-
if(!ChartScreenShot(cid, file, w, hh, ALIGN_RIGHT))
|
|
416
|
-
{
|
|
417
|
-
ok = false;
|
|
418
|
-
err = "screenshot basarisiz, hata=" + IntegerToString(GetLastError());
|
|
419
|
-
}
|
|
420
|
-
else
|
|
421
|
-
{
|
|
422
|
-
result = StringFormat("{\"file\":\"%s\",\"width\":%d,\"height\":%d,\"symbol\":\"%s\",\"period\":%d,\"temp_chart\":%s,\"template_applied\":%s,\"theme_ok\":%s,\"bg\":%d}",
|
|
423
|
-
JStr(file), w, hh, symWant, (int)tfUse, (tempChart ? "true" : "false"), (tplApplied ? "true" : "false"), (themeOk ? "true" : "false"), bgNow);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
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 */
|
|
443
|
-
}
|
|
444
|
-
else
|
|
445
|
-
{
|
|
446
|
-
ok = false;
|
|
447
|
-
err = "bilinmeyen komut: " + cmd;
|
|
448
|
-
}
|
|
449
|
-
WriteAck(id, cmd, ok, err, result);
|
|
450
|
-
DeleteCmdIfId(id);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
/* BeastFinance.tpl acik tema renklerini grafige uygular (sablon bulunamazsa da garanti) */
|
|
454
|
-
bool ApplyLightTheme(const long cid)
|
|
455
|
-
{
|
|
456
|
-
bool okAll = true;
|
|
457
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_BACKGROUND, (long)16449525) && okAll;
|
|
458
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_FOREGROUND, (long)0) && okAll;
|
|
459
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_GRID, (long)12632256) && okAll;
|
|
460
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_CHART_UP, (long)13434880) && okAll;
|
|
461
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_CHART_DOWN, (long)0) && okAll;
|
|
462
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_CHART_LINE, (long)0) && okAll;
|
|
463
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_CANDLE_BULL, (long)13434880) && okAll;
|
|
464
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_CANDLE_BEAR, (long)0) && okAll;
|
|
465
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_VOLUME, (long)32768) && okAll;
|
|
466
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_BID, (long)12632256) && okAll;
|
|
467
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_ASK, (long)12632256) && okAll;
|
|
468
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_LAST, (long)12632256) && okAll;
|
|
469
|
-
okAll = ChartSetInteger(cid, CHART_COLOR_STOP_LEVEL, (long)17919) && okAll;
|
|
470
|
-
okAll = ChartSetInteger(cid, CHART_MODE, CHART_CANDLES) && okAll;
|
|
471
|
-
okAll = ChartSetInteger(cid, CHART_SHOW_GRID, false) && okAll;
|
|
472
|
-
okAll = ChartSetInteger(cid, CHART_SHOW_OHLC, true) && okAll;
|
|
473
|
-
okAll = ChartSetInteger(cid, CHART_SHOW_BID_LINE, false) && okAll;
|
|
474
|
-
okAll = ChartSetInteger(cid, CHART_SHOW_ASK_LINE, false) && okAll;
|
|
475
|
-
okAll = ChartSetInteger(cid, CHART_SHOW_LAST_LINE, true) && okAll;
|
|
476
|
-
ChartRedraw(cid);
|
|
477
|
-
return okAll;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
/* "M15"/"H1"/"15"/"60" gibi metni ENUM_TIMEFRAMES'e cevirir */
|
|
481
|
-
ENUM_TIMEFRAMES TfFromText(const string t)
|
|
482
|
-
{
|
|
483
|
-
string s = t;
|
|
484
|
-
StringTrimLeft(s);
|
|
485
|
-
StringTrimRight(s);
|
|
486
|
-
StringToUpper(s);
|
|
487
|
-
if(s == "M1" || s == "1") return PERIOD_M1;
|
|
488
|
-
if(s == "M5" || s == "5") return PERIOD_M5;
|
|
489
|
-
if(s == "M15" || s == "15") return PERIOD_M15;
|
|
490
|
-
if(s == "M30" || s == "30") return PERIOD_M30;
|
|
491
|
-
if(s == "H1" || s == "60") return PERIOD_H1;
|
|
492
|
-
if(s == "H4" || s == "240") return PERIOD_H4;
|
|
493
|
-
if(s == "D1" || s == "1440") return PERIOD_D1;
|
|
494
|
-
if(s == "W1") return PERIOD_W1;
|
|
495
|
-
if(s == "MN1") return PERIOD_MN1;
|
|
496
|
-
return PERIOD_CURRENT;
|
|
497
|
-
}
|
|
498
|
-
//+------------------------------------------------------------------+
|
|
Binary file
|