Tylko jedna operacja podczas trwania świecy

O jezykach programowania w platformach i nie tylko.
nerio
Bywalec
Bywalec
Posty: 8
Rejestracja: 03 mar 2009, 09:53

Tylko jedna operacja podczas trwania świecy

Nieprzeczytany post autor: nerio »

Witam, wszystkich

szukam i kombinuje i
nie mogę sobie poradzić w EA z zabezpieczeniem, aby po spełnionym warunku gdy otwarta zostaje pozycja sytuacja się już nie powtórzyła podczas trwania tej samej godziny(świecy)


teraz mój robot otwiera pozycję i jeśli TP wystąpi za chwilę a warunki które trzeba było spełnić nadal się zgadzają otworzy kolejną, a chciałbym aby robot po spełnieniu warunków zadziałał tylko raz na danej świeczce

poradźcie co tu można wprowadzić jakaś pętla, może jest jakaś funkcja lub licznik ?

Awatar użytkownika
Pierz Andrzej
Przyjaciel Forum
Przyjaciel Forum
Posty: 1200
Rejestracja: 02 lip 2006, 14:17

Re: Tylko jedna operacja podczas trwania świecy

Nieprzeczytany post autor: Pierz Andrzej »

Witam

stwórz funkcje która sprawdza ostatnie zlecenie na historii i zwróć wartość iBarShift w oparciu o czas otwarcia pozycji OrderOpenTime jeżeli będzie 0 oznaczać to będzie że na danej świecy była już otwarta pozycja . Jako defaultową wartość funkcji daj -1.
z poważaniem
Andrzej Pierz
FOREX-SERVICE

robs
Gaduła
Gaduła
Posty: 196
Rejestracja: 22 sty 2010, 03:05

Re: Tylko jedna operacja podczas trwania świecy

Nieprzeczytany post autor: robs »

Ja mam coś takiego.

Kod: Zaznacz cały

//////////////////////////////////////////////////////////////////<          >
bool       bNewBar ()                                           //<          >
{                                                               //<          >
//                                                              //<          >
datetime static iTime_0 = 0;                                    //<          >
//                                                              //<          >
if     ( iTime_0 < iTime ( NULL , 0 , 0 ) )                     //<          >
       { iTime_0 = iTime ( NULL , 0 , 0 ) ; return ( TRUE  ) ; }//<          >
else     {                                 return ( FALSE ) ; } //<          >
//                                                              //<          >
}                                                               //<          >
//////////////////////////////////////////////////////////////////<          >

radical material simplification

nerio
Bywalec
Bywalec
Posty: 8
Rejestracja: 03 mar 2009, 09:53

Re: Tylko jedna operacja podczas trwania świecy

Nieprzeczytany post autor: nerio »

kombinowałem raczej z

Time[0]

i ewentualnie jakimś IF gdyby time !=0

ale marne skutki, wydaje mi się że powinno być coś prostszego od sięgania do historii, bo po prostu nie umiem twojego pomysłu zakodować

-- Dodano: pn 24-08-2015, 16:38 --

dzięki robs to już coś na kształt info które do tej pory znalazłem w sieci, tylko mam pytanie

bo wywala mi błąd że mogę to mieć tylko w sekcji global

a niestety nie widzi moich zmiennych

czy powinienem to wstawić do start()

Awatar użytkownika
Pierz Andrzej
Przyjaciel Forum
Przyjaciel Forum
Posty: 1200
Rejestracja: 02 lip 2006, 14:17

Re: Tylko jedna operacja podczas trwania świecy

Nieprzeczytany post autor: Pierz Andrzej »

sięganie do historii nie jest takie trudne :-)

Kod: Zaznacz cały

int orders_history_bar(int order_type)
{
   for(int i = OrdersHistoryTotal() - 1; i >= 0;i--)
   {  
      if (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) == false) continue;
      if (magic_number == OrderMagicNumber() && OrderType() == order_type &&  Symbol() == OrderSymbol()) return iBarShift(Symbol(),Period(),OrderOpenTime());
   }
   return -1;
}

voi start()
{
.....
if (Twoje warunki dla buy && orders_history_bar(OP_BUY) != 0) otworz zlecenie buy
if (Twoje warunki dla sell && orders_history_bar(OP_SELL) != 0) otworz zlecenie sell
.....
}
oczywiście można skorzystać z funkcji IsNewBar ale pewniejsze z mojego punktu widzenia jest sprawdzenie historii ;-)
z poważaniem
Andrzej Pierz
FOREX-SERVICE

nerio
Bywalec
Bywalec
Posty: 8
Rejestracja: 03 mar 2009, 09:53

Re: Tylko jedna operacja podczas trwania świecy

Nieprzeczytany post autor: nerio »

dziękuje dam znać jutro jak posżło, dziś już kończe

może nie jest trudne :), jednak dziś siedzę cały czas nad plikiem PDF z kursem i dla nie programującego to jednak kosmos

nie ma szans żebym napisał coś takiego jak mi podesłałeś

jutro spróbuje to połączyć ze swoim kodem

nerio
Bywalec
Bywalec
Posty: 8
Rejestracja: 03 mar 2009, 09:53

Re: Tylko jedna operacja podczas trwania świecy

Nieprzeczytany post autor: nerio »

więc po kilku dniach testów wszystko działa zdecydowałem się na rozwiązanie przez zmienną

kiedy dochodzi do otwarcia pozycji
ustawiam zmienną BLOKADA="TAK"

w warunkach otwarcia pozycji musi być spełniony warunek BLOKADA=="BRAK"

do wyzerowania zmiennej BLOKADA użyłem funkcji
isNewBar()

..... BLOKADA="NIE"


i efekt został osiągnięty

dzięki

Awatar użytkownika
bucho1504
Stały bywalec
Stały bywalec
Posty: 55
Rejestracja: 01 sie 2008, 21:46

Re: Tylko jedna operacja podczas trwania świecy

Nieprzeczytany post autor: bucho1504 »

lub można tak

Kod: Zaznacz cały

int start() 
{ 
  if(IsNewBar())
   {
         
   if (countOrdersNumber(144)==0)

 }

return(0);
}

bool countOrdersNumber(int magic_number)
{
  bool found = false;

  for (int i = OrdersTotal()-1 ; i >= 0; i--)
  {
    OrderSelect(i, SELECT_BY_POS, MODE_TRADES);

    if ((OrderMagicNumber() == magic_number) && (OrderSymbol() == Symbol()))
    {
      found = true;
      break;
    }
  }
  return(found);
}
Ten nie popełnia błędów kto nic nie robi

poxter
Stały bywalec
Stały bywalec
Posty: 39
Rejestracja: 26 gru 2007, 20:57

Re: Tylko jedna operacja podczas trwania świecy

Nieprzeczytany post autor: poxter »

Cześć, troszkę odświeżę (lepsze to nić otwieranie nowego tematu).
Mam ten sam problem - też chce zrobić blokadę wykonywania więcej jak jednej transakcji na świecy - załóżmy godzinowej (kupowanie/sprzedawnie idzie po ticku).

Nie zależy mi na typie transakcji więc order_type likwiduje - nurtuje mnie co daje na końcu: " != 0" w podanym kodzie??
Pierz Andrzej pisze:sięganie do historii nie jest takie trudne :-)

Kod: Zaznacz cały

int orders_history_bar(int order_type)
{
   for(int i = OrdersHistoryTotal() - 1; i >= 0;i--)
   {  
      if (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) == false) continue;
      if (magic_number == OrderMagicNumber() && OrderType() == order_type &&  Symbol() == OrderSymbol()) return iBarShift(Symbol(),Period(),OrderOpenTime());
   }
   return -1;
}

voi start()
{
.....
if (Twoje warunki dla buy && orders_history_bar(OP_BUY) != 0) otworz zlecenie buy
if (Twoje warunki dla sell && orders_history_bar(OP_SELL) != 0) otworz zlecenie sell
.....
}
oczywiście można skorzystać z funkcji IsNewBar ale pewniejsze z mojego punktu widzenia jest sprawdzenie historii ;-)
i teraz przy piątku już nie potestuje w realu więc... czy kod powinien wyglądać tak:

Kod: Zaznacz cały

int orders_history_bar
{
   for(int i = OrdersHistoryTotal() - 1; i >= 0;i--)
   {  
      if (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) == false) continue;
      if (magic_number == OrderMagicNumber()  &&  Symbol() == OrderSymbol()) return iBarShift(Symbol(),Period(),OrderOpenTime());
   }
   return -1;
}

voi start()
{
.....
if ( ((kup1 && kup2)  || (kup3 && kup4) ) && orders_history_bar= 0)  otworz zlecenie buy
.....
}
czy może ten wykrzyknik jest potrzebny??

Kod: Zaznacz cały


voi start()
{
.....
if ( ((kup1 && kup2)  || (kup3 && kup4) ) && orders_history_bar != 0)  otworz zlecenie buy
.....
}

-rookie-
Maniak
Maniak
Posty: 2307
Rejestracja: 13 kwie 2015, 19:00

Re: Tylko jedna operacja podczas trwania świecy

Nieprzeczytany post autor: -rookie- »

Może zrób coś na zasadzie countera... Wstaw teraz do testera ten kod i zobacz w konsoli że co 15 minut będzie wyśwwietlało która jest minuta według tej instrukcji if (a(15)) { w onTick. Jak dasz 5 minut to będzie co 5 minut wyświetlało. Żeby wyświetlać co godzine trzeba wpisać 60, co 4 godziny 240 itd . Według tego będziesz miał w tej instrukcji jakąś zaplanowaną akcje co te x minut. W jforex jest to już zrobione jako standard i wystarczy wpisać coś takiego period.equlas(period.FIFTEEN_MIN)) i będzie co 15 minut wykonywało tą instrukcje. W testerze daj period M1 (1 minuta).

Kod: Zaznacz cały

//+------------------------------------------------------------------+
//|                                     periodTestbeta1_29092018.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
     
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
      
      if (a(15)) {
         Print( Minute() );
      }
      
  }
//+------------------------------------------------------------------+

int counter = 0;
bool start = false;
bool a(int period) {
   int n = 0;
   bool test = false;
   if (counter < period + 1) {
      counter ++;
   } 
   if (counter == period + 1) {
      counter = 1;
   }    
   n = counter - 1;
   if (n + period == period) {
      //test = true; // pierwszy test musi zwracac false, potrzebne jest sprawdzenie tego jako bool start
      if (start == true) {
         test = true;
      }
      if (start == false) {
         start = true;
      }
   } else {
      test = false;
   }
   //Print( (n + period) + " " + (period) );
   return test;
}
-- Dodano: 29 wrz 2018, 03:45 --

Zapomniałem o skalowaniu według otwartego timeframe. Bo jeśli na M1 to wszystko dzielisz przez 1, jeśli M5 to przez 5 itd. Więc to będzie wyglądało mniej więcej tak... funkcja scale() może zwracać dzielnik według otwartego TF, jeśli dasz w testerze M5 lub będziesz to miał na wykresie M5 na bieżąco wtedy będziesz mógł zmieniać TF na inne a scale() będzie zwracało dzielnik w zależności na jakim interwale jesteś i podstawiało do period = period / scale();

Kod: Zaznacz cały

bool start = false;
bool b(int period) {
   int n = 0;
   bool test = false;
   period = period / scale();
   if (counter < period + 1) {
      counter ++;
   } 
   if (counter == period + 1) {
      counter = 1;
   }    
   n = counter - 1;
   if (n + period == period) {
      //test = true; // pierwszy test musi zwracac false, potrzebne jest sprawdzenie tego jako bool start
      if (start == true) {
         test = true;
      }
      if (start == false) {
         start = true;
      }
   } else {
      test = false;
   }
   //Print( (n + period) + " " + (period) );
   return test;
}

int scale() {
   int n = 0;
   if (Period() == PERIOD_M1) {
      n = 1;
   } else if (Period() == PERIOD_M5) {
      n = 5;
   } else if (Period() == PERIOD_M15) {
      n = 15;
   }
   //. itd
   return n;
}
Może z tym pokombinuj...

-- Dodano: 29 wrz 2018, 09:09 --

Jednak to wyżej to jest średni pomysł, lepiej chyba zrobić to tak... sprawdzić resztę z dzielenia Minute() % period np 15. Tutaj ustawiłem dla przykładu że według losowej liczby będzie otwierało buy lub sell, jeśli random jest mniejsze lub większe od 100. I otowrzy tylko 1 pozycje ponieważ w funkcji jest if (OrdersTotal() > 0) return; które przerywa funkcje jeśli jest już otwarta jakaś pozycja. I najpierw zamyka zlecenie potem otwiera kolejne. Tutaj akurat ustawiłem co godzinę, czyli 60 minut na wejściu if (h(60))

Kod: Zaznacz cały

//+------------------------------------------------------------------+
//|                                     periodTestbeta1_29092018.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

extern int MagicNumber = 100;
extern int Slippage = 3;
extern double LotSize = 0.1;
int _counter = 0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
     
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
      if (h(60)) {
         int random = MathRand() / 100;
         if (random < 100) {
            manuallyCloseOrder();
            sendBuyOrder();
         } else {
            manuallyCloseOrder();
            sendSellOrder();
         }
         //Print( random );
      }      
      
  }
//+------------------------------------------------------------------+


bool h(int period) {
   int n = 0;
   bool d = false;
   if ((Minute() % period) == 0) {
      //Print( Minute() + " <<< " );
      d = true;
   } else {
      //Print( Minute() );
      d = false;
   }
   return d;
}

void sendBuyOrder() {
   if (OrdersTotal() > 0) return;
   OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, 0, 0,"Buy[" + _counter +"]", MagicNumber, 0, clrGreen);
   _counter++;
}

void sendSellOrder() {
   if (OrdersTotal() > 0) return;
   OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, 0, 0,"Sell[" + _counter +"]", MagicNumber, 0, clrRed);
   _counter++;
}

void manuallyCloseOrder() {
   for(int i=OrdersTotal(); i>=0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 0) {
            OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 0, clrNONE);
         } else if (OrderType() == 1) {
            OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 0, clrNONE);
         }
      }
   }
}
-- Dodano: 29 wrz 2018, 09:11 --

tak samo testowane na M1 w testerze, wiec pewnie wymaga dodania scale() tak jak w przykładzie wyżej. Ale to już...

ODPOWIEDZ