Twoje nieudokumentowane funkcje doradców pisanie na MQL4

Anonim

Czasopismo publikuje wiele opinii Radni programy oraz ich wpływ: niektóre są bardziej skuteczne, podczas gdy inne są rozpatrywane niezwłocznie jako przynoszących straty, co jest również bardzo przez sam wynik. Ale wydajność doradcą, kiedy dokładnie rozważyć, jest złożonym wynik:

1) używany strategii handlowej (algorytm generacji open-close sygnały);

2) stosowanych technik zarządzania kapitałem (algorytm kontroli wielkości partii);

3) dokładność programu zapisanego na korespondencji MQL opisy pierwszych dwóch punktów (błędy logiczne) i pod nieobecność niechcianych efektów ubocznych.

Według pierwszych dwóch pozycjach jest napisane dużo, a teraz chciałbym się skupić na niektóre drobniejsze kwestia używania języka MQL , który nie znaleźć żadnej wzmianki na wyświetlaczu oraz opis języka (na przykład, opisane tutaj: _ // docs MQL4 com / RU / dokumenty) …

Jest to ważne z dwóch powodów:

? Po pierwsze, wiedza o zachowaniu konstrukcji języka nie znajduje odzwierciedlenia w dokumentacji uniemożliwia źle rozumianej skutki uboczne w programie;

?Po drugie, pozwala zapisać bardziej efektywny kod , mniej podatny na ukryte błędy. Aby korzystać z tych funkcji w swoich doradców nie potrzeba żadnych specjalnych kwalifikacji, muszą tylko połączenia i wiem, co można użyć. A jeśli w poniższym tekście pewne sformułowanie wydaje się trochę złożoności; … bezboleśnie przegap ich, są wykonane tylko przez wzgląd na kompletność.

Parametry przejściu do funkcji przez referencję (adres)

Ta sprawa jest dobrze znana programistów na dowolny uniwersalnego języka programowania, na przykład, w C, a nawet więcej w C ++. Napiszmy najprostszy Advisor (plik t2 mq4 - nazwy testów zwany przypadek w załączonym pliku.) I umieścić ją na wykresie dowolnej pary walut:

int start () {

statyczny int nTick = 0;

Inc (nTick);

Alert ("new tick No." + nTick);

}

// -------------

nieważne Inc (int n) {n ++;}

THE będzie ciągłe powtarzanie tego samego rezultatu, „nowy tik №0» … przeniesione do wartości zmian fabularnych n tam, ale to nie przynosi żadnego wpływu na działanie środowiska zewnętrznego (zwana funkcja start ()) - w funkcji przekazany do

Kopiuj zmienna nTick, więc zazwyczaj prace wywołanie funkcji w MQL4. Dodać jeden znak (&) do opisu funkcji Inc ():

nieważne Inc (Int & n) {n ++;}

Wykonywanie radykalnego zmiany doradcą

Nowy kleszczy № 1

Nowy kleszczy № 2

Nowy kleszczy № 3 …

Ikona i

wskazuje, że funkcja nie musi przekazać kopię i

oryginalny zmienna nTick, a wszystkie zmiany dokonane przez na tej zmiennej wewnątrz funkcji wpłynie na wartość Ta zmienna jest poza funkcją . To zachowanie nazywa się skutkiem ubocznym funkcji .

999 Wnioski: Jakie są konsekwencje tej małej ciekawości? Bardzo dalekosiężne. Funkcja w MQL są ograniczone, mogą wrócić tylko jedną wartość najprostszego typu: int, string, datetime, … Ze względu na efekt uboczny, funkcją wielu parametrów można wprowadzić zmiany do wszystkich z nich, rzeczywiście powróci (po jego wykonaniu) więcej niż jeden wynik (lub można je uznać za zwrot danych strukturalnych). Na przykład ta funkcja:

dwukrotnie funkc (Int & n, łańcuch i y, data i godzina & t) {…} Transfer w funkcji parametrów macierzy przez odniesienie

Poniższy przykład (. Plik T3 mq4) jest zbliżony do poprzedniego, lecz tutaj skutki uboczne i związane z nimi możliwości są znacznie większe:

zewnętrzny int N = 7;

int A [];

// ----------------------

int init () {

ArrayResize (A, N);

Alert ("rozmiar tablicy" + ArraySize (A));

dla (int i = 0, i

}

// ----------------------

int start () {

statyczne nBars = 0; // aby nie rozstawać, teraz w barach zamiast kleszcze

{// jeśli więc nie czekaj, zacznij od M1

nBars = Bars (NBars = bary!);

IncArray (A);

ShowArray (A);

}

}

// ----------------------

nieważne IncArray (int-Array []) {

int n = ArraySize (Array);

do (int i = 0; i

}

nieważne ShowArray (Int Array []) {

n = ArraySize int (macierz);

ciąg Msg = «»;

for (int i = 0; i

Msg = Msg + Array [i];

if (i

}

Alert (Msg);

}

Drag doradcą zaplanować (najlepsze ramy czasowe M1) i będziesz miał przyjemność oglądania zawarcia tych komunikatów:

2, 3, 4, 5, 6, 7, 8

3 4, 5, 6, 7, 8, 9

4, 5, 6, 7, 8, 9, 10

Wniosek:

jest poddawana zmiany przesyłanych oddzielnie każdy element tablicy.

Uwaga:

To ciekawe, jak zmienić zachowanie programu, jeśli tablica jest w IncArray () funkcja nie będą przekazywane przez referencję?Czy zostanie utworzona kopia tablicy do pracy z nią wewnątrz funkcji (podobnie jak w poprzednim przykładzie dla jednej wartości)? Osiągamy to, przepisując tytuł tej funkcji tak: (<).

void IncArray (int Array []) {

Wynik jest nieoczekiwane, nawet dla doświadczonych programistów w języku C lub C ++! W czasie kompilacji, nie osiągając wydajność, otrzymamy komunikat o typie błędu:

„Array” - element tablicy nie może być przypisany C: Program Files MetaTrader - Alpari eksperci t3. mq4 (22, 33)

Oznacza to, że regulacja w wartości L (dostępność na zlecenie) dla elementów macierzy jest realizowane przez kompilator więcej! I dla pojedynczych (skalarnych) parametrów nie jest tak.

Zmień wymiar tablicy, przekazywane przez referencję

następna sztuczka mogła zanurzyć zdumiony nawet doświadczonego programistę na klasycznych języków programowania. Sama możliwość w każdej chwili zmienić rozmiar tablicy - to samo w sobie jest istotną cechą MQL4

Int A [5];

dla (i = 0, i ShowArray (A);

ArrayResize (A, 7);

dla (i = 0, i

ShowArray (A);

Potem znajdujemy dziwnie: 333, 333, 333, 333, 333, 0, 0

Okazuje się, że tablice nie są w pełni pererazmeschaet i "dodatki" na żądany wymiar - wszystkie wcześniej przypisane wartości pozycji są zapisywane! Ale bez takiej sztuczki prawdopodobnie nie będzie możliwe, aby deweloperzy MQL4 wdrożyli reprezentację serii czasowej w MT4.

Teraz obiecana sztuczka polega na zmianie wymiaru tablicy wewnątrz funkcji.

Aby to zrobić, po prostu przepisaj jedną z funkcji z poprzedniego przykładu:

nieważne IncArray (int-Array []) {

n = ArraySize int (macierz);

ArrayResize (A, n + 1);

dla (int i = 0; i <= n; i ++) Array [i] = i + 1;

}

Wyniki Execution (skopiowane z terminala dziennika MetaTrader 4 (// fortrader.org / terminale forex / torgovyj-terminal-metatrader-4-skachat. html), który rozszerza wyniki oddolne):

2011. 02. 10 19: 54: 00: @ T3 EURUSD M1 alert: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14

2011. 02. 10 19: 53: 02: @ T3 EURUSD M1 alert: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13

2011. 02. 10 19: 52: 08: @ t3 EURUSD M1: zaalarmowany: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12

Uwaga: po raz kolejny z powrotem do kwestii omówionych powyżej: w jaki sposób (kopia lub oryginał) jest przekazywana do tablicy MQL4? W tym celu napisz ponownie:

nieważne IncArray (Int Array []) {

n = ArraySize int (macierz);

ArrayResize (A, n + 1); }

Otrzymamy raczej nieoczekiwany wynik:

2011. 03 20 17 lipca 02 t4 EURUSD M1: Uwaga: 1, 2, 3, 4, 5, 6, 7, 0, 0, 0

2011. 03. 20 lipca: 16: 01 t4 EURUSD M1: Uwaga: 1, 2, 3, 4, 5, 6, 7, 0, 0

2011. 03. 20 lipca: 15: 44 t4 EURUSD M1: Uwaga: 1, 2, 3, 4, 5, 6, 7, 0

W rezultacie, można stwierdzić, że tablica przekazywany do funkcji jest zawsze link, ale jeśli nie określają wyraźnie (i)

kompilator

będzie monitorować i zapobiegać próbom zmienić elementy tablicy.