Numer magiczny — do czego naprawdę służy
Numer magiczny jest wspólny dla rachunku, nie dla terminala. Kiedy trzeba go zmieniać, kiedy nie, i dlaczego sam nie wystarcza do rozpoznania własnej pozycji.
Kod z tej strony skompilowany i uruchomiony: MetaEditor build 6090, sprawdzone 2026-08-02.
Numer magiczny to liczba, którą ekspert dokleja do każdego zlecenia, żeby później rozpoznać własne pozycje wśród cudzych. Brzmi trywialnie i jest źródłem zaskakująco wielu problemów.
Zasięg: rachunek, nie terminal
To jest pytanie, które wraca na forach regularnie: mam dwa terminale różnych brokerów, ten sam ekspert w obu — czy muszę zmieniać numer magiczny?
Nie. Numer magiczny jest zapisywany w zleceniu na serwerze i istnieje wyłącznie w kontekście rachunku. Dwa terminale połączone z dwoma różnymi rachunkami widzą dwa różne zbiory pozycji i nigdy się nie mieszają.
Zmieniać trzeba wtedy, gdy na jednym rachunku działa więcej niż jeden ekspert — także wtedy, gdy to ten sam ekspert na dwóch wykresach.
| Sytuacja | Czy zmieniać numer |
|---|---|
| dwa terminale, dwa rachunki | nie |
| jeden rachunek, dwa różne eksperty | tak |
| jeden rachunek, ten sam ekspert na EURUSD i GBPUSD | zależy |
| jeden rachunek, ta sama strategia w dwóch wariantach | tak |
Trzeci wiersz zależy od tego, czy chcesz liczyć limity osobno dla każdego instrumentu, czy wspólnie. Jeśli osobno — wystarczy filtr po symbolu przy tym samym numerze. Jeśli wspólnie, ale z osobnymi limitami ryzyka — potrzebne są różne numery.
Sam numer nie wystarcza
Filtrowanie wyłącznie po numerze magicznym to najczęstszy błąd w pętlach po pozycjach. Ekspert pracujący na EURUSD zobaczy wtedy również swoje pozycje na GBPUSD i policzy je do limitu, którego nie chciał dzielić.
int MojePozycje(const string symbol, const ulong magic)
{
int ile = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong bilet = PositionGetTicket(i);
if(bilet == 0 || !PositionSelectByTicket(bilet))
continue;
if(PositionGetInteger(POSITION_MAGIC) != (long)magic)
continue;
if(PositionGetString(POSITION_SYMBOL) != symbol)
continue;
ile++;
}
return ile;
}Numer musi przeżyć restart
Nie generuj numeru losowo ani z czasu. Po ponownym uruchomieniu terminala ekspert wygeneruje inny i przestanie rozpoznawać własne, wciąż otwarte pozycje.
input ulong Magic = 0;
int OnInit()
{
ulong magic = (ulong)TimeCurrent(); // po restarcie będzie inny
return INIT_SUCCEEDED;
}Numer ma być parametrem wejściowym o stałej wartości domyślnej. Wtedy użytkownik może go zmienić świadomie, a ekspert po restarcie odnajduje swoje pozycje.
Konwencja, która pomaga po roku
Numery przydzielane przypadkowo są nie do rozszyfrowania, gdy na rachunku pracuje sześć strategii. Warto zakodować w nich znaczenie — na przykład strategię, instrument i wariant:
//--- SSIIV: SS = strategia, II = instrument, V = wariant
//--- 120301 = strategia 12, instrument 03, wariant 01
input ulong Magic = 120301;To nie jest wymóg techniczny, tylko zabezpieczenie przed sobą samym za pół roku, gdy w historii transakcji zobaczysz numer i będziesz próbował sobie przypomnieć, co go otwierało.
Historia też ma numer
W transakcjach z historii numer magiczny odczytuje się osobną funkcją. Pominięcie tego filtru zawyża wynik strategii o cudze transakcje:
if(HistoryDealGetInteger(bilet, DEAL_MAGIC) != (long)Magic)
continue;