Automatyczna pozycja przeciwstawna do każdego otwartego

O jezykach programowania w platformach i nie tylko.
Awatar użytkownika
hienas
Stały bywalec
Stały bywalec
Posty: 30
Rejestracja: 27 cze 2007, 16:25

Automatyczna pozycja przeciwstawna do każdego otwartego

Nieprzeczytany post autor: hienas »

Witajcie,
Próbuję uporać się z takim automatem-pomocnikiem, który wystawiałby automatyczne zlecenia oczekujące do każdego, które jest już otwarte na rynku, lub które dopiero otworzę. Dodatkowym warunkiem jest sprawdzanie wolumenu przeciwstawnych zależnie od preferencji. Powinien również skanować zlecenia na bieżąco - niezależnie od tego w którym momencie go włączę (z czystą listą zleceń, czy z już otwartymi przed jego włączeniem).


Założeniem wyjściowym było "dopisywanie" komentarza do wysyłanego zlecenia oczekującego z numerem kontr-zlecenia dla którego zostało ono złożone. Miał to być znak rozpoznawczy, że zlecenie jest już "obsłużone". Może to siermiężna metoda, ale lepszej logicznej i praktycznej nie znalazłem...

W kodzie jest kilka "nic nie robiących" funkcji piszących tylko numery zleceń - póki nie uporam się z poprawną selekcją to sporo ułatwia by nie pogubić się w kodzie i w śledzeniu logów EA.

Przykład:
1. jest na rynku zlecenie BUY z ticketem 111111
2. jest na rynku zlecenie SELL z ticketem 999999
3. jest zlecenie oczekujące z ticketem 333333

4. skanuje listę zleceń i usuwam pending order, gdyż jego wolumen nie odpowiada moim założeniom z EA
5. usuwa oczekujące, zostają dwa aktywne
6. do zlecenia BUY sprawdza (na podstawie komentarza) czy nie istnieje dla niego już kontra
6a. jeśli nie istnieje to wrzuca na rynek oczekujące z komentarzem "Kontra dla 111111" - to znak rozpoznawczy
6b. jeśli istnieje - przechodzę do kolejnego aktywnego zlecenia
7. do zlecenia SELL sprawdza czy nie istnieje kontra
7a. jeśli nie istnieje to wrzuca na rynek oczekujące z komentarzem "Kontra dla 999999" - to znak rozpoznawczy
7b. jeśli istnieje - przechodzę do kolejnego aktywnego zlecenia
8. brak innych zleceń - koniec pętli

9. wrzucam z ręki kolejny SELL z ticketem 5555555
10. pętla sprawdza wszystkie zlecenia czy posiadają kontr-zlecenia, jeśli nie mają to wysyła kolejne oczekujące z komentarzem "Kontra dla 555555"
itd.


Tak to mniej więcej powinno wyglądać wg moich założeń, jednak podczas wielokrotnego multiskanowania mieszają się w kodzie aktualnie wybrane zlecenia przez OrderSelect() - przez co EA nie potrafi przeskanować wszystkiego poprawnie :(

Czy znalazłby się ktoś, kto poprawiłby mój kod?

PS. W rezultacie będzie to przydatne narzędzie nie tylko dla mnie


Oto moja próbka kodu:

Kod: Zaznacz cały

//+------------------------------------------------------------------+
//|                                        auto pending position.mq4 |
//|                                                     2015 - Jacek |
//+------------------------------------------------------------------+
#property copyright "2015 Jacek"

extern int     auto_pending_distance = 250;
extern string  vol_przeciwstawnej_pozycji = "!!! w procentach %%% !!!";
extern int     oposite_order_volumen = 100;
extern string  maxymalny_volumen = "MAXYMALNY DOPUSZCZALNY VOLUMEN ?";
extern double  max_vol = 0.1;


//extern bool ignoreOtherEA=true;

// INICJALIZACJA EXPERTA
int init() {
   Print("KONTO:  ", AccountInfoDouble(ACCOUNT_BALANCE) );
   return(0);
}

// DE-INICJALIZACJA EXPERTA
int deinit() {
   return(0);
}

// FUNKCJA GŁÓWNA
int start() 
{
   double poziom_wejscia,pre_pending_order;
   
   // JEŚLI JEST TYLKO 1 ZLECENIE OTWARTE :
   if (OrdersTotal()==1)
   {  
      for(int i=0;i<OrdersTotal();i++)
      {  if(!OrderSelect(i,SELECT_BY_POS)) continue;
         //double v = NormalizeDouble(OrderLots()+ (OrderLots()*2),2);
         
         if(OrderType()==OP_BUY)       // jeśli aktualne zlecenie to BUY
         {  poziom_wejscia=OrderOpenPrice();
            pre_pending_order = poziom_wejscia-(auto_pending_distance*Point);
            if(OrderSend(Symbol(),OP_SELLSTOP,vol(OrderLots()),pre_pending_order,0,0,0,"Kontra do zlecenia "+OrderTicket())) continue;
            Print(OrderComment());
         }

         if(OrderType()==OP_SELL)      // jeśli aktualne zlecenie to SELL
         {  poziom_wejscia=OrderOpenPrice();
            pre_pending_order = poziom_wejscia+(auto_pending_distance*Point);
            if(OrderSend(Symbol(),OP_BUYSTOP,vol(OrderLots()),pre_pending_order,0,0,0,"Kontra do zlecenia "+OrderTicket())) continue;
         }
         
         // ZAMYKANIE POZYCJI OCZEKUJĄCYCH, JEŚLI NIE MA INNYCH
         if(OrdersTotal()==1 && (OrderType()==OP_BUYSTOP ||
                                 OrderType()==OP_SELLSTOP ||
                                 OrderType()==OP_BUYLIMIT ||
                                 OrderType()==OP_SELLLIMIT))
         {  if(OrderDelete(OrderTicket())) continue;
            Print("OrderDelete ostatni error jest: ",GetLastError() + ", A TICKET TO: " + DoubleToString(OrderTicket(),8));

         }
         
         //Print("Pozycja: "+ DoubleToStr(i,0)+" - "+ DoubleToStr(NormalizeDouble(pre_pending_order,Digits),Digits));
      }
   }


   // JEŚLI JEST WIĘCEJ NIŻ 1 ZLECENIE OTWARTE :
   int    order_ticket  =  0;
   if (OrdersTotal()>2)
   {  
      for(int k=0;k<OrdersTotal();k++)
      {  //if(!OrderSelect(k,SELECT_BY_POS)) continue;
         
         
         if(OrderSelect(k, SELECT_BY_POS)==true)
            {order_ticket=OrderTicket();
             //   PROCEDURA SPRAWDZENIA CZY ISTNIEJE JUŻ PRZECIWSTAWNE ZLECENIE
             Print("OrderSelect wybrał zlecenie nr ",order_ticket);
             czy_ticket_istnieje(OrderTicket());
             
            } else
         Print("OrderSelect failed error code is ",GetLastError());
         
         
         if(OrderType()==OP_BUY)       // jeśli aktualne zlecenie to BUY
         {  poziom_wejscia=OrderOpenPrice();
            pre_pending_order = poziom_wejscia-(auto_pending_distance*Point);
            //OrderSend(Symbol(),OP_SELLSTOP,vol(OrderLots()),pre_pending_order,0,0,0,NULL);
         }

         if(OrderType()==OP_SELL)      // jeśli aktualne zlecenie to SELL
         {  poziom_wejscia=OrderOpenPrice();
            pre_pending_order = poziom_wejscia+(auto_pending_distance*Point);
            //OrderSend(Symbol(),OP_BUYSTOP,vol(OrderLots()),pre_pending_order,0,0,0,NULL);
         }
         
         // ZAMYKANIE POZYCJI OCZEKUJĄCYCH, JEŚLI NIE MA INNYCH
         if(OrdersTotal()==1 && (OrderType()==OP_BUYSTOP ||
                                 OrderType()==OP_SELLSTOP ||
                                 OrderType()==OP_BUYLIMIT ||
                                 OrderType()==OP_SELLLIMIT))
         {  //OrderDelete(OrderTicket());
         }
         
         //Print("Pozycja: "+ DoubleToStr(i,0)+" - "+ DoubleToStr(NormalizeDouble(pre_pending_order,Digits),Digits));
      }
   }



   // USUWANIE POZYCJI PRZECIWSTAWNYCH ZE ZŁYM VOLUMENEM W STOSUNKU DO POZYCJI AKTYWNEJ  
   if (OrdersTotal()>=2)
   {  
      double pos_active_vol,    pos_pending_vol;
      int    pos_active_ticket, pos_pending_ticket;
      string koment;
      for(int j=0;j<OrdersTotal();j++)
      {  if(OrderSelect(j,SELECT_BY_POS)==True);
                  
          if(OrderType()==OP_BUY || OrderType()==OP_SELL) {
            pos_active_vol=OrderLots();
            pos_active_ticket=OrderTicket();
            }

          if(OrderType()==OP_BUYLIMIT || OrderType()==OP_BUYSTOP || OrderType()==OP_SELLLIMIT || OrderType()==OP_SELLSTOP) {
            pos_pending_vol=OrderLots();
            pos_pending_ticket=OrderTicket();
            koment=OrderComment();
            //}
            }
          Print("Activ VOL: ",pos_active_vol,", Pend VOL: ",pos_pending_vol,", Activ TICKET: ",pos_active_ticket,", Pending TICKET: ",pos_pending_ticket," Komentarz: ",koment);
                    
      //}
      
      if((pos_pending_vol != vol(pos_active_vol)))
         {
         //OrderSelect(pos_pending_ticket,SELECT_BY_TICKET);
         OrderDelete(pos_pending_ticket);
         OrderPrint();
            Print("OrderDelete ostatni error jest: ",GetLastError() + ", A TICKETssss TO: " + DoubleToString(OrderTicket(),0));
         }         
      }    
   }   
   return(0);
}



// FUNKCJA WYLICZAJĄCA VOLUMEN DLA POZ. PRZECIWSTAWNEJ (zależnie od aktywnej na rynku)
double vol(double current_v)
{
   double vol_multiply;
   
   if(current_v>max_vol) 
      vol_multiply = NormalizeDouble(2*current_v,2);
      else 
      vol_multiply = NormalizeDouble(current_v+(current_v*oposite_order_volumen)/100,2);
   return(vol_multiply);
}


// PROCEDURA SPRAWDZENIA CZY ISTNIEJE JUŻ PRZECIWSTAWNE ZLECENIE
bool  czy_ticket_istnieje(string tick)
{
   string komentarz = "Kontra do zlecenia ";
   StringAdd(komentarz,tick);
   for(int m=0;m<OrdersTotal();m++)
   {
      if(OrderSelect(m,SELECT_BY_POS)==True)
      if(OrderComment()==komentarz)
      {
         Print("Zlecenie istnieje: "+OrderComment()+" z ticketem: "+tick + komentarz   );
         return(True);
         break;
      }
      else
      {  Print("Chyba brak zlecenia - "+komentarz);
         return(false);
         break;
      }   
   
   }  
   
   if(OrderSelect(tick,SELECT_BY_TICKET)==True)
   {Print("Wybrano ticketaaaaaaa: ",tick); }
}
kolejne stopnie na schodach wytrwałości....

EAForex
Bywalec
Bywalec
Posty: 19
Rejestracja: 10 gru 2014, 15:04

Re: Automatyczna pozycja przeciwstawna do każdego otwartego

Nieprzeczytany post autor: EAForex »

0.Dla każdej pary zleceń ustalasz osobny Magic number.
1.Przy inicjacji utwórz tablicę w której będziesz "wiązał" zlecenia oryginalne z przeciwstawnymi.
2.Przy każdym ticku sprawdzasz czy wszystkie zlecenia zapisane w tablicy istnieją:
2a.Jeżeli któreś nie istnieje to usuwasz również przeciwstawne.
2b.Przy każdym nowym zleceniu dodajesz nowy element do tablicy z odpowiednim komentarzem.

Awatar użytkownika
hienas
Stały bywalec
Stały bywalec
Posty: 30
Rejestracja: 27 cze 2007, 16:25

Re: Automatyczna pozycja przeciwstawna do każdego otwartego

Nieprzeczytany post autor: hienas »

EAForex pisze:0.Dla każdej pary zleceń ustalasz osobny Magic number.
1.Przy inicjacji utwórz tablicę w której będziesz "wiązał" zlecenia oryginalne z przeciwstawnymi.
(...)
MagicNumbers to dla mnie trochę magia :shock: , a tablice to muszę chyba jednak opanować dopiero....
kolejne stopnie na schodach wytrwałości....

ODPOWIEDZ