Полезные функции от KimIV - страница 118

 
borilunad:
Это то, да не то, много лишних вызовов других функций с вытекающими ошибками!

Ну, ошибки-то уже вы наделали...

Там всё просто и наглядно: правьте под себя как нужно.

 
KimIV:


По аналогии с этой можете что-нибудь изобразить...

update...

Во вложении скрипт для тестирования функции ExistOPNearPrice()

Сделал, не знаю правильно ли.

//+----------------------------------------------------------------------------+
//|  Описание : Возвращает флаг существования позиции или ордера в заданном    | 
//|           : диапазоне от заданной цены                                     |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента        ("" или NULL - текущий символ)     |
//|    op - торговая операция               (    -1      - любая операция)     |
//|    mn - MagicNumber                     (    -1      - любой магик)        |
//|    price - заданная цена                (    -1 - текущая цена рынка       |  
//|    ds - расстояние в пунктах от цены    (  1000000   - по умолчанию)       |
//+----------------------------------------------------------------------------+
bool ExistOPNearMarkets(string sy="", int op=-1, int mn=-1, double price = -1, int ds=1000000) {
  int i, k=OrdersTotal(), ot;

  if (sy=="" || sy=="0") sy=Symbol();
  double p=MarketInfo(sy, MODE_POINT);
  if (p==0) if (StringFind(sy, "JPY")<0) p=0.00001; else p=0.001;
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      ot=OrderType();
      if (OrderSymbol()==sy) {
        if (mn<0 || OrderMagicNumber()==mn) {
          if (op==OP_BUY && (ot==OP_BUY || ot==OP_BUYLIMIT || ot==OP_BUYSTOP)) {
            if ((price<0 && MathAbs(MarketInfo(sy, MODE_ASK)-OrderOpenPrice())<ds*p) ||
                (price>0 && MathAbs(price-OrderOpenPrice())<ds*p)) 
               {
                return(True);
               }
          }
          if (op==OP_SELL && (ot==OP_SELL || ot==OP_SELLLIMIT || ot==OP_SELLSTOP)) {
            if ((price<0 && MathAbs(OrderOpenPrice()-MarketInfo(sy, MODE_BID))<ds*p) ||
                (price>0 && MathAbs(OrderOpenPrice()-price)<ds*p)) 
               {
                return(True);
               }
          }
        }
      }
    }
  }
  return(False);
}
 
artmedia70:

Ну, ошибки-то уже вы наделали...

Там всё просто и наглядно: правьте под себя как нужно.

Спасибо! Да уже обошёлся другими приёмами.
 
khorosh:

Сделал, не знаю правильно ли.

Вроде как да, правильно... универсально получилось )))
 

CorrectingPrice().


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

Функция CorrectingPrice() предназначена для корректировки основных ценовых уровней ордеров и позиций под требование STOPLEVEL ещё до отправки торговой заявки на сервер, то есть на этапе подготовки исходных данных.

Все параметры функции являются обязательными, умолчательных значений нет. Кроме того, последние три параметра передаются по ссылке, то есть в них же будет лежать результат работы функции. Функция принимает следующие параметры:
  • sy - Наименование торгового инструмента. Пустое значение "" или NULL будет означать текущий торговый инструмент (символ).
  • op - Торговая операция. Допустимыми являются следующие значения: OP_BUY, OP_SELL, OP_BUYLIMIT, OP_SELLLIMIT, OP_BUYSTOP и OP_SELLSTOP.
  • pp - Цена открытия/установки позиции/ордера.
  • sl - Ценовой уровень StopLoss.
  • tp - Ценовой уровень TakeProfit.
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 02.07.2013                                                     |
//|  Описание : Выполняет корректирование ценовых уровней под STOPLEVEL.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование торгового инструмента                                 |
//|    op - торговая операция                                                  |
//|    pp - цена открытия/установки                                            |
//|    sl - ценовой уровень StopLoss                                           |
//|    tp - ценовой уровень TakeProfit                                         |
//+----------------------------------------------------------------------------+
void CorrectingPrice(string sy, int op, double& pp, double& sl, double& tp) {
  if (sy=="" || sy=="0") sy=Symbol();
  RefreshRates();
  int    di=MarketInfo(sy, MODE_DIGITS);
  int   msl=MarketInfo(sy, MODE_STOPLEVEL);
  int    sp=MarketInfo(sy, MODE_SPREAD);
  double mp=MarketInfo(sy, MODE_POINT);
  double pa=MarketInfo(sy, MODE_ASK);
  double pb=MarketInfo(sy, MODE_BID);
  double ds=NormalizeDouble(pp-sl, di);
  double dp=NormalizeDouble(pp-tp, di);

  if (msl==0) msl=2*sp;
  switch (op) {
    case OP_BUY:
      pp=pa;
      sl=pp-ds;
      tp=NormalizeDouble(pp-dp, di);
      if (sl>pp-msl*mp) sl=pp-msl*mp;
      if (tp>0 && tp<pp+msl*mp) tp=pp+msl*mp;
      break;
    case OP_SELL:
      pp=pb;
      sl=NormalizeDouble(pp-ds, di);
      tp=pp-dp;
      if (sl>0 && sl<pp+msl*mp) sl=pp+msl*mp;
      if (tp>pp-msl*mp) tp=pp-msl*mp;
      break;
    case OP_BUYLIMIT:
      if (pp>pa-msl*mp) {
        pp=pa-msl*mp;
        sl=pp-ds;
        tp=NormalizeDouble(pp-dp, di);
      }
      if (sl>pp-msl*mp) sl=pp-msl*mp;
      if (tp>0 && tp<pp+msl*mp) tp=pp+msl*mp;
      break;
    case OP_BUYSTOP:
      if (pp<pa+msl*mp) {
        pp=pa+msl*mp;
        if (sl>0) sl=pp-ds;
        if (tp>0) tp=NormalizeDouble(pp-dp, di);
      }
      if (sl>pp-msl*mp) sl=pp-msl*mp;
      if (tp>0 && tp<pp+msl*mp) tp=pp+msl*mp;
      break;
    case OP_SELLLIMIT:
      if (pp<pb+msl*mp) {
        pp=pb+msl*mp;
        sl=NormalizeDouble(pp-ds, di);
        tp=pp-dp;
      }
      if (sl>0 && sl<pp+msl*mp) sl=pp+msl*mp;
      if (tp>pp-msl*mp) tp=pp-msl*mp;
      break;
    case OP_SELLSTOP:
      if (pp>pb-msl*mp) {
        pp=pb-msl*mp;
        sl=NormalizeDouble(pp-ds, di);
        tp=pp-dp;
      }
      if (sl>0 && sl<pp+msl*mp) sl=pp+msl*mp;
      if (tp>pp-msl*mp) tp=pp-msl*mp;
      break;
    default:
      Message("CorrectingPrice(): Неизвестная торговая операция!");
      break;
  }
}

 
KimIV:

CorrectingPrice().


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

Функция CorrectingPrice() предназначена для корректировки основных ценовых уровней ордеров и позиций под требование STOPLEVEL ещё до отправки торговой заявки на сервер, то есть на этапе подготовки исходных данных.

Все параметры функции являются обязательными, умолчательных значений нет. Кроме того, последние три параметра передаются по ссылке, то есть в них же будет лежать результат работы функции. Функция принимает следующие параметры:
  • sy - Наименование торгового инструмента. Пустое значение "" или NULL будет означать текущий торговый инструмент (символ).
  • op - Торговая операция. Допустимыми являются следующие значения: OP_BUY, OP_SELL, OP_BUYLIMIT, OP_SELLLIMIT, OP_BUYSTOP и OP_SELLSTOP.
  • pp - Цена открытия/установки позиции/ордера.
  • sl - Ценовой уровень StopLoss.
  • tp - Ценовой уровень TakeProfit.

Игорь, некоторые ДЦ сейчас вместо StopLevel, который имеет нулевое значение, используют Spread*2. Бегло просмотрев код, не заметил в нём проверки на эту ситуацию. Неплохо было бы подправить код для проверки такой ситуации, иначе - будут те же ошибки 130
 
artmedia70:
Игорь, некоторые ДЦ сейчас вместо StopLevel, который имеет нулевое значение, используют Spread*2. Бегло просмотрев код, не заметил в нём проверки на эту ситуацию. Неплохо было бы подправить код для проверки такой ситуации, иначе - будут те же ошибки 130


Артём, я не встречал таких ДЦ... Можете в личку скинуть пару штук? Почитаю торговые регламенты...

Или можно проще поступить. Сами мне скажите, достаточно ли корректно будет использовать такую поправку?

int   msl=MarketInfo(sy, MODE_STOPLEVEL);
int    sp=MarketInfo(sy, MODE_SPREAD);
if (msl==0) msl=2*sp;

 UPDATE: Внёс поправку в функцию CorrectingPrice().

 

Новая версия функции CorrectTF().

Меня как-то давненько критиковали за функцию CorrectTF(), что мол её функционал не соответствует заявленному. И, действительно, таймфрейм она подгоняет к ближайшему минимальному, а не просто к ближайшему. Я подсчитал средние арифметические значения между стандартными таймфреймами и переписал функцию под соответствие описанию.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 21.05.2013                                                     |
//|  Описание : Корректирует таймфрейм под ближайший поддерживаемый МТ4.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    TimeFrame - таймфрейм (количество минут).                               |
//+----------------------------------------------------------------------------+
int CorrectTF(int TimeFrame) {
  if (TimeFrame>     1 && TimeFrame<    3) return(PERIOD_M1);
  if (TimeFrame>=    3 && TimeFrame<   10) return(PERIOD_M5);
  if (TimeFrame>=   10 && TimeFrame<   23) return(PERIOD_M15);
  if (TimeFrame>=   23 && TimeFrame<   45) return(PERIOD_M30);
  if (TimeFrame>=   45 && TimeFrame<  150) return(PERIOD_H1);
  if (TimeFrame>=  150 && TimeFrame<  840) return(PERIOD_H4);
  if (TimeFrame>=  840 && TimeFrame< 5760) return(PERIOD_D1);
  if (TimeFrame>= 5760 && TimeFrame<26640) return(PERIOD_W1);
  if (TimeFrame>=26640                   ) return(PERIOD_MN1);
}
 
KimIV:


Артём, я не встречал таких ДЦ... Можете в личку скинуть пару штук? Почитаю торговые регламенты...

Скинул

Или можно проще поступить. Сами мне скажите, достаточно ли корректно будет использовать такую поправку?

int   msl=MarketInfo(sy, MODE_STOPLEVEL);
int    sp=MarketInfo(sy, MODE_SPREAD);
if (msl==0) msl=2*sp;

Конечно же, всё верно.

UPDATE: Внёс поправку в функцию CorrectingPrice().

Игорь, практически так и делаю в советниках, всегда в первую очередь считываю данные и присваиваю нужное значению переменной level, потом уже с ней и сверяю расчёты.
 
KimIV:


Артём, я не встречал таких ДЦ... Можете в личку скинуть пару штук? Почитаю торговые регламенты...

Или можно проще поступить. Сами мне скажите, достаточно ли корректно будет использовать такую поправку?

 UPDATE: Внёс поправку в функцию CorrectingPrice().

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

Как я понимаю, надо сделать обращение к этой функции для коррекции параметров перед выставлением ордера.

есть такая строка на открытие ордера:

 if(buy == true && Open[0]>UpTr  && Trade) {

 buy=OrderSend(Symbol(),OP_BUYSTOP,LOT(),NormalizeDouble(op,Digits),slippage,NormalizeDouble(sl,Digits),NormalizeDouble(tp,Digits),"T",Magic,0,MediumBlue);

это тут должно быть обращение? И как правильно это сделать. Или эта команда не нуждается в функции CorrectingPrice()?

Заранее благодарю. 

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