moje EA - dlaczego nie działa?

O jezykach programowania w platformach i nie tylko.
farnick
Bywalec
Bywalec
Posty: 18
Rejestracja: 02 lis 2011, 09:51

moje EA - dlaczego nie działa?

Nieprzeczytany post autor: farnick »

Witam,

Zrobiłem swoje pierwsze EA ale nie działa, nie mam pojęcia dlaczego, siedzę już nad tym któryś dzień i nie mam pojęcia co może być nie tak, Kod wydaje mi się prosty i zrozumiały jednak coś jest nie tak. Zrobiłem nawet wskaźnik do tego EA, który rysuje zmienną SYG 1,0 albo -1 - na wykresie jest sporo sygnałów jednak jak uruchamiam backtest to system nic nie robi.

EA podzieliłem w ten sposób, że na system na wyjściu daje sygnał SYG=1 dla pozycji długiej, -1 dla krótkiej albo 0 dla pozostania poza rynkiem. Ten sygnał trafia do następnego modułu, który obsługuje komendy kupna na podstawie tych sygnałów. Proszę o pomoc i wskazanie dlaczego ten kod nie działa i co jest w nim nie tak.

Oto on:
///////////////////////////////////////////////////////////


double WstegaGorna[10000];
double WstegaDolna[10000];
double SYG[1000];
double EMA[1000];
double ATRClose[10000];
double L[1000];
double H[1000];
double O[1000];

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+

int start()
{
int i, counted_bars=IndicatorCounted();


if(counted_bars>=100) i=Bars-counted_bars-1;
while(i>=0)
{

EMA=iMA( NULL ,0,10,1,MODE_EMA,PRICE_OPEN,i );
ATRClose=iATR(NULL,0,10,0)/Close;
WstegaGorna=iMA( NULL ,0,10,1,MODE_EMA,PRICE_CLOSE,i )*(1+ATRClose*0.97);
WstegaDolna=iMA( NULL ,0,10,1,MODE_EMA,PRICE_CLOSE,i )*(1-ATRClose*0.97);


H=iHigh(NULL,0,i);
L=iLow(NULL,0,i);
O=iOpen(NULL,0,i);

//-----------------------------------------------
//ustalenie sygnalów
//-----------------------------------------------

if ( H[i]>WstegaGorna[i+1] )
{
SYG[i]=1;
}
else
{
if ( L[i]<WstegaDolna[i+1] )
{
SYG[i]=-1;
}
else
{
if ( SYG[i+1]==1 && O[i]<EMA[i+1])
{
SYG[i]=0;
}
else
{
if ( SYG[i+1]==-1 && O[i]>EMA[i+1])
{
SYG[i]=0;
}
else
{
SYG[i]=SYG[i+1];
}
}
}
}


i--;
}


//Sygnal kupna przez odwrocenie pozycji


if ((SYG[0]==1 && SYG[1]==-1)|| (SYG[0]==1 && SYG[1]==1 && SYG[2]==-1))
{OrderSelect(0,SELECT_BY_POS,MODE_TRADES);

if(OrderType() == OP_SELL && OrderLots()>0)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket(), OrderLots(), Ask, 3);
}

if(OrderType()!=OP_BUY && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_BUY, 0.3, Ask, 5, Ask*0.995, Ask*2, "", 8, 0, Blue);
return;
}
}

// Sygnal kupna po cover

if ((SYG[0]==1 && SYG[1]==0)|| (SYG[0]==1 && SYG[1]==1 && SYG[2]==0) )
{
if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_BUY, 0.3, Ask, 5, Ask*0.995, Ask*2, "", 8, 0, Blue);
return;
}
}

//Sygnal sprzedazy przez odwrocenie pozycji

if ((SYG[0]==-1 && SYG[1]==1)|| (SYG[0]==-1 && SYG[1]==-1 && SYG[2]==1))
{OrderSelect(0,SELECT_BY_POS,MODE_TRADES);

if(OrderType() == OP_BUY && OrderLots()>0)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket(), OrderLots(), Bid, 3);
}

if(OrderType()!=OP_SELL && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_SELL, 0.3, Bid, 5, Bid*1.005, Bid*0.5, "", 8, 0, Red);
return;
}
}

// Sygnal sprzedazy po cover

if ((SYG[0]==-1 && SYG[1]==0)||(SYG[0]==-1 && SYG[1]==-1 && SYG[2]==0) )
{
if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_SELL, 0.3, Bid, 5, Bid*1.005, Bid*0.5, "", 8, 0, Red);
return;
}
}

// Cover

if ((SYG[0]==0 && (SYG[1]==1 || SYG[1]==-1)) || (SYG[0]==0 && SYG[1]==0 && (SYG[2]==1 || SYG[2]==-1)) )
{
if(OrderType() == OP_BUY && OrderLots()>0 && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Bid, 3);
}
if(OrderType() == OP_SELL && OrderLots()>0 && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Ask, 3);
}
}

// Niezgodna pozycja

if (SYG[0]==1 && SYG[1]==1 && OrderType() == OP_SELL)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Ask, 3);
}

if (SYG[0]==-1 && SYG[1]==-1 && OrderType() == OP_BUY)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Bid, 3);
}
return(0);
}
//+------------------------------------------------------------------+

Kris82
Stały bywalec
Stały bywalec
Posty: 34
Rejestracja: 11 lip 2012, 00:27

Re: moje EA - dlaczego nie działa?

Nieprzeczytany post autor: Kris82 »

Nie działa ponieważ TP jest za wysokie.

Kod: Zaznacz cały

OrderSend(Symbol(), OP_BUY, 0.3, Ask, 5, Ask*0.995, Ask*2, "", 8, 0, Blue);
Czyli SL jest dobrze Ask*0.995, chociaż ja bym to zapisał tak Ask*0.995
TP jest stanowczo za wysokie Ask*2, przykładowa cena Ask 1.333*2= 2.666 ten poziom raczej nie będzie osiągnięty.

To samo się tyczy zleceń SELL

Kod: Zaznacz cały

OrderSend(Symbol(), OP_SELL, 0.3, Bid, 5, Bid*1.005, Bid*0.5, "", 8, 0, Red);
Tutaj warunkiem zamknięcia zlecenia przez TP jest wartość połowy Bid.
W przypadku Bid 1.3000 zlecenie zostanie zamknięte gdy cena osiągnie wartość 0.6500

Co do reszty to nie wczytywałem się, ale jak zostanie zmieniony warunek zamknięcia pozycji na:
Kupno

Kod: Zaznacz cały

OrderSend(Symbol(), OP_BUY, 0.3, Ask, 5, Ask*0.995, Ask*1.005, "", 8, 0, Blue);
Sprzedaż

Kod: Zaznacz cały

OrderSend(Symbol(), OP_SELL, 0.3, Bid, 5, Bid*1.005, Bid*0.995, "", 8, 0, Red);
powinno działać jak nalerzy

-- Dodano: śr 03-04-2013, 8:17 --

Przetestowałem na EUR/USD interwał 30 minut przez okres 10 lat przy ustawieniach TP jw.
Wyniki nie powalają na kolana, ale i tak jest na plus. Teraz pozostaje kwesta dobrania odpowiednich wartości TP i SL.
Proponuje sprawdzić w przypadku opcji kupna jak wysoko cena poszła w górę, obliczając maksymalny zasięg ceny od zlecenia BUY w określonym przedziale czasowym. Można by tu było zastosować sieci neuronowe.
Jak na pierwsze EA, to naprawdę kawał dobrej roboty, nie to co te moje gnioty nieudolnie napisane :D

farnick
Bywalec
Bywalec
Posty: 18
Rejestracja: 02 lis 2011, 09:51

Re: moje EA - dlaczego nie działa?

Nieprzeczytany post autor: farnick »

Dzięki bardzo. Doszedłem do tego, że głównym powodem był brak i=Bars-1;

powinno być:

int start()
{
int i, counted_bars=IndicatorCounted();
i=Bars-1;

-- Dodano: śr 03-04-2013, 13:04 --

ten target profit to tak podałem z kosmosu, pozycje są zamykane głównie po spełnieniu się warunku

-- Dodano: śr 03-04-2013, 13:11 --

Co mnie natomiast martwi to to że wskaźnik sygnału (zmienna SYG) który zrobiłem do tego EA zachowuje się bardzo dziwnie w czasie backtestu - żeby to zaobserować trzeba odpalić back test w trybie wizualizacji i na rysowany w backteście wykres dodać poniższy wskaźnik, który rysuje zmienną SYG (tzn albo wartość 1 dla buy -1 dla sell i 0 dla wyjścia ):

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 LightSeaGreen



double WstegaGorna[10000];
double WstegaDolna[10000];
double SYG[1000];
double EMA[1000];
double ATRClose[10000];
double L[1000];
double H[1000];
double O[1000];


//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
IndicatorShortName("SYG");
//---- indicators
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0, SYG);



//----
return(0);
}


//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+

int start()
{
int i, counted_bars=IndicatorCounted();

i=Bars-1;

if(counted_bars>=0) i=Bars-counted_bars-1;
while(i>=0)
{

EMA=iMA( NULL ,0,10,1,MODE_EMA,PRICE_OPEN,i );
ATRClose=iATR(NULL,0,10,0)/Close;
WstegaGorna=iMA( NULL ,0,10,1,MODE_EMA,PRICE_CLOSE,i )*(1+ATRClose*0.97);
WstegaDolna=iMA( NULL ,0,10,1,MODE_EMA,PRICE_CLOSE,i )*(1-ATRClose*0.97);




H=iHigh(NULL,0,i);
L=iLow(NULL,0,i);
O=iOpen(NULL,0,i);




//-----------------------------------------------
//ustalenie sygnalów
//-----------------------------------------------


if ( H[i]>WstegaGorna[i+1] )
{
SYG[i]=1;
}
else
{
if ( L[i]<WstegaDolna[i+1] )
{
SYG[i]=-1;
}
else
{
if ( SYG[i+1]==1 && O[i]<EMA[i+1])
{
SYG[i]=0;
}
else
{
if ( SYG[i+1]==-1 && O[i]>EMA[i+1])
{
SYG[i]=0;
}
else
{
SYG[i]=SYG[i+1];
}
}
}
}

i--;
}
}
//+------------------------------------------------------------------+

-- Dodano: śr 03-04-2013, 13:17 --

/////////////////////////////////////////////////////////////

problem polega na tym, że dla niektórych sygnałów, które pojawiły się w backteście - wskaźnik nie rysuje sygnału tzn nie zmienia się z -1 na 1 albo odwrotnie, Kod jest przecież taki sam. Jak to możlwie, że w backteście system daje sygnał kupna, który jest wykonywany ale wskaźnik, który również powinien narysować wskaźnik kupna nie reaguje.

Albo jeszcze dziwniejsze zachowanie - tak jakby wskaźnik z ostatniej świeczki był kopiowany na kolejne a z tej wcześniejszej (i+1) ustawiany na 0, mimo, ze przed chwilś wskaźnik dla tej świeczki był np. -1.

Proszę wyjaśnijcie mi o co tu chodzi i jak to możliwe. Kod jest przecież jednoznaczny i nie ma takiej opcji, żeby dla rysowanej w danym czasie świeczki był sygnał -1 a po kolejnym ticku 0, potem za chwilę znów -1, a tak to wygląda.

dulf
Pasjonat
Pasjonat
Posty: 399
Rejestracja: 24 kwie 2010, 15:13

Re: moje EA - dlaczego nie działa?

Nieprzeczytany post autor: dulf »

Kod: Zaznacz cały

double WstegaGorna[10000];
double WstegaDolna[10000];
double SYG[1000];
double EMA[1000];
double ATRClose[10000];
double L[1000];
double H[1000];
double O[1000];


//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+

int start()
{
int i, counted_bars=IndicatorCounted();

i=Bars-1;

if(counted_bars>=0) i=Bars-counted_bars-1;
while(i>=0)
{
To jest błędne rozwiązanie , tablice masz o pewnym rozmiarze który przy pierwszym załadowaniu wskaźnika może zostać przekroczony przez wartość Bars gdy świece nie są jeszcze przeliczone .Nastąpi początkowo naruszenie pamięci w wskaźniku.

Kolejnym błędem jest pozyskiwanie sygnałów w ten sposób i oczekiwanie że zostaną one poprawnie odwzorowane na wykres .Bufor SYG ,a konkretnie jego indeksy nie przesuwają się razem z wykresem.
Tylko na początku gdy Bars-counted ma wartość maksymalną wszystko jest przeliczane i odświeżane , przy kolejnych tickach , " ogon" bufora SYG , czyli kolejne wartości przypisane do indeksów większych od Bars-counted_bars pozostają bez zmian ,a nadpisywane są tylko te które indyk odświeża ,czyli w czasie działania praktycznie olewa to co było ,a pracuje na indeksach początku tablicy nadpisując je w kolejności od 0 do Bars-counted_bars .
Konstrukcja ifów jest dla mnie nie czytelna więc się nie wypowiadam co do poprawności generowania syg .
W jaki sposób EA pozyskuje sygnał z bufora SYG ?.Ten kod jest w jednym pliku , indykatoro -EA ?
Nie rozumiem który kod należy do modułu indykatora , a który do EA .
Niektóre funkcje wykorzystywane w indykach nie działają w modułach EA ! .
W tym funkcja IndicatorCounted() zwraca -1 .
Nie spiesz się , zawsze zdążysz stracić .

farnick
Bywalec
Bywalec
Posty: 18
Rejestracja: 02 lis 2011, 09:51

Re: moje EA - dlaczego nie działa?

Nieprzeczytany post autor: farnick »

Dzięki bardzo za odpowiedź.

Zdecydowałem sie na taki sposób podawania sygnałów ze względu na to, że chcę mieć możliwość do sięgania wartości z poprzednich świeczek albo wcześniejszych wartości innych zmiennych a nie znalazłem żadnej funkcji, która by to umożliwiała. W Amibrokerze jest to funkcja Ref (Zmienna, -5) czyli pobiera wartośc Zmiennej 5 świeczek do tyłu. Czy w MQL jest podobna funkcja.

Jeśli chodzi o kody to są to dwa odrębne kody - 1 który podałem w pierwszym poście to EA a drugi kod (osobny plik), który jedynie rysuje linię sygnału SYG -1,0, albo 1.

Jak inaczej ewentualnie napisać taki kod żeby nie używać tablic ale móc sięgać do wcześniejszych wartości poszczególnych zmiennych. Ja zastosowałem takie dziwne rozwiązanie bo wg założeń i zmienne miały być kopiowane z poprzednich wartości, chyba, że dla danej świeczki zachodził warunek if - wówczas mogła nastąpić zmiana wartości

-- Dodano: pt 05-04-2013, 14:31 --

Albo ewentualnie jak inaczej napisać ale tak, żeby program działał poprawnie.

dulf
Pasjonat
Pasjonat
Posty: 399
Rejestracja: 24 kwie 2010, 15:13

Re: moje EA - dlaczego nie działa?

Nieprzeczytany post autor: dulf »

Używaj tablic , w EA nie są ci potrzebne dane z tak odległego okresu , wystarczy tablica z rozmiarem pokrywającym bary z których są brane dane jako sygnał otwarcia .W tym przypadku interesuje cię indeks 0 i poprzedni ( jeśli pracujesz na bieżącej świecy,jeśli nie, trzeba przesunąć iterację pętli od 1 nie od 0),indeksujesz też tablicę i+1 więc rozmiar tablicy trzeba zwiększyć w stosunku do 'i' licznika z racji konstrukcji pętli dla i ==2 przeglądasz elementy tablicy SYG 0,1,2 oraz i+1 czyli 3 co daje w sumie 4 wartości które musisz zapisać do tablicy , rozmiar tablicy 4 .Tyle wystarczy
Jeśli chcesz przeglądać więcej elementów zwiększ i , ale pamiętaj żeby rozmiar tablicy był większy od i .
Nie używaj w EA funkcji IndicatorCounted(); bo ona nie działa .Ustal sobie które indeksy są ci potrzebne do otwierania pozycji i na tej podstawie dobierz ile elementów ma być przeliczane.

Kod: Zaznacz cały

int start()
{
//int i, counted_bars=IndicatorCounted();  // To jest bez sensu

///i=Bars-1;

///////// if(counted_bars>=0) i=Bars-counted_bars-1;

 int i = 10 ;    //   tu podajesz ile elementów cię interesuje , tablice dajesz większe o 2
while(i>=0)
{.....
-- Dodano: sob 06-04-2013, 6:56 --

Jeszcze jedna uwaga .Najpierw przeliczasz dane , potem sprawdzasz czy jest odpowiedni warunek , przy poprzedniej konstrukcji na jednej pętli masz dane nie aktualne przy sprawdzaniu warunków.Potrzebne są więc 2 pętle.

Kod: Zaznacz cały

double WstegaGorna[10];
double WstegaDolna[10];
double SYG[10];
double EMA[10];
double ATRClose[10];
double L[10];
double H[10];
double O[10];

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+

int start()
{

// przeliczanie parametrów 
int i = 3 ;
while(i>=0)
{

EMA[i]=iMA( NULL ,0,10,1,MODE_EMA,PRICE_OPEN,i );
ATRClose[i]=iATR(NULL,0,10,0)/Close[i];
WstegaGorna[i]=iMA( NULL ,0,10,1,MODE_EMA,PRICE_CLOSE,i )*(1+ATRClose[i]*0.97);
WstegaDolna[i]=iMA( NULL ,0,10,1,MODE_EMA,PRICE_CLOSE,i )*(1-ATRClose[i]*0.97);


H[i]=iHigh(NULL,0,i);
L[i]=iLow(NULL,0,i);
O[i]=iOpen(NULL,0,i); 

  i-- ;

}
//-----------------------------------------------
//ustalenie sygnalów 
//-----------------------------------------------

   i = 3 ;
 
while(i>=0)
{
      if(cośtam)
     {
        SYG[i] = .....

      }

  i-- ;

}
-- Dodano: sob 06-04-2013, 7:22 --

Czyli ma to wyglądać tak:
1.Zebranie wartości wskaźników do tablic (jedna pętla)
2.Analiza zebranych wartości i zapełnienie na ich podstawie tablicy SYG (kolejna pętla)
3.W dalszej części kodu otwieranie pozycji na podstawie zawatrości tablicy SYG.
Nie spiesz się , zawsze zdążysz stracić .

farnick
Bywalec
Bywalec
Posty: 18
Rejestracja: 02 lis 2011, 09:51

Re: moje EA - dlaczego nie działa?

Nieprzeczytany post autor: farnick »

Dzięki bardzo, właśnie próbuję to ogarnąć ;)

-- Dodano: sob 06-04-2013, 22:31 --

Poprawiłem EA wg Twoich wskazówek. ogólnie działa, ale czasem zamyka przedwcześnie pozycję. Nie mam pojęcia dlaczego. Żeby zaobserwować czy prawidłowo otwiera pozycję zrobiłem indykator który rysuje wstęgi i wtedy to widać.
Poniżej wklejam kod EA. Trochę uprościłem kod żeby był bardziej czytelny.
W dodatku w dzienniku wyskakują jakieś błędy OrderClose Error 4051 i inne. Wskażcie prosze co jest jeszcze nie tak w kodzie.

//---------------------------------------------------------------------------------------------
double WstegaGorna[12];
double WstegaDolna[12];
double SYG[12];
double ATRClose[12];
double L[12];
double H[12];
double O[120];

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+

int start()
{

// przeliczanie parametrów
int i = 3 ;
while(i>=0)
{
ATRClose=iATR(NULL,0,10,0)/Close;
WstegaGorna=iMA( NULL ,0,10,1,MODE_EMA,PRICE_CLOSE,i )*(1+ATRClose*1);
WstegaDolna=iMA( NULL ,0,10,1,MODE_EMA,PRICE_CLOSE,i )*(1-ATRClose*1);


H=iHigh(NULL,0,i);
L=iLow(NULL,0,i);
O=iOpen(NULL,0,i);

i-- ;

}
//-----------------------------------------------
//ustalenie sygnalów
//-----------------------------------------------


i = 3 ;

while(i>=0)
{

if ( H>WstegaGorna[i+1] )
{
SYG[i]=-1;
}
else
{
if ( L[i]<WstegaDolna[i+1] )
{
SYG[i]=1;
}
else
{

SYG[i]=SYG[i+1];
}
}




i--;
}


//Sygnal kupna przez odwrocenie pozycji


if ((SYG[0]==1 && SYG[1]==-1)|| (SYG[0]==1 && SYG[1]==1 && SYG[2]==-1))
{OrderSelect(0,SELECT_BY_POS,MODE_TRADES);

if(OrderType() == OP_SELL && OrderLots()>0)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket(), OrderLots(), Ask, 3);
}

if(OrderType()!=OP_BUY && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_BUY, 0.3, Ask, 5, Ask*0.995, Ask*1.005, "", 8, 0, Blue);
return;
}
}

// Sygnal kupna po cover

if ((SYG[0]==1 && SYG[1]==0)|| (SYG[0]==1 && SYG[1]==1 && SYG[2]==0) )
{
if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_BUY, 0.3, Ask, 5, Ask*0.995, Ask*1.005, "", 8, 0, Blue);
return;
}
}

//Sygnal sprzedazy przez odwrocenie pozycji

if ((SYG[0]==-1 && SYG[1]==1)|| (SYG[0]==-1 && SYG[1]==-1 && SYG[2]==1))
{OrderSelect(0,SELECT_BY_POS,MODE_TRADES);

if(OrderType() == OP_BUY && OrderLots()>0)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket(), OrderLots(), Bid, 3);
}

if(OrderType()!=OP_SELL && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_SELL, 0.3, Bid, 5, Bid*1.005, Bid*0.995, "", 8, 0, Red);
return;
}
}

// Sygnal sprzedazy po cover

if ((SYG[0]==-1 && SYG[1]==0)||(SYG[0]==-1 && SYG[1]==-1 && SYG[2]==0) )
{
if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_SELL, 0.3, Bid, 5, Bid*1.005, Bid*0.995, "", 8, 0, Red);
return;
}
}

// Cover

if ((SYG[0]==0 && (SYG[1]==1 || SYG[1]==-1)) || (SYG[0]==0 && SYG[1]==0 && (SYG[2]==1 || SYG[2]==-1)) )
{
if(OrderType() == OP_BUY && OrderLots()>0 && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Bid, 3);
}
if(OrderType() == OP_SELL && OrderLots()>0 && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Ask, 3);
}
}

// Niezgodna pozycja

if (SYG[0]==1 && SYG[1]==1 && OrderType() == OP_SELL)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Ask, 3);
}

if (SYG[0]==-1 && SYG[1]==-1 && OrderType() == OP_BUY)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Bid, 3);
}
return(0);
}
//+------------------------------------------------------------------+


a niżej kod indyka, który rysuje wstęgi

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 LightSeaGreen
#property indicator_color2 LightSeaGreen


double WstegaGorna[1000];
double WstegaDolna[1000];
double SYG[1000];
double EMA[1000];
double ATRClose[1000];
double L[1000];
double H[1000];
double O[1000];


//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
IndicatorShortName("SYG");
//---- indicators
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0, WstegaGorna);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1, WstegaDolna);




//----
return(0);
}


//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+

int start()
{
int i, counted_bars=IndicatorCounted();

i=Bars-1;

if(counted_bars>=0) i=Bars-counted_bars-1;
while(i>=0)
{

ATRClose[i]=iATR(NULL,0,10,0)/Close[i];
WstegaGorna[i]=iMA( NULL ,0,10,1,MODE_EMA,PRICE_CLOSE,i )*(1+ATRClose[i]*1);
WstegaDolna[i]=iMA( NULL ,0,10,1,MODE_EMA,PRICE_CLOSE,i )*(1-ATRClose[i]*1);


i--;
}
}
//+------------------------------------------------------------------+

Będę wdzięczny za wskazanie błędów i poprawienie kodu.

-- Dodano: ndz 07-04-2013, 9:42 --

Zmieniłem sposób działania EA na kanały cenowe Donchiana bo tutaj lepiej widac że cos jest nie tak

EA:
///////////////////////////////////////

double KanalGorny[12];
double KanalDolny[12];
double SYG[12];
double ATRClose[12];
double L[12];
double H[12];
double O[120];

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+

int start()
{

// przeliczanie parametrów
int i = 3 ;
while(i>=0)
{
KanalGorny[i]=High[iHighest(NULL, 0, MODE_HIGH, 70, i)];
KanalDolny[i]=Low[iLowest(NULL, 0, MODE_LOW, 70, i)];


H[i]=iHigh(NULL,0,i);
L[i]=iLow(NULL,0,i);
O[i]=iOpen(NULL,0,i);

i-- ;

}
//-----------------------------------------------
//ustalenie sygnalów
//-----------------------------------------------


i = 3 ;

while(i>=0)
{

if ( H[i]>KanalGorny[i+1] )
{
SYG[i]=-1;
}
else
{
if ( L[i]<KanalDolny[i+1] )
{
SYG[i]=1;
}
else
{

SYG[i]=SYG[i+1];
}
}




i--;
}


//Sygnal kupna przez odwrocenie pozycji


if ((SYG[0]==1 && SYG[1]==-1)|| (SYG[0]==1 && SYG[1]==1 && SYG[2]==-1))
{OrderSelect(0,SELECT_BY_POS,MODE_TRADES);

if(OrderType() == OP_SELL && OrderLots()>0)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket(), OrderLots(), Ask, 3);
}

if(OrderType()!=OP_BUY && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_BUY, 0.3, Ask, 5, Ask*0.995, Ask*1.005, "", 8, 0, Blue);
return;
}
}

// Sygnal kupna po cover

if ((SYG[0]==1 && SYG[1]==0)|| (SYG[0]==1 && SYG[1]==1 && SYG[2]==0) )
{
if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_BUY, 0.3, Ask, 5, Ask*0.995, Ask*1.005, "", 8, 0, Blue);
return;
}
}

//Sygnal sprzedazy przez odwrocenie pozycji

if ((SYG[0]==-1 && SYG[1]==1)|| (SYG[0]==-1 && SYG[1]==-1 && SYG[2]==1))
{OrderSelect(0,SELECT_BY_POS,MODE_TRADES);

if(OrderType() == OP_BUY && OrderLots()>0)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket(), OrderLots(), Bid, 3);
}

if(OrderType()!=OP_SELL && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_SELL, 0.3, Bid, 5, Bid*1.005, Bid*0.995, "", 8, 0, Red);
return;
}
}

// Sygnal sprzedazy po cover

if ((SYG[0]==-1 && SYG[1]==0)||(SYG[0]==-1 && SYG[1]==-1 && SYG[2]==0) )
{
if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_SELL, 0.3, Bid, 5, Bid*1.005, Bid*0.995, "", 8, 0, Red);
return;
}
}

// Cover

if ((SYG[0]==0 && (SYG[1]==1 || SYG[1]==-1)) || (SYG[0]==0 && SYG[1]==0 && (SYG[2]==1 || SYG[2]==-1)) )
{
if(OrderType() == OP_BUY && OrderLots()>0 && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Bid, 3);
}
if(OrderType() == OP_SELL && OrderLots()>0 && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Ask, 3);
}
}

// Niezgodna pozycja

if (SYG[0]==1 && SYG[1]==1 && OrderType() == OP_SELL)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Ask, 3);
}

if (SYG[0]==-1 && SYG[1]==-1 && OrderType() == OP_BUY)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Bid, 3);
}
return(0);
}
//+------------------------------------------------------------------+


//////////////
//////////////
/////////////


a tutaj indykator rysujący kanały:

//////////////////////////////


#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 LightSeaGreen
#property indicator_color2 LightSeaGreen


double KanalGorny[10000];
double KanalDolny[10000];
double SYG[10000];
double EMA[10000];
double ATRClose[10000];
double L[10000];
double H[10000];
double O[10000];


//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
IndicatorShortName("SYG");
//---- indicators
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0, KanalGorny);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1, KanalDolny);




//----
return(0);
}


//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+

int start()
{
int i, counted_bars=IndicatorCounted();

i=Bars-1;

if(counted_bars>=0) i=Bars-counted_bars-1;
while(i>=0)
{

KanalGorny[i]=High[iHighest(NULL, 0, MODE_HIGH, 70, i)];
KanalDolny[i]=Low[iLowest(NULL, 0, MODE_LOW, 70, i)];


i--;
}
}
//+------------------------------------------------------------------+

-- Dodano: ndz 07-04-2013, 15:23 --

Już wiem, dałem błędny rozmiar tablicy double O[120]; powinno być double O[12];

Awatar użytkownika
Tig3r
Przyjaciel Forum
Przyjaciel Forum
Posty: 2310
Rejestracja: 02 sty 2008, 10:46

Re: moje EA - dlaczego nie działa?

Nieprzeczytany post autor: Tig3r »

Mała uwaga, jeśli tworzysz wskaźnik to nie potrzebujesz tablic typu:

Kod: Zaznacz cały

double WstegaGorna[10000];
double WstegaDolna[10000];
double SYG[1000];
double EMA[1000];
double ATRClose[10000];
double L[1000];
double H[1000];
double O[1000];
W MT4 dla wskaźników sa buffory.

I tak jak weźmiesz pierwszy lepszy wksaźnik:

Kod: Zaznacz cały

// przed funkcjami
#property  indicator_buffers 1
double     ExtBuffer0[];

// w init:
SetIndexBuffer(0,ExtBuffer0);

// a potem w kodzie:
ExtBuffer0[0] - bieżąca świeca
ExtBuffer0[i] - poprzednie świece o i wstecz
======================================================
Nie głupi ten co nie wie, lecz ten który nie chce się nauczyć..

farnick
Bywalec
Bywalec
Posty: 18
Rejestracja: 02 lis 2011, 09:51

Re: moje EA - dlaczego nie działa?

Nieprzeczytany post autor: farnick »

EA niestety nie działa prawidłowo. Niby otwiera i zamyka pozycje ale jak się przyjrzeć dobrze wykresowi robionemu w czasie testu to okazuje się że zamyka pozycje w zupełnie przypadkowych momentach.
Podobnie z otwieraniem.
Sam algorytm otwierania i odwracania pozycji jest bardzo prosty - jak cena przebije górna wstęgę to ma zamknąć longa i otworzyć shorta , jak przebije dolna wstęgę to ma zamknąć shorta i otworzyć longa. EA zakłada obecność na rynku przez cały czas z wyjątkiem odpalenia SL ale ustawiłem je (na potrzeby sprawdzenia czy EA działa prawidłowo) bardzo daleko.

Poniżej wklejam zrzuty ekranu, które pokazują nieprawidłowo zamknięte pozycje - takich wypadków na wykresie jest mnóstwo.
http://charts.mql5.com/1/304/eurusd-m15 ... -banku.png
http://charts.mql5.com/1/304/eurusd-m15 ... anku-2.png

Nie odwraca też pozycji tylko czasami zamyka ale już nie otwiera pozycji przeciwstawnej.

Proszę pomóżcie i wskażcie co jest nie tak z kodem.

Poniżej wklejam pełny kod EA:

Kod: Zaznacz cały

double WstegaGorna[5];
double WstegaDolna[5];
double SYG[5];
double EMA1[5];
double EMA2[5];
double ATRClose[5];
double L[5];
double H[5];
double O[5];



//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+

int start()
{

// przeliczanie parametrów
int i=3 ;
while(i>=0)
{

ATRClose[i]=iATR(NULL,0,10,0)/Close[i];
WstegaGorna[i]=iMA( NULL ,0,10,1,MODE_EMA,PRICE_OPEN,i )*(1+ATRClose[i]*1.5);
WstegaDolna[i]=iMA( NULL ,0,10,1,MODE_EMA,PRICE_OPEN,i )*(1-ATRClose[i]*1.5);

H[i]=iHigh(NULL,0,i);
L[i]=iLow(NULL,0,i);
O[i]=iOpen(NULL,0,i);

  i-- ;

}



//0.2=0.2*NormalizeDouble(AccountEquity()/10/412.25,0);
//if(0.2<0.1) 0.2=0.1;


//-----------------------------------------------
//ustalenie sygnalów
//-----------------------------------------------


i=3 ;
 
while(i>=0)
{

   if ( H[i]>WstegaGorna[i] )
   {
   SYG[i]=-1;
   }
   else
   {
   if ( L[i]<WstegaDolna[i] )
   {
   SYG[i]=1;
   }
   
   else
   {   
   SYG[i]=SYG[i+1];
   }
   }
   
  




i--;
}



//Sygnal long przez odwrocenie pozycji


if (SYG[0]==1 && SYG[1]==-1 /*&& OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true*/)
{
if(OrderType() == OP_SELL && OrderLots()>0)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket(), OrderLots(), Ask, 3);
}

if(OrderType()!=OP_BUY && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_BUY, 0.2, Ask, 5, Ask*0.95, Ask*1.05, "", 8, 0, Blue);
}
return(0);
}

// Sygnal long po cover

if (SYG[0]==1 && SYG[1]==0 && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_BUY, 0.2, Ask, 5, Ask*0.95, Ask*1.05, "", 8, 0, Blue);
return(0);
}

//Sygnal short przez odwrocenie pozycji

if (SYG[0]==-1 && SYG[1]==1 /*&& OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true*/)
{
if(OrderType() == OP_BUY && OrderLots()>0)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket(), OrderLots(), Bid, 3);
}

if(OrderType()!=OP_SELL && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_SELL, 0.2, Bid, 5, Bid*1.05, Bid*0.95, "", 8, 0, Red);
}
return(0);
}

// Sygnal short po cover

if (SYG[0]==-1 && SYG[1]==0 && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==false)
{
OrderSend(Symbol(), OP_SELL, 0.2, Bid, 5, Bid*1.05, Bid*0.95, "", 8, 0, Red);
return(0);
}

// Cover

if (SYG[0]==0 && (SYG[1]==1 || SYG[1]==-1) && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true) 
{
if(OrderType() == OP_BUY && OrderLots()>0 )
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Bid, 3);
}
if(OrderType() == OP_SELL && OrderLots()>0 )
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Ask, 3);
}
return(0);
}

// Niezgodna pozycja

if (SYG[0]==1 && SYG[1]==1 && OrderType() == OP_SELL)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Ask, 3);
}

if (SYG[0]==-1 && SYG[1]==-1 && OrderType() == OP_BUY)
{
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket() , OrderLots(), Bid, 3);
}


return(0);
}
//+------------------------------------------------------------------+


i niżej kod indyka który rysuje wstęgi (zrobiony na razie jeszcze po staremu czyli z tymi dużymi tablicami:

Kod: Zaznacz cały


#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 LightSeaGreen
#property indicator_color2 LightSeaGreen



double WstegaGorna[10000];
double WstegaDolna[10000];
double SYG[10000];
double Rozn[10000];
double ATRClose[10000];
double L[10000];
double H[10000];
double O[10000];


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorShortName("SYG");
//---- indicators
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,  WstegaGorna);
      SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,  WstegaDolna);
   
      
//----
   return(0);
  }


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

int start()
  {
  int i, counted_bars=IndicatorCounted();
   
 i=Bars-1;
 
if(counted_bars>=0) i=Bars-counted_bars-1;
while(i>=0)
{

ATRClose[i]=iATR(NULL,0,10,0)/Close[i];
WstegaGorna[i]=iMA( NULL ,0,10,1,MODE_EMA,PRICE_OPEN,i )*(1+ATRClose[i]*1.5);
WstegaDolna[i]=iMA( NULL ,0,10,1,MODE_EMA,PRICE_OPEN,i )*(1-ATRClose[i]*1.5);
      
     H[i]=iHigh(NULL,0,i);
     L[i]=iLow(NULL,0,i);
     O[i]=iOpen(NULL,0,i); 
      
   
i--;
}
}
//+------------------------------------------------------------------+

dulf
Pasjonat
Pasjonat
Posty: 399
Rejestracja: 24 kwie 2010, 15:13

Re: moje EA - dlaczego nie działa?

Nieprzeczytany post autor: dulf »

Czego jęczysz ,jak zabrałeś się za programowanie to myśl jak programista - samodzielnie .
To nie polega na tym żeby napisać skomplikowany kod i wołać o pomoc ,jeśli coś nie działa trzeba uprościć.
Sprawdzić czy dane pokrywają się z tymi których oczekujemy i czy poszczególne części warunków działają poprawnie.
Brak jest debugera ale można to obejść .
1.Czy wartości z bufora ze wstęgami EA pokrywają się w momencie gdy cena spełnia warunki otwarcia na wykresie ze wskaźnikiem .
2.Zastosuj początkowo TYLKO jeden warunek do sprawdzenia SYG[] , daruj sobie odwracanie pozycji , zamykania itp .
3.Doprowadz do stanu że zacznie działać .
4.Dołóż kolejny fragment kodu.
5.Patrz co spierdoliłeś.
6.Patrz punkt 3 .

Jak rozumiem testujesz w trybie wizualnym ,czyli masz EA , wskaźnik i EA zbierają wartości z TF aktualnego i taki wykres uruchamiasz,czyli jeśli wstęga ma być z M15 , to takie wartości masz przedstawione na wskaźniku i takich oczekujesz z EA .
Wrzuć do EA kod który pozwoli podejrzeć wartości wstęg EA i czy pokrywają się z wskaźnikiem .

Comment(DoubleToStr( WstegaGorna[0],..) +" " + DoubleToStr(Dolna[]0] itp itd .
wyświetli ci na aktualnym wykresie w górnym rogu wartość zmiennej ,porównaj to z wykresem lub sprawdz sobie wartości
warunków czy są poprawne.

Podobnie możesz zobaczyć czy zawartość SYG jest poprawna .

Kolejną rzeczą to wydaje mi się że żle operujesz zleceniami , Wybierając przez Select powinieneś raczej operować następnie na pętli przez OrdersTotal .Może nie ma to w tym momencie znaczenia trochę nie tak .
Te warunki są zamotane , zrób na początek jeden konkretny ,aby było widać że pozycja jest otwierana w poprawnym miejscu.Ilość zleceń i Select wystarczy prawdopodobnie użyć raz przez sprawdzaniem wszystkich warunków.
OrdersTotal wskazuje na ilość zleceń , przez tą fun przechodzisz do Select ,dopiero szukasz zleceń.Nie można zakładać że akurat indeks 0 będzie odpowiadał zleceniu które tobie się podoba ,albo przez Select sprawdzisz że akurat pozycja otwarta jako pierwsza będzie w dalszym przetwarzaniu miała indeks 0 i będzie ona akurat Sell lub Buy .
To tak na pierwszy rzut oka .
http://bossa.pl/index.jsp?layout=2&page ... at_id=1338
Nie spiesz się , zawsze zdążysz stracić .

ODPOWIEDZ