Wszystkie pytania dozwolone początkujących programistów

O jezykach programowania w platformach i nie tylko.
ext3
Gaduła
Gaduła
Posty: 136
Rejestracja: 04 maja 2010, 21:46

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: ext3 »

Ile czasu ma na wykonanie się funkcja start() w EA? Czy jest przerywana, gdy trwa zbyt długo?
Chodzi mi głównie o to, czy jej wykonanie zostanie przerwane przy nadejściu nowego ticku, zanim poprzednie wywołanie zostanie ukończone. Zagadnienie wiąże się chyba z wątkami/ilością wątków?
Co się dzieje w sytuacji np. przychodzi kilka bardzo szybkich ticków, a mamy napisaną funkcję, której wykonanie trwa dłużej niż odstęp między tickami? Czy kolejne ticki - powodują nowe wywołania funkcji start() i przerywają wykonanie ewentualnych trwających jeszcze poprzednich wywołań?

Moje pytanie zadaję w kontekście napisania prostego EA, które będzie zamykać wszystkie otwarte i oczekujące pozycje. Taka pętla po wszystkich zleceniach z order pool może trochę trwać szczególnie z konieczną obsługą błędów (wrong price, za mały slippage, refreshRates(), dodatkowy while dla IsTradeContextBusy() - w przypadku kilku par). EA każdej pary dodatkowo sprawdza wszystkie zlecenia, w tym samym czasie co EA na innych parach i tu mogą wystąpić opóźnienia i blokowanie dostępu do trading context. Idealnie byłoby, gdyby każde wywołanie start() miało nieograniczony czas na wykonanie, ale pewnie tak nie jest, bo mogłoby skutkować kikloma chodzącymi wywołaniami w danym czasie (bieżące + spóźnione).

Z góry dzięki za wszelkie info.

David_Plavko
Gaduła
Gaduła
Posty: 132
Rejestracja: 27 sie 2011, 13:10

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: David_Plavko »

ext3, nowe ticki są ignorowane aż do do wykonania całej funkcji.

Misfic
Bywalec
Bywalec
Posty: 12
Rejestracja: 15 cze 2011, 16:36

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: Misfic »

Dzięki bfx.

Mam kolejne pytanie. Napisałem prostego EA, który zawiera losowo transakcje z ustalonym TP i SL. Kompilator nie zwraca błędów, ale podczas testów nie ma ani jednego tradea.

Kod: Zaznacz cały

double SLk;
double TPk;
double SLs;
double TPs;
double odleglosc_k;
double odleglosc_s;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetTimer(60);
    MathSrand(GetTickCount());
      
//---
   return(INIT_SUCCEEDED);
  }
  
  //EA
 int start()
  {
  
   if (iVolume(Symbol(),PERIOD_D1,0)==1) 
      {
      odleglosc_s = (MathMax(iHigh(Symbol(),PERIOD_D1,2),MathMax(iHigh(Symbol(),PERIOD_D1,3),iHigh(Symbol(),PERIOD_D1,4))-Bid));
      odleglosc_k = (Ask-MathMin(iLow(Symbol(),PERIOD_D1,2),MathMin(iLow(Symbol(),PERIOD_D1,3),iLow(Symbol(),PERIOD_D1,4))));
      SLk=Ask-odleglosc_k;
      TPk=Ask+3*odleglosc_k;
      SLs=Bid+odleglosc_s;
      TPs=Bid-3*odleglosc_s;
 

 
 if (0.3<=MathRand()/32767)
 {OrderSend(Symbol(),OP_BUY,0.1,Ask,3,SLk,TPk);
 return(0);}

if (0.3<=MathRand()/32767)
 {OrderSend(Symbol(),OP_SELL,0.1,Bid,3,SLs,TPs);
 return(0);
 } 
 return(0);
 
   }
   return(0);}
 
 
 
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Tester function                                                  |
//+------------------------------------------------------------------+
double OnTester()
  {
//---
   double ret=0.0;
//---

//---
   return(ret);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   
  }
Czemu tak jest?

Kod który ja pisałem to tylko wypisanie zmiennych, MathSrand w OnInit oraz int start(). Reszta została mi wygenerowana przez MT4, kiedy zaczynałem tworzyć nowe EA.

ext3
Gaduła
Gaduła
Posty: 136
Rejestracja: 04 maja 2010, 21:46

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: ext3 »

David_Plavko pisze:ext3, nowe ticki są ignorowane aż do do wykonania całej funkcji.
Dzięks David.

@Misfic

Nie wiem, czy to Ci pomoże, ale samo gołe wywołanie ordersend w EA, które ma coś później robić na koncie real jest ryzykowne. Warto dodać obsługę błędów, umieścić ordersend w pętli while, sprawdzić trading context, sprawdzić, czy nie było błędu - err=GetlastError() i zrobić print() tego erroru, żebyś wiedział jaki jest problem z wysłaniem zlecenia, czasem jest TP/SL za blisko, czasem już zła cena, slippage za mały. Sporo możliwości 'wykrzaczenia'. A najlepiej też stworzyć w EA osobny plik na dysku z logiem i tam zrzucać takie eventy na bieżąco.

Ja mam taki prosty kod znaleziony w necie, może ktoś poprawić/uzupełnić w razie konieczności:

Kod: Zaznacz cały

             count = 0; c1 = false;
              while ((c1 == false) && (count < closeTrialCount))
              {
                     RefreshRates();                                
                     closeQuote = NormalizeDouble(MarketInfo(OrderSymbol(),MODE_BID),MarketInfo(OrderSymbol(),MODE_DIGITS));                       
                     while(IsTradeContextBusy()) { Print("wating for context"); Sleep(100); }   
                     c1 = OrderClose(OrderTicket(), OrderLots(), closeQuote, closeSlip);   
                     if (c1 == true) { FileWrite(handle, "Order Closed: ",OrderTicket()); FileFlush(handle); break;}       
                     count++;
               }  if (c1 != true) {   err=GetLastError(); FileWrite(handle, "blad zamykania pozycji(",err,") : ",OrderTicket()); FileFlush(handle); }    

Tutaj czekanie na context jest nieskończone, zakładam, że się skończy. W zasadzie powinno się też dodać max liczbę prób, lub max czas oczekiwania, żeby nie zwiesić EA.

Awatar użytkownika
bfx
Pasjonat
Pasjonat
Posty: 1260
Rejestracja: 11 sty 2013, 15:49

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: bfx »

Witam. Czy jest możliwośc sprawdzenia czy mamy widoczny np. wykres liniowy? Chciałbym żeby wskaźnik pokazywał mi niektóre rzeczy tylko jak mam wykres świeczkowy..
"Ty też jesteś Bogiem! Tylko uświadom to sobie, sobie"

Awatar użytkownika
lolek
Gaduła
Gaduła
Posty: 335
Rejestracja: 26 lut 2008, 00:12

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: lolek »

bfx pisze:Witam. Czy jest możliwośc sprawdzenia czy mamy widoczny np. wykres liniowy? Chciałbym żeby wskaźnik pokazywał mi niektóre rzeczy tylko jak mam wykres świeczkowy..
Bardzo fajne pytanie :564:
Myślę że dawniej nie było takiej funkcji a przynajmniej ja nie widziałem ale teraz po pojawieniu się MT5 wzięli się też za MT4 i dodali parę rzeczy.
Możesz nie tylko pobierać ale też zmieniać te ustawienia i nawet otwierać nowy wykres.
Funkcja której potrzebujesz w Twoim przypadku to ChartGetInteger i musisz ją wywołać z parametrem CHART_MODE
W helpie masz przykład który przetestowałem i fajnie działa.
Tam gdzie definiujesz funkcje czyli poza wszelkimi klamrami (przestrzeń globalna) wklej definicje funkcji z helpa:

Kod: Zaznacz cały

int wynik;
  ENUM_CHART_MODE ChartModeGet(const long chart_ID=0)
  {
//--- prepare the variable to get the property value
   long result=WRONG_VALUE;
//--- reset the error value
   ResetLastError();
//--- receive the property value
   if(!ChartGetInteger(chart_ID,CHART_MODE,0,result))
     {
      //--- display the error message in Experts journal
      Print(__FUNCTION__+", Error Code = ",GetLastError());
     }
//--- return the value of the chart property
   return((ENUM_CHART_MODE)result);
  }
Jak widzisz na samym początku zadeklarowałem sobie też zmienną wynik do której będę zapisywał to co zwróci funkcja.
I teraz tam gdzie potrzebuje wywołuje kod żeby sprawdzić jak jest ustawiony wykres:

Kod: Zaznacz cały

wynik=ChartModeGet();
if(wynik==CHART_BARS) Print("Slupki");
if(wynik==CHART_CANDLES) Print("Swieczki");
if(wynik==CHART_LINE) Print("Linie");
Tu masz taki mały przykład użycia.
Pamiętaj że Print zapisuje komunikaty do zakładki strategie.
Nie pamiętam już czy wskaźnik też ale te Printy są tylko do sprawdzenia czy działa i jak działa to je zamieniasz na to co chcesz.
Ostatnia rzecz jaką trzeba uwzględnić to fakt że po naciśnięciu guzika z wyborem sposobu wyświetlania (np. z linii na świeczki) skrypt nie będzie o tym wiedział i dopiero jak będzie nowy tik to się tego dowie a więc co każdy tik trzeba to sprawdzać i aktualizować.
Możliwe też że po naciśnięciu guzika tego co pisałem ze zmianą sposobu wyświetlania skrypt wywoła OnChartEvent()
Nie wiem czy pamiętasz poprzednią wersje gdzie była funkcja start() wywoływana co każdy tick a teraz jest to funkcja OnTick() i po zmianach dodali też inne funkcje wywoływane zależnie od zdarzeń i dodali też wspomnianą OnChartEvent() związaną ze zdarzeniami zachodzącymi na wykresie.
Ja bym dodał sprawdzanie do OnTick() i do OnChartEvent() dla pewności.
Zawsze można zrobić jakiś tymczasowy kod i zbadać to dokładnie ale nie wiadomo czy nic nie zmienią w przyszłości.
ps. Fajne te nowe funkcje :)
Pozdrawiam.

Awatar użytkownika
bfx
Pasjonat
Pasjonat
Posty: 1260
Rejestracja: 11 sty 2013, 15:49

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: bfx »

Wielkie dzieki! Sprawdze jak bede w domu. A wiesz moze gdzie znajde opis tych nowych funkcji? Jak nie to poszukam. Po polsku pewnie mie ma? Ciekawie sie zapowiada :) dzieki jeszcze raz :)
"Ty też jesteś Bogiem! Tylko uświadom to sobie, sobie"

Awatar użytkownika
lolek
Gaduła
Gaduła
Posty: 335
Rejestracja: 26 lut 2008, 00:12

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: lolek »

Jest bardzo prosta metoda żeby się dowiedzieć.
Wpisujesz jakąkolwiek funkcje do edytora i naciskasz na niej kursor albo od razu naciskasz kursor na funkcji którą Ci edytor utworzył jak rozpoczynasz projekt i naciskasz F1 który włącza helpa do tej funkcji gdzie dałeś kursor i potem już buszujesz po całym helpie który jest co prawda po angielsku ale ma masę przykładów które można od razu wklejać do projektu. Ten help jest bardzo kształcący i intuicyjny.

Druga metoda to wpisywanie tych funkcji na Google i wtedy wchodzisz na takiego helpa online.
np. hasło "ChartGetInteger mql" (bez apostrofa) wpisane do wujka Google daje mi na pierwszym miejscu stronkę z linku poniżej:
http://docs.mql4.com/chart_operations/chartgetinteger

EDIT:
Ten link co Ci dałem to jest dokumentacja online i podobna jest w edytorze tylko ma dodatkowo przykładowe kody.
W edytorze prawie wszystko co edytor po wpisaniu ustawia jakiś kolorek można kliknąć na to kursor i wcisnąć F1 żeby się dowiedzieć coś na ten temat.

Awatar użytkownika
bfx
Pasjonat
Pasjonat
Posty: 1260
Rejestracja: 11 sty 2013, 15:49

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: bfx »

Ok. Fajnie. Bedzie zajecie na weekend. Dzieki
"Ty też jesteś Bogiem! Tylko uświadom to sobie, sobie"

Misfic
Bywalec
Bywalec
Posty: 12
Rejestracja: 15 cze 2011, 16:36

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: Misfic »

Co oznaczają błędy:

Kod: Zaznacz cały

TestGenerator: unmatched data error (volume limit 5800 at 2014.03.18 00:00 exceeded)
TestGenerator: unmatched data error (high value 1.39150 at 2014.03.07 00:00 is not reached from the least timeframe, high price 1.38780 mismatches)
I czym mogą być powodowane?

Z góry dzięki za pomoc.

ODPOWIEDZ