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

 

Ещё примеры использования функции SetOrder().

Для наглядности нужно выбрать инструмент с большим минимально допустимым уровнем стоп-лосса/тейк-профита в пунктах. Я выбрал AUDCAD, у которого этот уровень в выбранном мной для тестирования ДЦ равен 10 пунктам.

1. Установка ордера BuyLimit лотом 0.1 на 5 пунктов ниже текущей цены. Я специально выбрал уровень установки ордера меньше минимально допустимого уровня, чтобы получить ошибку 130 (Неправильные стопы) и показать, как функция SetOrder её отработает.

SetOrder(NULL, OP_BUYLIMIT, 0.1, Ask-5*Point);

Содержимое протокола (читается снизу вверх):
2008.03.17 09:06:24 test_SetOrder AUDCAD,M5: removed
2008.03.17 09:06:24 stdlib AUDCAD,M5: removed
2008.03.17 09:06:24 stdlib AUDCAD,M5: uninit reason 0
2008.03.17 09:06:24 test_SetOrder AUDCAD,M5: uninit reason 0
2008.03.17 09:06:24 test_SetOrder AUDCAD,M5: open #21616412 buy limit 0.10 AUDCAD at 0.9180 ok
2008.03.17 09:06:15 test_SetOrder AUDCAD,M5: SetOrder(): Скорректированы ценовые уровни
2008.03.17 09:06:15 test_SetOrder AUDCAD,M5: Ask=0.919 Bid=0.918 sy=AUDCAD ll=0.1 op=Buy Limit pp=0.9185 sl=0 tp=0 mn=0
2008.03.17 09:06:15 test_SetOrder AUDCAD,M5: Error(130) set order: invalid stops, try 1
2008.03.17 09:06:15 stdlib AUDCAD,M5: loaded successfully
2008.03.17 09:06:14 test_SetOrder AUDCAD,M5: loaded successfully

Из протокола видно, что функция попыталась поставить ордер по 0,9185 (pp=0.9185), но торговый сервер не принял такую заявку, вернул ошибку 130. Тогда функция корректирует уровень установки ордера в соответствии с минимально допустимым уровнем и предпринимает следующую торговую попытку, которая заканчивается удачно. Ордер установлен по 0,9180.

2. Установка ордера BuyStop лотом 0.3 на 6 пунктов выше текущей цены со стопом 9 пунктов

SetOrder(NULL, OP_BUYSTOP, 0.3, Ask+6*Point, Ask+(6-9)*Point);

Содержимое протокола (читается снизу вверх):
2008.03.17 09:27:36 test_SetOrder AUDCAD,M5: removed
2008.03.17 09:27:36 stdlib AUDCAD,M5: removed
2008.03.17 09:27:36 stdlib AUDCAD,M5: uninit reason 0
2008.03.17 09:27:36 test_SetOrder AUDCAD,M5: uninit reason 0
2008.03.17 09:27:36 test_SetOrder AUDCAD,M5: open #21617419 buy stop 0.30 AUDCAD at 0.9209 sl: 0.9195 ok
2008.03.17 09:27:26 test_SetOrder AUDCAD,M5: SetOrder(): Скорректированы ценовые уровни
2008.03.17 09:27:26 test_SetOrder AUDCAD,M5: Ask=0.9198 Bid=0.9188 sy=AUDCAD ll=0.3 op=Buy Stop pp=0.9204 sl=0.9195 tp=0 mn=0
2008.03.17 09:27:26 test_SetOrder AUDCAD,M5: Error(130) set order: invalid stops, try 1
2008.03.17 09:27:26 stdlib AUDCAD,M5: loaded successfully
2008.03.17 09:27:25 test_SetOrder AUDCAD,M5: loaded successfully

Этот пример показывает, как произошло изменение уровня установки ордера с 0,9204 на 0,9209. При этом уровень стопа остался прежним sl=0.9195. То есть стоп в пунктах увеличился с 9 до 14.

 

3. Установка ордера SellLimit лотом 0.5 на 8 пунктов выше текущей цены со стопом 9 пунктов и тейком 7 пунктов

SetOrder(NULL, OP_SELLLIMIT, 0.5, Bid+8*Point, Bid+(8-9)*Point, Bid-(8+7)*Point);

Содержимое протокола:
2008.03.17 10:38:50 test_SetOrder AUDCAD,M5: removed
2008.03.17 10:38:50 stdlib AUDCAD,M5: removed
2008.03.17 10:38:50 stdlib AUDCAD,M5: uninit reason 0
2008.03.17 10:38:50 test_SetOrder AUDCAD,M5: uninit reason 0
2008.03.17 10:38:49 test_SetOrder AUDCAD,M5: open #21620553 sell limit 0.50 AUDCAD at 0.9190 sl: 0.9201 tp: 0.9179 ok
2008.03.17 10:38:40 test_SetOrder AUDCAD,M5: SetOrder(): Скорректированы ценовые уровни
2008.03.17 10:38:40 test_SetOrder AUDCAD,M5: Ask=0.919 Bid=0.918 sy=AUDCAD ll=0.5 op=Sell Limit pp=0.9188 sl=0.9197 tp=0.9179 mn=0
2008.03.17 10:38:40 test_SetOrder AUDCAD,M5: Error(130) set order: invalid stops, try 1
2008.03.17 10:38:40 stdlib AUDCAD,M5: loaded successfully
2008.03.17 10:38:39 test_SetOrder AUDCAD,M5: loaded successfully

В этом примере снова сделана попытка установить лимитный ордер слишком близко к рынку. Уровень установки ордера скорректирован вверх на 2 пункта с 0.9188 до 0.9190. Уровень стопа также подправлен, но на 4 пункта с 0.9197 до 0.9201. Неизменным остался только уровень тейка, что привело к его увеличению в пунктах с 9 до 11.

Пожалуй, хватит примеров. Они итак довольно сложны для понимания. Какие можно сделать выводы?
1. Функция будет изо всех сил стараться выполнить возложенную на неё задачу, то есть пытаться установить ордер. Будет корректировать уровни под изменяющийся рынок и вновь, и вновь пытаться сделать своё дело.
2. Корректировка уровня установки стоповых ордеров приводит к увеличению уровня стопа в пунктах относительно цены установки. Объясняется это тем, что уровень стопа стопового ордера остаётся на месте, а уровень установки ордера отодвигается от уровня стопа. Для ордера BuyStop уровень установки сдвигается вверх, а для ордера SellStop - вниз. Такие манипуляции с уровнем установки ордера увеличивают размер стопа в пунктах на величину корректировки уровня установки ордера.
3. Корректировка уровня установки лимитных ордеров приводит к увеличению уровня тейка в пунктах относительно цены установки. Происходит это таким образом. Тейки стоят на месте, а стопы и уровни установки сдвигаются для BuyLimit - вверх, для SellLimit - вниз. Размер тейка в пунктах увеличивается на величину корректировки уровня установки ордера.

Внимание! В код функции SetOrder я внёс изменения - переставил местами несколько строк. Старый пост для редактирования уже недоступен, поэтому исправленную функцию выкладываю здесь. В прицепе также скрипт для онлайн-тестирования функции SetOrder.


Файлы:
 

Чтобы ускорить публикацию функции ModifyOrder, я решил переключиться на некоторое время на функции для работы с позициями, а потом опять вернуться на функции для ордеров и закончить с ними.

Примечание!
Позициями я называю торговые операции OP_BUY и OP_SELL. Позиции открываются и закрываются.
Ордерами я называю торговые операции OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLIMIT и OP_SELLSTOP. Ордера устанавливаются и удаляются. Если ордер сработает, то он становится позицией.

Функция ExistPositions().

Предназначена для проверки наличия открытых покупок или продаж. Аналогична функции ExistOrders. По умолчанию осматривает все позиции: текущего и других инструментов. Конкретизировать отбор можно комбинацией фильтров - параметров функции:

  • sy - Накладывает ограничение на наименование инструмента. По умолчанию параметр равен "" - отсутствие ограничений, то есть любой инструмент. Если передать NULL, то отбор позиций будет ограничен текущим инструментом.
  • op - Накладывает ограничение на тип позиции (Buy/Sell). По умолчанию ограничение отсутствует, то есть проверяется наличие позиции любого типа. Допустимые значения параметра -1, OP_BUY и OP_SELL.
  • mn - Накладывает ограничение на идентификационное ("магическое") число позиции. По умолчанию ограничение отсутствует, то есть проверяется наличие позиции с любым магическим числом.
  • ot - Накладывает ограничение на время открытия позиции. Проверяется, чтобы позиция была открыта позже значения данного параметра. По умолчанию ограничение отсутствует, то есть проверяется наличие позиции с любым временем открытия.
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 06.03.2008                                                     |
//|  Описание : Возвращает флаг существования позиций                          |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//|    ot - время открытия             ( 0   - любое время открытия)           |
//+----------------------------------------------------------------------------+
bool ExistPositions(string sy="", int op=-1, int mn=-1, datetime ot=0) {
  int i, k=OrdersTotal();
 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (ot<=OrderOpenTime()) return(True);
            }
          }
        }
      }
    }
  }
  return(False);
}
 

Примеры использования функции ExistPositions().

1. Проверить наличие любой позиции

ExistPositions();

2. Проверить наличие любой позиции по инструменту текущего графика

ExistPositions(NULL);

3. Проверить наличие покупки по любому инструменту

ExistPositions("", OP_BUY);

4. Проверить наличие продажи с магиком 123456 по EURUSD

ExistPositions("EURUSD", OP_SELL, 123456);

5. Проверить наличие любой позиции с временем открытия не ранее 15 минут назад

ExistPositions("", -1, -1, TimeCurrent()-15*60);

В прицепе скрипт для тестирования функции ExistPositions. Первые четыре примера закомментированы.

Файлы:
 
Простите конечно, но ни OrderSet_1 ни OrderSet_2 не работают! Ошибки выдает - компилировать не хочет! Что делать???
 
SoloEgoist:
Простите конечно, но ни OrderSet_1 ни OrderSet_2 не работают! Ошибки выдает - компилировать не хочет! Что делать???
Файлы OrderSet_1 ни OrderSet_2 - это исходные коды разных версий функции OrderSet. Просто исходные коды и всё. Ни компилироваться, ни исполняться они толком (без ошибок) не будут. Для того, чтобы получить хоть какой-то результат, нужно ещё создать рабочее окружение, использующее функцию OrderSet. Пример такого рабочего окружения я сделал в файле test_SetOrder.
 
Спасибо.Понятно - буду пытаться, просто почти языка не знаю.
 

Функций и способов работы с датой и временем пригодились бы...

Например:
- вычесть от текушего времени 2 часа
- до экспирации осталось Х дней...

И ещё... не знаю в тему ли... :(

Функций для статистики. Например:
- сколько часовых свечек 21:00 каждый понедельник
- из них: 215 бычьи, 245 медвежьи
- из бычьих: мин. 12 пип макс 54 пип
- и т. .д...

или
- лоу каждой первой 15Н свечки дня выше\ниже второй Х количество раз

Важнее не сами функции а способы их построения, тогда и своё легче реализовать,
попутно изучая програмирование...
Пожалуюсь в очередной раз :))) порой много не очень понятно, и указывают что книжки по Си помогут.
естественно почитать можно, а надо ли??? забивать лишней инфой голову сосредоточившись лишь на мкл4.
Какие непотнятки? например это: ||

 
kombat:

Функций и способов работы с датой и временем пригодились бы...

Например:
- вычесть от текушего времени 2 часа
- до экспирации осталось Х дней...

...


таккую функцию писать не стоит - есть очень простое решение!


int gHour = 2;
datetime gДваЧасаВыесть ;


gДваЧасаВыесть = TimeCorrent() - ((86400)/24) * gHour ); // 2 часа
gДваЧасаВыесть = TimeCorrent() - 7200; // то же самое но без нагрузки вычислений

т е в сутках получаем 86400 тиков таймера

значит 2 часа = 7200 тиков, т к 86400/24 * 2 = 7200
1 час = 3600; и т д
 
kombat:

Функций и способов работы с датой и временем пригодились бы...

Функций для статистики. Например:
- сколько часовых свечек 21:00 каждый понедельник
- из них: 215 бычьи, 245 медвежьи
- из бычьих: мин. 12 пип макс 54 пип
- и т. .д...

или
- лоу каждой первой 15Н свечки дня выше\ниже второй Х количество раз

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

Принято к сведению... :-)

kombat писал (а):
Пожалуюсь в очередной раз :))) порой много не очень понятно, и указывают что книжки по Си помогут.
естественно почитать можно, а надо ли??? забивать лишней инфой голову сосредоточившись лишь на мкл4.
Какие непотнятки? например это: ||

Это логическое ИЛИ. Поясню на примере. Выражение "Если х>2 или х<-3, тогда х=5" на языке MQL4 будет иметь вид

if (х>2 || х<-3) х=5;