Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Следи за новостями. Заходи на официальный канал нашей компании!
Pirat
251
Pirat 2011.04.09 01:04 

Здравствуйте уважаемые форумчане.

Необходимо написать функцию для удаления отложников при изменении лота.

Лот изменяется следующей функцией

extern double Lots = 0.1;
extern int     Kloss           =      1;
extern double  MultiplierLoss  =      2.0;


void OpenOrder() {

Lot =  KillaLoss();

.....

}


double KillaLoss(){
// -----
int Loss;
// -----
int orders=OrdersHistoryTotal();
  
double Lot=Lots;

   if(Kloss>0){

// ---- Считаем кол-во лоссов
      
      for (int i = orders - 1; i >= 0; i--) {
         if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) == FALSE) {
            Print("Ошибка в истории!");
            break;
         }
         if (OrderSymbol()!= Symbol() || OrderType() > OP_SELL) continue;
         if (OrderMagicNumber()!=MAGIC_NUMBER) continue;
         if (OrderProfit() > 0.0) break;
         if (OrderProfit() < 0.0) Loss++;
         }

// ---- Выставляем новый объём

       if(Loss>=Kloss) {
       
       Lot=Loss*MultiplierLoss*Lot;
      
       }
       
    } //--end if(Kloss>0){    
// -----

 return(Lot);
}


Дело в том что у меня тс построена на отложниках, и новый объем сделки применяется только к вновь открытым отложникам. Старые приходится удалять вручную.

Функция должна отслеживать объём лота, и при его изменении удалять отложники 1 раз (у меня получается ток с зацикленным удалением:) )

Также, если можно хотелось бы просто доработать KillaLoss, чтобы удаляло отложники если случился лосс. Так было бы намного лучше.

P.S.

Пытался сделать так, но не вышло:

void OpenOrder()
//+------------------------------------------------------------------+
{
   lot =   KillaLoss();
   
   if (lot>Lots) CloseLimit();
.....

void CloseLimit() {
   int LimitErrorForClose; // Получение информации об ошибке, GetLastError(), для данной функции
   int LimitDelete;     // Удаление отложников в данной функции
   int CountCloseLimit = 0; // Счетчик для попыток удаления отложников
   while (true) {
      if (OrderMagicNumber() == MAGIC_NUMBER && OrderSymbol() == Symbol()) LimitDelete = OrderDelete(OrderTicket());
      LimitErrorForClose = GetLastError();
      if (LimitErrorForClose == 0/* NO_ERROR */) {
         Print("Close Limit Order. Лимит ордер закрыт");
         return;
      }
      Print("Не могу закрыть лимит ордер по символу ", Symbol(), " Ошибка № ", GetLastError());
      Sleep(500);
      RefreshRates();
      CountCloseLimit++;
      if (CountCloseLimit <= 25) continue;
      break;
   }
   Alert("Order failed to CLOSE - See Journal for errors");
}

Заранее спасибо за помощь.

Alexander
2441
Alexander 2011.04.09 01:19  

Замените

int CountCloseLimit = 0; // Счетчик для попыток удаления отложников
   while (true) {

На

int CountCloseLimit = 0; // Счетчик для попыток удаления отложников
for(int i=OrdersTotal()-1;i>=0;i--)
{
OrderSelect(i,SELECT_BY_POS);   
while (true) {

и после алерта еще одну закрывающую скобку

И еще, замените return; на continue;

Pirat
251
Pirat 2011.04.09 13:16  
Спасибо за помощь, работает. Но теперь остаются отложники большего объёма уже после того как сделка была закрыта в +. То есть был лос, отложники удалились, и лот выставился удвоенный, далее был тейк и лот у ордеров должен стать прежним, но по правилу они удаляются только если новый лот больше текущего
if (lot>Lots) CloseLimit();

То есть после тейка остаются висеть удвоенные отложники.

Если сделать так

if (lot>Lots || lot<Lots) CloseLimit();

то будет бесконечный цикл удаления.

То есть, теперь нужна функция, которая бы удаляла отложники при запуске терминала и, если ордер был закрыт в тейк или лосс, то есть сразу после срабатывания стоп ордера тейка или лосса.


Заранее спасибо за помощь.

Pirat
251
Pirat 2011.04.09 18:29  
Написал сейчас функцию на основе KillaLoss, но всё равно получается бесконечное зацикливание по удалению отложников после первого ордера.
Pirat
251
Pirat 2011.04.10 13:07  

По прежнему проблема актуальна...

Прошу помочь

Pirat
251
Pirat 2011.04.10 16:14  

Скажу в двух словах, так думаю проще было)

Ордер закрылся по стоп-лоссу (по траллу) или тейку (не виртуальные), далее нужно чтобы удалились отложники.

Вот нужна функция которая бы удаляла отложники после закрытия ордера.

Pirat
251
Pirat 2011.04.10 17:56  

проблем с установкой ордеров нет. Единственно что нужно

>>>

нужна функция которая бы удаляла отложники после закрытия ордера.

Видимо я как-то не так объясняю. Попробую заново объяснить.

Советник выставлять отложенные ордера, например 4 ордера на OP_BUYLIMIT. Для каждого ордера установлены уровни тейка и стопа.

Допустим цена зацепила 1 ордер, и он закрылся по тейку.

(!) Далее необходимо чтобы остальные 3 отложенные ордера OP_BUYLIMIT удались.

Вот нужна функция которая бы удаляла отложники после закрытия ордера.

>>>

Далее, если вести учет открытых ордеров функцией CalculateOrd

if(CalculateOrd(OP_BUY)==0) CloseDelete(OP_BUYLIMIT);
if(CalculateOrd(OP_SELL)==0) CloseDelete(OP_SELLLIMIT);

Не приведет ли это к зацикливанию и бесконечному удалению отложников?

Pirat
251
Pirat 2011.04.10 18:00  

То есть, нужна функция, которая бы удаляла отложники при запуске терминала и, если ордер был закрыт в тейк или лосс, то есть сразу после срабатывания стоп ордера тейка или лосса.

А если использовать

if(CalculateOrd(OP_BUY)==0) CloseDelete(OP_BUYLIMIT);

То будет бесконечное зацикливание - ордера будут выставляться и сразу удаляться.

Pirat
251
Pirat 2011.04.10 18:12  

Можно сделать например удаление отложников, если будет открыт ордер, например так:

if(OrdersCount(OP_SELL,MagicNumber)==1)DeleteOrders(OP_BUYSTOP, MagicNumber);
if(OrdersCount(OP_BUY,MagicNumber)==1)DeleteOrders(OP_SELLSTOP, MagicNumber);

//+----

int OrdersCount(int type, int mn)
{
//+----
  int orders=0;
  int cnt=OrdersTotal();
  for (int i=0; i<cnt; i++) {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol()!=Symbol()) continue;
    if (OrderMagicNumber()!=mn) continue;
    if (OrderType()==type||type<0) orders++;
  }
//+----
  return (orders);
}

void DeleteOrders(int op=-1, int mn=-1) {
  bool fd;
  int  i, it, k=OrdersTotal();
  for (i=k-1; i>=0; i--) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
        if (OrderSymbol()==Symbol() && OrderType()==op) {
          if (OrderMagicNumber()==mn) {
            for (it=1; it<=5; it++) {
              if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
              while (!IsTradeAllowed()) Sleep(5000);
              fd=OrderDelete(OrderTicket(), 0);
              if (fd) { PlaySound("ok.wav"); break;
              Sleep(1000*5);
            }
          }
        }
      }
    }
  }
  return(0);
}

Но как сделать чтобы происходило удаление при запуске терминала + если ордер был закрыт по тейку или лоссу. Далее они сами выставятся новые.

Pirat
251
Pirat 2011.04.10 19:43  

А, может я не так написал опять. Всмысле чтобы он 1 раз удалил их и всё (при запуске терминала и если ордер был закрыт по тейку или лоссу), без цикла, разовая процедура, всё равно что удалять скриптом.

Просто лот же нельзя другой выставлять у отложников (модифицировать), вот из-за этого такие трудности.

Alexander
2441
Alexander 2011.04.10 20:27  

После каждого изменения лота проверяйте увеличился или нет и запоминайте его размер в глобальной или статической переменной. Если увеличился, идем на удаление.

/ /12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий