Qualsiasi domanda da principiante, per non ingombrare il forum. Professionisti, non passate oltre. Da nessuna parte senza di te - 6. - pagina 103

 
hoz:

Se sono le 7.43 e non sono andato a letto... Quindi credo che si scriva graal!

No, non c'è bisogno di imprecare così :)) Yusuf mi ha dato il Graal. Sono seduto nelle mie valigie, aspettando la manna dal cielo, andando alle Maldive :))

 
artmedia70:
Quindi mostratemi cosa avete fatto... Nessun telepate qui - sono in vacanza.

extern string time1 = "n";// 
extern string time2="m";
extern double lot=0.2;// объявили лот
extern int slippage=2;// объявили макс отклонение от цены





int start()
{
double max;// максимальная цена 6-ти свечей
double min;// минимальная цена 6-ти свечей
int hour1 = TimeHour(StrToTime(time1)); // время часы
int minute1 = TimeMinute(StrToTime(time1));// время минуты


if (hour1 == TimeHour(TimeCurrent()) && minute1 == TimeMinute(TimeCurrent()))// если время подошло то
{
min=Low[iLowest(Symbol(),0,MODE_LOW,6,1)]; // вычисляем минимальную цену последних 6 свечей
max=High[iHighest(Symbol(),0,MODE_HIGH,6,1)]; // вычисляем максимальную цену последних 6 свечей
double volum=max-min;// общий объем локалки последних 6 свечей М5
 int ticket1=-1;
 int ticket2=-1;
if ((volum<=0.0018)==true)// если объем свечей меньше или равно z пунктов 

if (ticket1<0)
{ 
OrderSend ( Symbol (), OP_BUYSTOP, lot,max+Point,3,min-Point,max+0.0022, NULL,0,time2, Red);
Alert(GetLastError());
}
if(ticket2<0)
{
OrderSend( Symbol (), OP_SELLSTOP, lot,min-Point,3,max+Point,min-0.0022, NULL,0,time2, Yellow);
Alert(GetLastError());
}


return;


if (OrderSelect(1,SELECT_BY_POS,MODE_HISTORY)) ///если первый открытый ордер закрылся с профитом 
if(OrderProfit()>0)
{
OrderDelete(OrderTicket());// удаляем второй отложенный
}

}



bool closeorder;//определим переменную закрытия ордеров
closeorder=true;

if (closeorder==true)// вечернее закрытие всех отложенных ордеров, и рыночных позиций
{
int hour2 = TimeHour(StrToTime(time2));// вычисляем время закрытия ордеров
int minute2 = TimeMinute(StrToTime(time2));

if (hour2 == TimeHour(TimeCurrent()) && minute2 == TimeMinute(TimeCurrent()))// если время ***
{// определяем количество открытых позиций, и отложенных ордеров
for(int i=OrdersTotal()-1; i>=0; i--)
 if (OrderSelect(1,SELECT_BY_POS,MODE_TRADES))break; //определяем место где будем искать ( рабочие позиции)
if (OrderType()==OP_BUY ) OrderClose (OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),slippage);// Закрытие ордера бай если такой есть
if (OrderType()==OP_SELL) OrderClose (OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),slippage);//Закрытие ордера селл если такой есть
if (OrderType()==OP_BUYSTOP)
{ 
OrderDelete(OrderTicket()); //удаляем отложенный байстоп
}                    
if(OrderType()==OP_SELLSTOP)
{ 
OrderDelete(OrderTicket()); //удаляем отложенный sellstop
}                    

Ho caricato il codice generale dell'Expert Advisor, per rendere più chiaro cosa dovrebbe fare... So che è un casino, ma non ho ancora imparato altrimenti =)))
Vi dirò ancora una volta dove è stupido
aprire un ordine pendente: apre un ordine pendente senza quello opposto o un intero gruppo di ordini pendenti in una direzione.
Cancella gli ordini: a volte ok la sera ad un'ora chiaramente specificata, e a volte in un giorno, o non chiude affatto...

Beh, la condizione è :
Se il primo ordine pendente aperto si chiude con un profitto, il secondo viene cancellato immediatamente - dubito di averlo scritto correttamente, ma non posso verificarlo in azione perché non voglio aprire due posizioni opposte=(((((
 
artmedia70:
Quando si cerca l'ultimo ordine chiuso, dovremmo prima trovare l'ultimo chiuso, ma il controllo della chiusura al take dovrebbe essere tolto dal ciclo, altrimenti controllerà la chiusura al take per ogni ordine chiuso e, se è così, ricorderà il tempo del primo ordine chiuso al take nel ciclo e non l'ultimo.


Beh, questa è l'ottimizzazione del codice. Il risultato non cambierà, per come la vedo io. Ci vuole solo più tempo per calcolare. Ho corretto il codice, ma è ancora lo stesso.

//+-------------------------------------------------------------------------------------+
//| Получаем состояние последней позиции (Открыта или закрыта)                          |
//+-------------------------------------------------------------------------------------+
datetime GetLastOrderState()
{
   datetime lastOrderCloseTime = -1,               // Время закрытия последнего открытого ордера
            lastOOTMarket = -1,          // Время открытия последнего открытого ордера рыночного
            lastOOTHist = -1;            // Время открытия последнего открытого ордера из истории
   
   for (int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderType() > 1) continue;               // Все удалённые отложки нас не интересуют..
  
      if (lastOrderCloseTime < OrderCloseTime())   // Находим время закрытия..
          lastOrderCloseTime = OrderCloseTime();   // ..последней закрытой позиции в истории
      Comment("Время закрытия последнего ордера в истории lastOrderCloseTime = ", lastOrderCloseTime);
   }

   if (MathAbs(OrderTakeProfit() - OrderOpenPrice()) < i_tp * pt) return(0);
      Comment("OrderTakeProfit() - OrderOpenPrice() < i_tp * pt = ", MathAbs(OrderTakeProfit() - OrderOpenPrice()) < i_tp * pt);
   lastOOTHist = OrderOpenTime();   // Тогда время открытия последней закрытой позиции из истории
      Comment("Время закрытия последнего ордера в истории lastOOTHist = ", lastOOTHist);
   
      Comment("Время открытия последнего открытого ордера = ", lastOOTHist);
  
   for (int h=OrdersTotal()-1; i>=0; i--)
   {   
      if (!OrderSelect(h, SELECT_BY_POS, MODE_TRADES)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      {
         if (lastOOTMarket < OrderOpenTime())
             lastOOTMarket = OrderOpenTime();
  
         if (lastOOTMarket < lastOOTHist)      // Если время открытия последнего открытого ордера (рыночного) ниже последнего открытого ордера из истории..
             lastOrderCloseTime = OrderCloseTime(); // Значит это искомый ордер
      }
   }

   Comment("Время закрытия последнего открытого ордера = ", lastOrderCloseTime);
   return (lastOrderCloseTime);
}

Eppure, c'è qualcosa che non va.

 
ex1m:

Ho cercato di mostrarvi il codice di un EA, so che è un casino, ma non ho mai imparato a farlo in modo diverso)))
Vi dirò ancora una volta dove è stupido
Aprire ordini pendenti: apre o un ordine pendente senza quello opposto o un intero gruppo di ordini pendenti in una direzione.
Cancellazione degli ordini: li cancella ogni volta, a volte ok la sera ad un'ora chiaramente specificata, e a volte in un giorno, o non li chiude affatto...

Bene, la condizione:
Se il primo ordine pendente aperto si chiude con un profitto, il secondo sarà cancellato immediatamente - dubito anche di averlo scritto correttamente, ma non posso controllare nel lavoro, perché non voglio aprire due posizioni opposte=(((((



Rispondere a una domanda con una domanda. Che diavolo è quello:

if ((volum<=0.0018)==true)// если объем свечей меньше или равно z пунктов 

Decifralo per me, non capisco :)

I controlli per aprire una posizione dovrebbero avvenire dopo il tentativo di aprire una posizione. Cioè

if (ticket1<0)

Lo metti dopo aver inviato un ordine.

Il prezzo deve essere superiore o inferiore all'Asc o al Bid per aprire la posizione. È così per il Buy:

 if (OOP > Ask)
 
hoz:


Beh, questa è l'ottimizzazione del codice. Il risultato non cambierà, per come la vedo io. Ci vuole solo più tempo per calcolare. Ho corretto il codice, ma è ancora lo stesso.

C'è ancora qualcosa che non va.

No, non è l'ottimizzazione del codice. Sta solo cercando esattamente l'ultimo. Una volta che abbiamo completato la ricerca di tutti gli ordini chiusi e trovato l'ultimo ordine chiuso di essi, solo allora dovremmo controllare la chiusura da parte del take e, se è chiuso dal take, solo allora ha senso continuare a cercare il resto.

Se controlliamo se c'è una chiusura all'interno del ciclo, cosa otterremo? Otterremo un errore di logica:
Supponiamo di aver selezionato un ordine che è stato chiuso un anno fa. Il suo tempo sarà comunque superiore a -1, quindi lo controlliamo per chiuderlo al take (viene controllato all'interno del ciclo). Sì, si è chiuso sulla presa... Cosa fa la tua funzione dopo? Giusto - continua a funzionare con quell' ordine chiuso al segno un anno fa. Fammi vedere cos'altro c'è che non va. Appena arrivato a casa...

 

Era scritto: 2. Se l'ultima posizione aperta si chiude al take, allora chiudete tutto!

Quindi, va così:

//-----------------------------------------------------------------------------------------------+
bool isCloseByTakeLastOpenPos (string sy, int mn, int delta) {
   datetime t=0;
   int   i, k, j=-1;
   
// Сначала определим, что последняя закрытая позиция была закрыта по тейку (в пределах дельты)
   k=OrdersHistoryTotal()-1;
   for(i=k; i>=0; i--) {
      if (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) {
         if (OrderMagicNumber()!=mn)   continue;
         if (OrderSymbol()!=sy)        continue;
         if (OrderType()>1)            continue;            // Сначала забыл вписать, подправил
         if (t<OrderCloseTime()) {t=OrderCloseTime(); j=i;}
         }
      }  
   // Нашли последнюю. Проверим её закрытие по тейку
   if (OrderSelect(j,SELECT_BY_POS,MODE_HISTORY)) {                      
      if (OrderProfit()+OrderSwap()+OrderCommission()<=0)   return(false);          // Закрыта с убытком или в ноль
      if (MathAbs(OrderTakeProfit()-OrderClosePrice())>delta*Point) return(false);  // закрыта в профите, но не в пределах дельты
      else t=OrderOpenTime();    // Если последняя закрытая была закрыта по тейку (в пределах дельты), запомним время её открытия
      }
   else {Print("FUNC isCloseByTakeLastOpenPos : не удалось выбрать ордер в истории");return(false);}
// Здесь мы имеем последнюю закрытую позицию в профите и закрытую по тейку (в пределах дельты), ищем дальше
   k=OrdersTotal()-1;
   for(i=k; i>=0; i--) {
      if (OrderSelect(i,SELECT_BY_POS)) {
         if (OrderMagicNumber()!=mn)   continue;
         if (OrderSymbol()!=sy)        continue;
         if (OrderType()>1)            continue;
         if (t<OrderOpenTime()) return(false);  // Выбранная рыночная позиция открыта позже закрытой по тейку
         }
      else {Print("FUNC isCloseByTakeLastOpenPos : не удалось выбрать рыночный ордер");return(false);}
      }
   return(true);  // Найденная закрытая по тейку позиция была открыта позже всех, возвращаем её время открытия
}
//-----------------------------------------------------------------------------------------------+

Passiamo alla funzione il simbolo che vogliamo controllare, il numero magico e il delta (distanza in pip == differenza tra il prezzo di acquisto e il prezzo di chiusura dell'ordine), come questo:

   if (isCloseByTakeLastOpenPos (Symbol(), Magic, 5)) { // Если последняя открытая была закрыта по тейку ...
      // ... тут обрабатываем эту ситуёвину
      }
   else {   // Иначе ...
      // тут обрабатываем, если последняя закрытая была открыта не последней или ...
      // ... последняя закрытая была закрыта с убытком или в профите, но за пределами дельты
      }

Non ho controllato questa funzione, l'ho scritta di mio pugno. Quindi, lascerò a voi la ricerca degli errori.

Potete renderlo int e usare i codici di ritorno. Per esempio, se la posizione che state cercando non esiste o esiste, ma è chiusa con una perdita, ritorna -1;
se esiste ed è chiusa con un profitto, ma non entro il delta, ritorna 0;
se esiste ed è chiusa con un profitto e al Take (entro il delta), ritorna 1...

Lo spazio per l'immaginazione è enorme...

 
artmedia70:

Se, d'altra parte, controlliamo la chiusura della presa, cosa otteniamo? Otterremo un errore logico:

Supponiamo di aver selezionato un ordine che è stato chiuso un anno fa. Il suo tempo sarà comunque superiore a -1, quindi lo controlliamo per chiuderlo alla ripresa (è questo controllo all'interno del ciclo). Sì, si è chiuso sulla presa...


Quindi, se facciamo un ciclo su tutti gli ordini, il ciclo si svolgerà comunque attraverso tutti gli ordini. L'ora di chiusura di ogni ordine sarà confrontata con quella selezionata in precedenza. Ma è qui che ci troviamo di fronte a un problema di prestazioni. TakeProfit sarà costantemente controllato nel ciclo, con ogni posizione chiusa, invece che solo l'ultima. Non è così?
 
PapaYozh:

Giusto.

Ma c'è Open[], con un prezzo di apertura.


Capito, grazie :)
 
hoz:

Quindi, se si fa un ciclo su tutti gli ordini, il ciclo sarà in ogni caso un ciclo su tutti gli ordini. Il tempo di chiusura di ogni ordine sarà confrontato con quello precedente selezionato. Ma è qui che ci troviamo di fronte a un problema di prestazioni. TakeProfit sarà costantemente controllato nel ciclo, con ogni posizione chiusa, invece che solo l'ultima. Non è così?
Ho già scritto un esempio della funzione.
 
hoz:

Quindi, se facciamo un ciclo su tutti gli ordini, il ciclo lo farà comunque su tutti gli ordini. L'orario di chiusura di ogni ordine sarà confrontato con quello precedente selezionato. Ma qui abbiamo un problema di prestazioni. TakeProfit sarà costantemente controllato nel ciclo, con ogni posizione chiusa, invece che solo l'ultima. Non è così?

Questo è un problema tecnico:

   for (int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderType() > 1) continue;               // Все удалённые отложки нас не интересуют.. 
  
      if (lastOrderCloseTime < OrderCloseTime())   // Находим время закрытия..
          lastOrderCloseTime = OrderCloseTime();   // ..последней закрытой позиции в истории
      
      if (MathAbs(OrderTakeProfit() - OrderOpenPrice()) < i_tp * pt) return(0); // ЗДЕСЬ ВЫХОДИМ ПРИ ПЕРВОМ ВСТРЕЧНОМ
      
      lastOOTHist = OrderOpenTime();   // Тогда время открытия последней закрытой позиции из истории
   }
Motivazione: