Открытие i+20 - страница 6

 
Vlad143:
Не пойму, зачем перебирать все ордера, если номер тикета нужного ордера уже известен. Объясните?

Затем, что номер тикета не всегда известен, это действует только для простейших советников с линейной архитектурой и парой десятков срочек кода, где после OrderSend() сразу же следует OrderModify().

Тикет у вас правильный будет до первого крэша или перезагрузки терминала, или до первого же применения OrderSelect() к другому ордеру где-то дальше по коду.

 
EugenioKP1983:

А вот теперь реальная задача.

Сейчас вхожу в рынок по Аску и тейк отщитываю от 1 свечи

Вот Пример

                normalizaTP = NormalizeDouble(Low[1] +(((int)zero_BE)*TP_Multiplayer_Buy)*_Point,5);/*PriceOpen_Buy Профит фактор 1/ к 3**/
                normalizeSL = NormalizeDouble(Low[1] -((((int)zero_BE)*SL_Multiplayer_Buy)/2)*_Point,5);
                RefreshRates();            

                ticketBuy = OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,normalizeSL,normalizaTP,"",Magic,0,clrGreen);


Значения для расчета у меня даны все раз в цикл так как уже при следующем перещете

zero_BE и TP_Multiplayer_Buy и SL_Multiplayer_Buy уже получают другое значение.

Вывод

Если сразу в коде после открытия ордера вставить функцию По OrderModify то не факт что сработает так как отдача от сервера может повлиять и советник получит ещо не открытую позициу.



Выход1. Поставить Паузу - если такая функция есть.Между оформлением позы и модификацией 

Выход 2. Записать normalizaTP и normalizeSL в Глобальные переменные и уже после перещета оперируя с ними устанавливать стоп и тейк от OrderOpenPrice. Что в сути намного лучше и чище нежели от Свечи 1

Как лучше посоветуйте

 Нету "лучше", оба решения могут применяться вместе. OrderModify() лучше применять на следующем тике или позже, после паузы.

1. Пауза - Sleep(milliseconds); после успешного OrderSend() можно сделать паузу в 1-5 секунд, зависит от скорости исполнения конкретного сервера.  Кроме Sleep(), можно использовать таймеры или в OnTick() организовать счётчики тиков.

2. OrderSelect() выдает цену открытия нужного ордера в любое время, глобальные переменные тут не нужны.

 
kstar1:
if не стал писать, думал понятно, что это проверка условия.
Почему занудство? Я и не знал, что к PeriodSeconds (он же вроде int), прибавлять datetime можно. Компилятор выдал предупреждение , вот я и стал к int все приводить. Убрал TimeSeconds и все заработало. Только советник теперь ордера открывает по истечении трех баров, хотя оба сигнала образовались еще на "первом". Понятно, что я где-то логику нарушил, но и писал её лишбы запустить. 
У меня другой вопрос. Я выше писал логику своей ТС. Если я поиск первого сигнала делаю так:
if (Signal_1 || Signal_2 == buy)
то как мне для поиска второго сигнала, который только один изних, определить какой из них сработал, чтобы проверять уже другой?
Надеюсь, понятно написал))
Или придется каждую пару отдельно проверять?




Организуйте счётчики отдельно для каждого сигнала и обнуляйте их после открфтиф позиции.
 
evillive:
Организуйте счётчики отдельно для каждого сигнала и обнуляйте их после открфтиф позиции.

А по-подробнее...А если флажками?
 
evillive:

Затем, что номер тикета не всегда известен, это действует только для простейших советников с линейной архитектурой и парой десятков срочек кода, где после OrderSend() сразу же следует OrderModify().

Тикет у вас правильный будет до первого крэша или перезагрузки терминала, или до первого же применения OrderSelect() к другому ордеру где-то дальше по коду.

Приняли результат OrderSend в переменную NewTicket. Больше нигде в коде она значение не получает. К моменту вызова OrderModify в теле той же функции ее значение прежнее. Причем здесь вызовы OrderSelect в дальнейшем -  не пойму.

Говоря о крешах и перезагрузках терминала, как я догадываюсь, Вы имеете в виду прекращение работы советника, корректное или нет. В том числе от сбоя электропитания, случайного нажатия на крестик окна терминала или окна графика с советником. Это что, действительно важно? Я отношусь к этим вещам как к форс-мажору. И, конечно, вручную проверяю, что там произошло со сделками. Ведь за время, пока советник не работал, могло потребоваться закрытие каких-то сделок. Неужели надо писать автомат, который сам разберется с любым окружением, включая возникшее после длительного перерыва в его работе... Обрабатывать разрывы связи, наверное, как-то стоит. Ведь сам -то советник при этом продолжает работать. Но сбои электропитания и прочие случайности, мне кажется, слишком сложно.

Есть еще вопрос. О линейной архитектуре. Как я думаю, советник работает в один поток, никакой параллелизм невозможен. Если функция начала работать, до выхода из нее никакая другая (из этого же советника) работать не будет, кроме вызванных ей. Правильно я понимаю?

 
kstar1:

А по-подробнее...А если флажками?

Если один сигнал приходит - флажком ещё можно, ну несколько сигналов по одному разу - тоже флажки, по одному отдельно для каждого. Но вот пришел сигнал второй раз, а флажок-то уже поднят. При повторениях удобней считать эти повторения, не так разве?

Но, допустим, сигналы всё же под одному разу учитываем, первый сигнал пришел - поднимем первый флажок и считаем время ожидания. Второй сигнал пришел и прошло сколько надо времени - торгуем, флажки сбрасываем. Ну это очень упрощенно, естественно в реальном коде куча проверок ещё нужна, особенно во время отладки.

 

bool sign1=false, sign2=false;
datetime timewait=0, timelimit=0;

void OnTick()
{

if(signal1) {timewait=TimeCurrent()+PeriodSeconds()*3; timelimit=TimeCurrent()+PeriodSeconds()*4; sign1=true;}
if(signal2 && (TimeCurrent()>=timewait && TimeCurrent()<timelimit) sign2=true;
if(sign1 && sign2) { trade; sign1=false; sign2=false;}

}
 

Со своей богодельней разобрался, пришлось кусками кд проверять во всех направления чтоб выявить проблему. Решил задачу GV переменными. Записываю туда конкретные значения а после модифицирую ордер.


Тут вот идея пришла создать утилитку сумирующую тейкпрофит по Истории робота и занося в GV переменную для  хранения. Задачю поставил себе а реализацию пока додумать не могу.


Начал вот отсюда


//+------------------------------------------------------------------+
//|                                             История_Миллиона.mq4 |
//|                                             Yevheniy Kopanitskyy |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Yevheniy Kopanitskyy"
#property link      "https://forexrobot.es"
#property version   "1.00"
#property strict


int i;
int N_Last_Order;
double Orderprofit;
string NLast_Order="NLast_Order";
string Total="Total";
double Calc;
double Gettotal;


 //+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  
  
  
if(IsNewBar)//Номер тикета больше чем номер прошлого тикета.
{ 
  i=GlobalVariableGet(N_Last_Order);
 if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)//21
   {
   for(int i = N_Last_Order; i < OrderTicket(); i++) //25,
   {
       if(OrderMagicNumber()== Magic && OrderType() == OP_SELL || OrderType() == OP_BUY)//если используется магик
     {
        Orderprofit == OrderProfit();
         if(Orderprofitz >0)
       {
         Gettotal = GlobalVariableGet(Total); 
         Calc= Gettotal+Orderprofit);
         GlobalVariableSet(Total,Calc);
         GlobalVariableSet(NLast_Order,N_Last_Order);
         
       }              
       
       if(GetLastError()==0)
        {
        Print("ошибка");
         } 
      
      }
   }
 }
}
   
  }
//+------------------------------------------------------------------+
/*--------------------------------------------------------*/
bool IsNewBar() /*Новый Бар*/
 {
  static int nBars = 0;
  if (nBars == 0) 
   {
    nBars = Bars;
    return(false);
   }
  if (nBars != Bars)
   {
    nBars = Bars;
    return(true);
   }
  return(false);
 }
/*---------------------*/



Пока для теста перещёт  поставил от нового бара.

Шаг 1 Присваиваю индексу номер последнего ордера, зацикливание будет через GV переменную

Шаг 2. Выборка из истории по номеру тикета.

Шаг 3. ВОт здесь думаю сделать цикл на получение номера ордера по параметру

OrderTicket()

Если не правильно думаю подскажите.

Шаг 4 Если получаю ордер проверяю на магик на вид ордера и

Шаг 5 получаю тейкпрофит из ордера

Далее вывожы всё в GV

Причина обращения: