Jump to content
Programmer

Курс MQL4

Recommended Posts

Programmer

Урок 63 - Способы перебора массивов

 

Приветствую, уважаемые читатели!

Поскольку данная тема уже поднималась несколько раз, я решил уделить ей целый урок, чтобы полностью разобраться с этим вопросом и построить ясную картину. Итак, "способы перебора массивов"!

 

Зачем нужно перебирать массивы?

Чаще всего, подобная задача возникает при поиске какого-либо или каких-либо определенных элементов в массиве. Например, мы можем перебирать массив ордеров в поисках самого прибыльного, или массив данных индикатора RSI в поисках всех значений выше 80-ти, и т.д.

 

Почему нельзя всегда просто перебирать от начала массива к концу?

Можно, но это надо делать очень аккуратно! Простейший пример: перебор массива открытых ордеров с целью закрытия всех ордеров, по которым текущий Profit > 0. Программист-новичок реализовал бы подобный цикл следующим орбразом:

 

for(int i=0; i<OrdersTotal(); i++) //incorrect!
{
  OrderSelect(i, SELECT_BY_POS);
  if(OrderProfit()>0)
     OrderClose(OrderTicket(), lots, price, slippage);
}

И это неверно! Действительно, давайте подумаем, что будет, если у нас есть всего 5 ордеров и их Profits следующие: -20,+10,+50,-10,+10. Действия цикла:

i=0<5: -20,+10,+50,-10,+10 -> profit<0 -> пропускаем -> массив НЕ меняется

i=1: -20,+10,+50,-10,+10 -> profit>0 -> закрываем -> массив изменился: -20,+50,-10,+10

i=2: -20,+50,-10,+10 -> profit<0 -> пропускаем -> массив НЕ меняется

i=3: -20,+50,-10,+10 -> profit>0 -> закрываем -> массив изменился: -20,+50,-10

i=4 > OrdersTotal() = 3 (новое значение) - цикл прекращается

 

Как видим, в итоге мы имеем массив ордеров с Profits: -20,+50,-10 - мы НЕ удалили значение "+50". Это произошло из-за сдвига массива. Именно поэтому, при закрытии/удалении ордеров массив лучше перебирать от конца к началу. А именно так:

 

for(int i=OrdersTotal()-1; i>=0; i--) //correct!
{
  OrderSelect(i, SELECT_BY_POS);
  if(OrderProfit()>0)
     OrderClose(OrderTicket(), lots, price, slippage);
}

 

Какие еще существуют методы перебора?

Теперь, когда я (надеюсь) Вас убедил, что к задаче перебора массива надо подходить с умом, давайте рассмотрим какие еще существуют варианты перебора/поиска массива/элементов в массиве и каковы их преимущества и недостатки.

 

Рассмотрим пример, когда из 1,000 ордеров Вы хотите найти тот, время открытия которого наиболее близко к указанному в условиях. Будем справедливы - такая задача вполне реальна. Рассмотрим два способа решения поставленной задачи:

A. Можно перебирать от начала к концу, можно перебирать от конца к началу - оба метода называются последовательным или линейным поиском. При линейном поиске в среднем потребуется (N+1)/2 сравнение, чтобы найти нужный ордер. Т.е. порядок данного метода: O(N).

B. Дихотомический поиск. Выбираем средний ордер [N/2] и сравниваем с заданным значением. Исходя из результата далее рассматриваем либо половину ордеров, находящуюся слева, либо ту, что спава. Повторяем процедуру для половины. Выбираем либо левую четверть, либо правую. Повторяем процедуру. И т.д. При дихотомическом поиске в среднем потребуется log2(N) сравнение, чтобы найти нужный ордер.

 

Теперь сравним требуемое количество операций двух методов.

(N+1)/2 = 500.5 ~ 500 сравнений

log2(N) = 9.96 ~ 10 сравнений

 

Как видим, в условвиях поставленной задачи (1,000 ордеров) дихотомический перебор требует В 50 РАЗ МЕНЬШЕ СРАВНЕНИЙ, в сравнении с линейным. И если при однократном переборе, Вы не особо замените разницы (компьютер и 500 и 10 сравнений сделает очень быстро), то если подобный перебор делается на каждом тике графика M15 за период в 3 года при оптимизации советника по двум параметрам - разница будет исчисляться часами или даже днями!

 

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

 

Помимо линейного и дихотомического также существует еще огромный выбор методов перебора: случайный перебор, маятниковый перебор, прямой упорядоченный перебор, метод затухающего маятника, метод Монте-Карло, метод золотого сечения, и прочие. Про метод Монте-Карло Вы, вероятно, слышали - он широко применяется в науке. Например:

 



Рис. 1 - Метод Монте-Карло в астрономии

 

Надеюсь, что данный урок был полезен для Вас.

До встречи на следующем уроке!

 

© Kirill. StockProgrammer@mail.ru

post-50854-1404216193,0851_thumb.jpg

Share this post


Link to post
Share on other sites
Programmer

Урок 64 - Вызов индикаторов (часть 1)

 

Здравствуйте, друзья!

Помните, мы в уроках 47-49 разбирали тему "Индикатор индикатора"? Сегодня настало время разобрать тему под названием просто "Индикаторы" :) Да, сегодняшняя тема будет легче, и, наверное, многие уже умеют вызывать индикаторы в MQL4, однако, я считаю важным все же разобрать данный аспект программирования MQL4, чтобы новички могли получить ответы на все имеющиеся вопросы, а также для полноты данного курса.

 

Итак, план ближайших уроков таков: сегодня мы рассмотрим функции вызова стандартных индикаторов в советниках (помимо функций XXXOnArray(), которые мы уже разобрали в уроках 47-49), в следующем уроке мы разберем пару примеров, а затем перейдем к очень интересной под-теме - к функции iCustom(), про которую мне есть что Вам рассказать ;)

 

Итак, поехали!

 

 

1 - iAC()

 

Синтаксис:

double iAC( string symbol, int timeframe, int shift)

 

Описание:

Расчет осциллятора Accelerator/Decelerator.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

2 - iAD()

 

Синтаксис:

double iAD( string symbol, int timeframe, int shift)

 

Описание:

Расчет индикатора Accumulation/Distribution.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

3 - iAlligator()

 

Синтаксис:

double iAlligator( string symbol, int timeframe, int jaw_period, int jaw_shift, int teeth_period, int teeth_shift, int lips_period, int lips_shift, int ma_method, int applied_price, int mode, int shift)

 

Описание:

Расчет индикатора Alligator.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

jaw_period - Период усреднения синей линии (челюсти аллигатора).

jaw_shift - Смещение синей линии относительно графика цены.

teeth_period - Период усреднения красной линии (зубов аллигатора).

teeth_shift - Смещение красной линии относительно графика цены.

lips_period - Период усреднения зеленой линии (губ аллигатора).

lips_shift - Смещение зеленой линии относительно графика цены.

ma_method - Метод усреднения. Может быть любым из значений методов скользящего среднего (Moving Average).

applied_price - Используемая цена. Может быть любой из ценовых констант.

mode - Источник данных, идентификатор одной из линий индикатора. Mожет быть любой из следующих величин:

MODE_GATORJAW - синяя линия (линия челюсти аллигатора),

MODE_GATORTEETH - красная линия (линия зубов аллигатора),

MODE_GATORLIPS - зеленая линия (линия губ аллигатора).

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

4 - iADX()

 

Синтаксис:

double iADX( string symbol, int timeframe, int period, int applied_price, int mode, int shift)

 

Описание:

Расчет Average Directional Movement Index.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период усреднения для вычисления индекса.

applied_price - Используемая цена. Может быть любой из ценовых констант.

mode - Индекс линии индикатора. Может быть любым из перечисленных идентификаторов линии индикаторов.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

5 - iATR()

 

Синтаксис:

double iATR( string symbol, int timeframe, int period, int shift)

 

Описание:

Расчет индикатора Average True Range.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период усреднения для вычисления индикатора.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

6 - iAO()

 

Синтаксис:

double iAO( string symbol, int timeframe, int shift)

 

Описание:

double iAO( string symbol, int timeframe, int shift)

Расчет Awesome oscillator.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

7 - iBearsPower()

 

Синтаксис:

double iBearsPower( string symbol, int timeframe, int period, int applied_price, int shift)

 

Описание:

double iBearsPower( string symbol, int timeframe, int period, int applied_price, int shift)

Расчет индикатора Bears Power.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период усреднения для вычисления индикатора.

applied_price - Используемая цена. Может быть любой из ценовых констант.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

8 - iBands()

 

Синтаксис:

double iBands( string symbol, int timeframe, int period, int deviation, int bands_shift, int applied_price, int mode, int shift)

 

Описание:

Расчет индикатора Bollinger Bands.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период усреднения основной линии индикатора.

deviation - Отклонение от основной линии.

bands_shift - Сдвиг индикатора относительно ценового графика.

applied_price - Используемая цена. Может быть любой из ценовых констант.

mode - Индекс линии индикатора. Может быть любым из идентификаторов линий индикаторов.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

9 - iBullsPower()

 

Синтаксис:

double iBullsPower( string symbol, int timeframe, int period, int applied_price, int shift)

 

Описание:

Расчет индикатора Bulls Power.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период усреднения для вычисления индикатора.

applied_price - Используемая цена. Может быть любой из ценовых констант.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

Share this post


Link to post
Share on other sites
Programmer

10 - iCCI()

 

Синтаксис:

double iCCI( string symbol, int timeframe, int period, int applied_price, int shift)

 

Описание:

Расчет индикатора Commodity Channel Index.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период усреднения для вычисления индикатора.

applied_price - Используемая цена. Может быть любой из ценовых констант.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

11 - iDeMarker()

 

Синтаксис:

double iDeMarker( string symbol, int timeframe, int period, int shift)

 

Описание:

Расчет индикатора DeMarker.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период усреднения для вычисления индикатора.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

12 - iEnvelopes()

 

Синтаксис:

double iEnvelopes( string symbol, int timeframe, int ma_period, int ma_method, int ma_shift, int applied_price, double deviation, int mode, int shift)

 

Описание:

Расчет индикатора Envelopes.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

ma_period - Период усреднения основной линии индикатора.

ma_method - Метод усреднения. Может быть любым из значений методов скользящего среднего (Moving Average).

ma_shift - Сдвиг индикатора относительно ценового графика.

applied_price - Используемая цена. Может быть любой из ценовых констант.

deviation - Отклонение от основной линии в процентах.

mode - Индекс линии индикатора. Может быть любым из значений идентификаторов линий индикаторов.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

13 - iForce()

 

Синтаксис:

double iForce( string symbol, int timeframe, int period, int ma_method, int applied_price, int shift)

 

Описание:

Расчет Force Index.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период усреднения для вычисления индикатора.

ma_method - Метод усреднения. Может быть любым из значений методов скользящей средней (Moving Average).

applied_price - Используемая цена. Может быть любой из ценовых констант.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

14 - iFractals()

 

Синтаксис:

double iFractals( string symbol, int timeframe, int mode, int shift)

 

Описание:

Расчет индикатора Fractals.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

mode - Индекс линии индикатора. Может быть любым из значений идентификаторов линии индикаторов.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

15 - iGator()

 

Синтаксис:

double iGator( string symbol, int timeframe, int jaw_period, int jaw_shift, int teeth_period, int teeth_shift, int lips_period, int lips_shift, int ma_method, int applied_price, int mode, int shift)

 

Описание:

Расчет осциллятора Gator. Осциллятор показывает разницу между синей и красной линией Аллигатора (верхняя гистограмма) и разницу между красной и зеленой линией (нижняя гистограмма).

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

jaw_period - Период усреднения синей линии (челюсти аллигатора).

jaw_shift - Смещение синей линии относительно графика цены.

teeth_period - Период усреднения красной линии (зубов аллигатора).

teeth_shift - Смещение красной линии относительно графика цены.

lips_period - Период усреднения зеленой линии (губ аллигатора).

lips_shift - Смещение зеленой линии относительно графика цены.

ma_method - Метод усреднения. Может быть любым из значений методов скользящей средней (Moving Average).

applied_price - Используемая цена. Может быть любой из ценовых констант.

mode - Индекс линии индикатора. Может быть любым из значений идентификаторов линии индикаторов.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

16 - iIchimoku()

 

Синтаксис:

double iIchimoku( string symbol, int timeframe, int tenkan_sen, int kijun_sen, int senkou_span_b, int mode, int shift)

 

Описание:

Расчет индикатора Ichimoku Kinko Hyo.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

tenkan_sen - Период усреднения Tenkan Sen.

kijun_sen - Период усреднения Kijun Sen.

senkou_span_b - Период усреднения Senkou Span B.

mode - Источник данных. Может быть одним из перечисленных идентификаторов Ichimoku Kinko Hyo.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

17 - iBWMFI()

 

Синтаксис:

double iBWMFI( string symbol, int timeframe, int shift)

 

Описание:

Расчет Market Facilitation Index.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

18 - iMomentum()

 

Синтаксис:

double iMomentum( string symbol, int timeframe, int period, int applied_price, int shift)

 

Описание:

Расчет индикатора Momentum.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период(количество баров) для вычисления изменения цены.

applied_price - Используемая цена. Может быть любой из ценовых констант.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

19 - iMFI()

 

Синтаксис:

double iMFI( string symbol, int timeframe, int period, int shift)

 

Описание:

Расчет Money Flow Index.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период(количество баров) для вычисления индикатора.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

20 - iMA()

 

Синтаксис:

double iMA( string symbol, int timeframe, int period, int ma_shift, int ma_method, int applied_price, int shift)

 

Описание:

Расчет скользящего среднего.

Параметры:

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период усреднения для вычисления скользящего среднего.

ma_shift - Сдвиг индикатора относительно ценового графика.

ma_method - Метод усреднения. Может быть любым из значений методов скользящего среднего (Moving Average).

applied_price - Используемая цена. Может быть любой из ценовых констант.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

Share this post


Link to post
Share on other sites
Programmer

21 - iOsMA()

 

Синтаксис:

double iOsMA( string symbol, int timeframe, int fast_ema_period, int slow_ema_period, int signal_period, int applied_price, int shift)

 

Описание:

Расчет Moving Average of Oscillator. Осциллятор OsMA показывает разницу между значениями MACD и его сигнальной линии. В некоторых системах этот осциллятор называется гистограммой MACD.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

fast_ema_period - Период усреднения для вычисления быстрой скользящей средней.

slow_ema_period - Период усреднения для вычисления медленной скользящей средней.

signal_period - Период усреднения для вычисления сигнальной линии.

applied_price - Используемая цена. Может быть любой из ценовых констант.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

22 - iMACD()

 

Синтаксис:

double iMACD( string symbol, int timeframe, int fast_ema_period, int slow_ema_period, int signal_period, int applied_price, int mode, int shift)

 

Описание:

Расчет индикатора Moving Averages Convergence/Divergence. В тех системах, где ОsМА называют гистограммой МАКД, данный индикатгор изображается в виде двух линий. В клиентском терминале схожденние/расхождение скользящих средних рисуется в виде гистограммы.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

fast_ema_period - Период усреднения для вычисления быстрой скользящей средней.

slow_ema_period - Период усреднения для вычисления медленной скользящей средней.

signal_period - Период усреднения для вычисления сигнальной линии.

applied_price - Используемая цена. Может быть любой из ценовых констант.

mode - Индекс линии индикатора. Может быть любым из значений идентификаторов линии индикаторов.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

23 - iOBV()

 

Синтаксис:

double iOBV( string symbol, int timeframe, int applied_price, int shift)

 

Описание:

Расчет индикатора On Balance Volume.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

applied_price - Используемая цена. Может быть любой из ценовых констант.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

24 - iSAR()

 

Синтаксис:

double iSAR( string symbol, int timeframe, double step, double maximum, int shift)

 

Описание:

Расчет индикатора Parabolic Stop and Reverse system.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

step - Приращение уровня стопа, обычно 0.02.

maximum - Максимальный уровень стопа, обычно 0.2.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

25 - iRSI()

 

Синтаксис:

double iRSI( string symbol, int timeframe, int period, int applied_price, int shift)

 

Описание:

Расчет Relative Strength Index.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период усреднения для вычисления индекса.

applied_price - Используемая цена. Может быть любой из ценовых констант.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

26 - iRVI()

 

Синтаксис:

double iRVI( string symbol, int timeframe, int period, int mode, int shift)

 

Описание:

Расчет Relative Vigor Index.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период усреднения для вычисления индекса.

mode - Индекс линии индикатора. Может быть любым из значений идентификаторов линии индикаторов.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

27 - iStdDev()

 

Синтаксис:

double iStdDev( string symbol, int timeframe, int ma_period, int ma_shift, int ma_method, int applied_price, int shift)

 

Описание:

Расчет индикатора Standard Deviation.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

ma_period - Период усреднения для вычисления индикатора.

ma_shift - Сдвиг индикатора относительно ценового графика.

ma_method - Метод усреднения. Может быть любым из значений методов скользящего среднего (Moving Average).

applied_price - Используемая цена. Может быть любой из ценовых констант.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

28 - iStochastic()

 

Синтаксис:

double iStochastic( string symbol, int timeframe, int %Kperiod, int %Dperiod, int slowing, int method, int price_field, int mode, int shift)

 

Описание:

Расчет Stochastic Oscillator.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

%Kperiod - Период(количество баров) для вычисления линии %K.

%Dperiod - Период усреднения для вычисления линии %D.

slowing - Значение замедления.

method - Метод усреднения. Может быть любым из значений методов скользящего среднего (Moving Average).

price_field - Параметр выбора цен для расчета. Может быть одной из следующих величин: 0 - Low/High или 1 - Close/Close.

mode - Индекс линии индикатора. Может быть любым из значений идентификаторов линий индикаторов.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

29 - iWPR()

 

Синтаксис:

double iWPR( string symbol, int timeframe, int period, int shift)

 

Описание:

Расчет индикатора Larry Williams' Percent Range.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

period - Период(количество баров) для вычисления индикатора.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

Надеюсь, данный урок был Вам полезен.

До встречи на следующем уроке!

 

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 65 - Вызов индикаторов (часть 2)

 

Приветствую, уважаемые читатели!

Сегодня мы продолжим разбирать тему вызова индикаторов. В прошлый раз я предложил Вашему вниманию длинный список функций - аж 29 штук, что же они все означают? Я полагаю, что все вы уже знакомы с индикаторами в торговом терминале МТ4. Как Вы, наверное, заметили каждый индикатор состоит из набора линий/гистограмм/областей/значков. На рисунке ниже приведены изображены в качестве примера несколько индикаторов: в окне графика находится индикатор "Ichimoku Kinko Hyo", ниже, в отдельном окне, - индикатор "Gator", еще ниже - индикатор "StdDev", который показывает волатильность рынка.

 



Рис. 1 - Примеры индкаторов

 

Если поднести мышку к отдельной линии индикатора, то возникет всплывающая подсказка и сообщит название индикатора, название этой линии и значение, принимаемое линией в данной точке. Иллюстрацию Вы можете видеть также на рисунке 1.

 

Наша задача в программировании - это узнать значение (в опрделенный момент времени) (выбранной линии) (выбранного индикатора), примененного к (выбранному таймфрейму) (выбранного финансового инструмента) :D

Не пугайтесь! Все просто! И тут нам помогут функции, описанные в предыдущем уроке. Рассмотрим пример:

 

1 - iAC()

 

Синтаксис:

double iAC( string symbol, int timeframe, int shift)

 

Описание:

Расчет осциллятора Accelerator/Decelerator.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

В качестве входных параметров нам надо передать три значения: symbol, timeframe и shift (сдвиг вправо относительно тек. бара). Таким образом, мы однозначно зададим финансовый интсрумент, период графика и момент времени, в который мы хотим знать значение индикатора. Например:

 

double X = iAC("EURUSD", PERIOD_H1, 2);

 

Таким нехитрым оператором (вызовом функции) мы присвоили переменной X значение индикатора на 3-ем (т.к. нумерация начинается с нуля) баре справа на графике EURUSD H1. Хочу заметить, что значение переменной X НЕ будет меняться вместе с индикатором. Оно зафиксировано - это просто число. Вы можете потом заново присовить переменной X некое (другое) значение, если пожелаете - например, Вы можете вызвать точно такой же оператор на следующем баре, и тогда значение переменной X станет равно значению индикатора на новом 3-ем баре.

 



Рис. 2 - Пример с AC

 

В данном примере в переменную X запишется число "-0.002083".

Рассмотрим пример посложней:

 

3 - iAlligator()

 

Синтаксис:

double iAlligator( string symbol, int timeframe, int jaw_period, int jaw_shift, int teeth_period, int teeth_shift, int lips_period, int lips_shift, int ma_method, int applied_price, int mode, int shift)

 

Описание:

Расчет индикатора Alligator.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

jaw_period - Период усреднения синей линии (челюсти аллигатора).

jaw_shift - Смещение синей линии относительно графика цены.

teeth_period - Период усреднения красной линии (зубов аллигатора).

teeth_shift - Смещение красной линии относительно графика цены.

lips_period - Период усреднения зеленой линии (губ аллигатора).

lips_shift - Смещение зеленой линии относительно графика цены.

ma_method - Метод усреднения. Может быть любым из значений методов скользящего среднего (Moving Average).

applied_price - Используемая цена. Может быть любой из ценовых констант.

mode - Источник данных, идентификатор одной из линий индикатора. Mожет быть любой из следующих величин:

MODE_GATORJAW - синяя линия (линия челюсти аллигатора),

MODE_GATORTEETH - красная линия (линия зубов аллигатора),

MODE_GATORLIPS - зеленая линия (линия губ аллигатора).

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

Это всеми обожамемый индикатор "Аллигатор Билла Вильямса". Выглядит сложновато, но ничего страшного тут нет:

 

double LIPS=iAlligator(NULL, 0, 13, 8, 8, 5, 5, 3, MODE_SMMA, PRICE_MEDIAN, MODE_GATORJAW, 0);

 

Всегда сначала указываем инструмент: "NULL" означает инструмент текущего графика (там, где будет запущена Ваша программа). Затем, период: "0" означает период текущего графика. Затем, идут параметры индикатора. У этого индикатора много параметров - мы просто передаем их по порядку: "13, 8, 8, 5, 5, 3, MODE_SMMA, PRICE_MEDIAN". Затем, надо указать, какую линию мы хотим рассчитать: "MODE_GATORLIPS" означает, что мы хотим зеленую линию. И в конце, мы указываем на каком баре нужно произвести расчет: "0" означает текущий бар.

 



Рис. 3 - Пример с Alligator

 

В данном примере в переменную LIPS запишется число "1.3778". В заключение хочу пояснить, что вовсе не нужно, чтобы индикатор был открыт на графике. С помощью указанных манипуляций Вы изнутри своей программы вызываете нужный Вам индикатор и накладываете его на выбранный Вами график, который может даже не быть открыт. Ваша программа произведет расчет индикатора и желанное значение будет записано в указанную Вами переменную, а дальше Вы сможете делать с ним все, что захотите!

 

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

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

post-50854-1404216616,2296_thumb.gif

post-50854-1404216616,2809_thumb.gif

post-50854-1404216616,3291_thumb.gif

Share this post


Link to post
Share on other sites
Programmer

Урок 66 - Функция iCustom() (Часть 1)

 

Всем привет, друзья!

Я уже получил очень много просьб рассказать про работу функции iCustom(), вот одна из них:

 

"Добрый день, изучаю MQL4, пока ни у Вас, ни на других учебных сайтах не увидела то, что ищу. Может, я, конечно, нерадивый ученик; подскажите, как привязать советник к уже готовому индикатору? Меня интересует механизм обращения к индикатору. Или подскажите, в каком разделе Вашего учебного материала это написано. Спасибо. Носова Юля"

 

Уважаемая Юля, Ваша задача легко решается с помощью функции iCustom(), и сегодня я раскрою тайну этого мощного инструмента MQL4.

 

Существует два типа индикаторов, которые Вы можете использовать в своем коде (в советниках, пользовательских индикаторах и скриптах): встроенные индикаторы и пользовательские индикаторы. Рассмотрим оба типа.

 

1 - Встроенные индикаторы

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

 

double iMA(string symbol, int timeframe, int period, int ma_shift, int ma_method, int applied_price, int shift)

 

Вышеуказанный код считает скользящую среднюю и возвращает полученное значение. Подробно вызов встроенных функций мы обсуждали в прошых двух уроках. А вот, что делать, если индикатор не родной для МТ4?

 

2 - Пользовательские индикаторы

Чтобы воспользоваться в своей программе пользовательским (не встроенным) индикатором, можно полностью копировать код этого индикатора в программу, но это очень неудобно, поскольку, например, в советниках не предусмотрены буферы, столь критичные для индикаторов. И поверьте мне, моделировать буфер в советнике - неблагодарное дело! Я один раз такой фокус проворачивал - встраивал индикатор "Heiken Ashi" напрямую в советник... нда... как вспомню, аж дрожь пробирает... не советую повторять :) Намного проще воспользоваться более простым способом - прибегнуть к помощи функции iCustom():

 

iCustom()

 

Синтаксис:

double iCustom( string symbol, int timeframe, string name, ..., int mode, int shift)

 

Описание:

Расчет указанного пользовательского индикатора. Пользовательский индикатор должен быть скомпилирован (файл с расширением EX4) и находиться в директории каталог_терминала\experts\indicators.

 

Параметры:

symbol - Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

timeframe - Период. Может быть одним из периодов графика. 0 означает период текущего графика.

name - Имя пользовательского индикатора.

... - Список параметров (при необходимости). Передаваемые параметры должны соответствовать порядку объявления и типу внешних (extern) переменных пользовательского индикатора.

mode - Индекс линии индикатора. Может быть от 0 до 7 и должен соответствовать индексу, используемому одной из функций SetIndexBuffer.

shift - Индекс получаемого значения из индикаторного буфера (сдвиг относительно текущего бара на указанное количество периодов назад).

 

 

Давайте внимательно посмотрим на эту функцию. Вы уже видите, что эта функция похожа на функции вызова встроенных индикаторов, которые мы разбирали в уроках 64 и 65? Напомню Вам, как мы вызывали индикатор Alligator:

 

Всегда сначала указываем инструмент: "NULL" означает инструмент текущего графика (там, где будет запущена Ваша программа). Затем, период: "0" означает период текущего графика. Затем, идут параметры индикатора. У этого индикатора много параметров - мы просто передаем их по порядку: "13, 8, 8, 5, 5, 3, MODE_SMMA, PRICE_MEDIAN". Затем, надо указать, какую линию мы хотим рассчитать: "MODE_GATORLIPS" означает, что мы хотим зеленую линию. И в конце, мы указываем на каком баре нужно произвести расчет: "0" означает текущий бар.

 

Теперь взглянем на описание iCustom() в сравнении с iAlligator:

 

double iCustom(string symbol, int timeframe, string name, ... , int mode, int shift)

double iAlligator(string symbol, int timeframe, int jaw_period, int jaw_shift, int teeth_period, int teeth_shift, int lips_period, int lips_shift, int ma_method, int applied_price, int mode, int shift)

 

Как видите, у них очень много схожего. Рассмотрим параметры по отдельности:

1й: string symbol - одинакоый, указывает финансовый инструмент

2й: int timeframe - одинаковый, указывает таймфрейм

3й: тут начинаются различия:

- у iCustom() идет параметр под названием "name" - он указывает название индикатора, который надо рассчитать

- а у iAlligator() начинается перечисление его входных параметров

4й: у iAlligator() продолжается перечисление входных параметров, а у iCustom() стоят три точки "..." На самом деле, это тоже перечисление всех входных параметров Вашего индикатора, просто iCustom() не знает ни их тип, ни их количество, поэтому задача правильно подставить параметры запрашиваемого индикатора целиком ложится на плечи программиста!

...

...

...

N-1й: int mode - одинаковый, указывает какую линию индикатора Вы хотите рассчитать

Nй: int shift - одинаковый, указывает сдвиг в барах от самого правого бара графика

 

Теперь Вы видите, что эти функции очень похожи? Различия лишь в том, что у iCustom() добавляется третий параметр - название индикатора, этот параметр функциям вызова встроенных индикаторов не нужен, т.к. сами названия функций (iADX, iBullsPower и т.д.) уже содержат в себе названия индикаторов. Второе различие - у iCustom() входные парамтеры индикатора не перечислены явно (поскольку они заранее не известны), вместо этого в описании iCustom() стоят три точки "...", которые подразумевают любое количество любых параметров, а не ошибиться при их вводе - это задача программиста. Вы уже достаточно опытные ;)

 

Материал непростой. Надеюсь, что я его достаточно доступно изложил. В следующий раз мы рассмотрим примеры работы с iCustom(), а пока советую потренироваться с вызвовом встроенных индикаторов (см. уроки 64-65).

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 67 - Функция iCustom() (Часть 2)

 

Всем привет, друзья!

Сегодня мы продолжим работу с функцией iCustom(). Напомню ее синтаксис:

 

double iCustom( 	string symbol, int timeframe, string name, ..., int mode, int shift)

 

Давайте рассмотрим простой пример применения данной функции. Ниже расположен код несложного индикатора, который я написал специально для этого урока:

 

//+------------------------------------------------------------------+
//|                                                 MyIndicator1.mq4 |
//|                                Copyright © 2011, StockProgrammer |
//|                                          StockProgrammer@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, StockProgrammer"
#property link      "StockProgrammer@mail.ru"

#property indicator_separate_window

#property indicator_buffers 1
#property indicator_color1 Yellow

double Buffer0[];

int init()
{
  SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,5);
  SetIndexBuffer(0,Buffer0);
  SetIndexEmptyValue(0,0.0);

  IndicatorShortName("CandleType");  

  return(0);
}

int start()
 {
  int    counted_bars=IndicatorCounted();
  if(counted_bars<0) return(-1);
  if(counted_bars>0) counted_bars--;

  for(int i=Bars-counted_bars; i>=0; i--)
  {
     if(Close[i] > Open[i])
        Buffer0[i] = +1.0;   //так мы будем обозначать бычью свечу
     else if(Close[i] < Open[i])
        Buffer0[i] = -1.0;   //так мы будем обозначать бычью свечу         
     else
        Buffer0[i] = 0.0;    //а это doji
  }
  return(0);
 }
//+------------------------------------------------------------------+

 



Рис. 1 - Пример работы индкатора

 

Исходя из кода и рисунка, приведенных выше, попробуйте сами догадаться, что показывает индикатор ;)

Если у Вас возникают сложности, или Вы недостаточно хорошо понимаете, как написан код индикатора, я советую Вам перечитать уроки 10-12 "Ваш первый индикатор". А теперь обратимся к коду советника, который торгует по показаниям данного индикатора:

 

//+------------------------------------------------------------------+
//|                                                    MyExpert1.mq4 |
//|                                Copyright © 2011, StockProgrammer |
//|                                          StockProgrammer@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, StockProgrammer"
#property link      "StockProgrammer@mail.ru"

extern int StopLoss = 50;
extern int TakeProfit = 50;
int ticket = 0;

int start()
{
  int LastCandleType;
  CheckTicket();
  if(ticket == 0)
  {
     LastCandleType = iCustom(Symbol(), Period(), "MyIndicator1", 0, 1);
     if(LastCandleType > 0)
        ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, Bid-StopLoss*Point, Bid+TakeProfit*Point, "ICustomTest1");
     if(LastCandleType < 0)
        ticket = OrderSend(Symbol(), OP_SELL, 0.1, Bid, 3, Ask+StopLoss*Point, Ask-TakeProfit*Point, "ICustomTest1");      
  }
  return(0);
}


void CheckTicket()   //функция контроля переменной ticket
{
  int res;
  if(ticket != 0)
  {
     res = OrderSelect(ticket, SELECT_BY_TICKET);
     if(res!=0)
     {
        if(OrderCloseTime() != 0)
           ticket = 0;
     }
     else
        ticket = 0;     
  }


}

 

В данном коде нас интересует следующая часть:

      LastCandleType = iCustom(Symbol(), Period(), "MyIndicator1", 0, 1);
     if(LastCandleType > 0)
        ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, Bid-StopLoss*Point, Bid+TakeProfit*Point, "ICustomTest1");
     if(LastCandleType < 0)
        ticket = OrderSend(Symbol(), OP_SELL, 0.1, Bid, 3, Ask+StopLoss*Point, Ask-TakeProfit*Point, "ICustomTest1"); 

 

В первой строчке мы обращаемся к нашему собственному индикатору, который уже написан, откомпилирован(!) и лежит в папке /experts/indicators. Для обращения мы используем функцию iCustom(), и чтобы она знала какой именно индикатор нам нужен, третий слева параметр указывает имя индикатора и должен совпадать с названием файла один-в-один (без учета расширения).

Первый параметр указывает валюту графика, на который надо наложить индикатор.

Второй параметр указывает период графика, на который надо наложить индикатор.

Как видите, поскольку индикатор у нас очень простой, у него отсутствуют входные параметры, и поэтому в iCustom() вместо входных параметров индикатора, обозначенных тремя точками "...", ничего ставить не надо.

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

Последний параметр - это сдвин относительно конца буфера. В нашем советнике мы хотим узнать показания индикатора для последнего завершенного бара - это бар номер [1].

 

Я полагаю, что глядя на коды программ выше, Вы уже догадались, что данный советник открывает сделку BUY, если предыдущая свеча была бычьей, и сделку SELL, если предыдущая свеча была медвежьей, при условии, что нет уже открытой сделки.

 

Надеюсь, данный урок помог Вам лучше понять iCustom(). Впереди у нас еще несколько уроков по этой функции, где мы рассмотрим более сложные примеры ее применения.

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

post-50854-1404216646,9627_thumb.gif

Share this post


Link to post
Share on other sites
Programmer

Урок 68 - Функция iCustom() (Часть 3)

 

Приветствую читаталей!

Как я и обещал, сегодня мы начнем рассмотрение достаточно сложного примера использования функции iCustom(). Напомню синтаксис iCustom(), чтобы он был у Вас перед глазами:

 

double iCustom(     string symbol, int timeframe, string name, ..., int mode, int shift)

Код индикатора, который мы будем использовать в ближайших уроках:

 

//+------------------------------------------------------------------+
//|                                                 MyIndicator2.mq4 |
//|                                Copyright © 2011, StockProgrammer |
//|                                          StockProgrammer@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, StockProgrammer"
#property link      "StockProgrammer@mail.ru"

#property indicator_chart_window

#property indicator_buffers 2
#property indicator_color1 Aqua
#property indicator_color2 Magenta

extern int period =  14;
extern int    adjustment_factor  = 50;
extern double adjustment_percent = 0.1;

double Buffer0[];
double Buffer1[];

int init()
{
  SetIndexStyle(0,DRAW_LINE,0,3);
  SetIndexBuffer(0,Buffer0);
  SetIndexEmptyValue(0,0.0);

  SetIndexStyle(1,DRAW_LINE,2);
  SetIndexBuffer(1,Buffer1);
  SetIndexEmptyValue(1,0.0);

  IndicatorShortName("CandleType"); 

  SetIndexLabel(0,"Main Line");
  SetIndexLabel(1,"Signal Line"); 

  return(0);
}

int start()
 {
  int    counted_bars=IndicatorCounted();
  if(counted_bars<0) return(-1);
  if(counted_bars>0) counted_bars--;

  for(int i=Bars-counted_bars; i>=0; i--)
  {
     Buffer0[i] = iMA(Symbol(), Period(), period, 0, 0, 4, i);

     double adjustment = 0;
     for(int j=i; j<i+adjustment_factor; j++)
        adjustment += iCustom(Symbol(), Period(), "MyIndicator1", 0, j) * (High[j]+Low[j])/2 * adjustment_percent/100;
     Buffer1[i] = Buffer0[i] + adjustment;
  }
  return(0);
 }
//+------------------------------------------------------------------+



Рис. 1 - Пример работы индкатора

 

Устройство индикатора

Данный индикатор устроен весьма интересным образом. У него есть два буфера:

 

#property indicator_buffers 2
#property indicator_color1 Aqua
#property indicator_color2 Magenta
...
double Buffer0[];
double Buffer1[];

Буферы заполняются следующим образом:

 

Буфер Buffer0[]

 

Buffer0[i] = iMA(Symbol(), Period(), period, 0, 0, 4, i);

В первый буфер (синий) просто переписываются показания индикатора Mooving Average.

 

Буфер Buffer1[]

 

      double adjustment = 0;
     for(int j=i; j<i+adjustment_factor; j++)
        adjustment += iCustom(Symbol(), Period(), "MyIndicator1", 0, j) * (High[j]+Low[j])/2 * adjustment_percent/100;
     Buffer1[i] = Buffer0[i] + adjustment;

А вот второй буфер (розовый) устроен гораздо интересней! Его показания представляют собой откорректированные значения Mooving Average. Для корректировки используются последние 50 (этот параметр задается переменно adjustment_factor) баров. Для каждого бара мы смотрим - был он медвежьим или бычьим.

 

  • Если бар бычий, то он увеличивает корректировку на 1% (параметр adjustment_percent) своей медианной цены ((High[j]+Low[j])/2).
  • Если бар медвежий, то он уменьшает корректировку на 1% (параметр adjustment_percent) своей медианной цены ((High[j]+Low[j])/2).

 

PS: корректировка может быть как положительной (вверх), так и отрицательной (вниз) - в зависимости от того, какое значение было рассчитано по указанному принципу.

 

Как видите, при рассчете второго буфера мы используем индикатор "MyIndicator1" из прошлого урока:

adjustment += iCustom(Symbol(), Period(), "MyIndicator1", 0, j) * (High[j]+Low[j])/2 * adjustment_percent/100;

Надеюсь, Вы помните, почему обращение к этому индикатору записывается именно так, и что означает параметр "j", передываемый в качестве последней переменной. Если нет - обратитесь к предыдущему уроку.

Советую Вам откомпилировать данный код у себя на компьютере и запустить индикатор в своем терминале, чтобы посмотреть, как он работает. Поэкспериментируйте с входными параметрами. Помните, что индикатор из предыдущего урока тоже должен присутствовать в папке /experts/indicators, иначе новый индикатор работать не будет. Если у Вас возникают сложности, или Вы недостаточно хорошо понимаете, как написан код индикатора, я советую Вам перечитать уроки 10-12 "Ваш первый индикатор".

 

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

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

post-50854-1404216698,7565_thumb.gif

Share this post


Link to post
Share on other sites
Programmer

Урок 69 - Устаревшие Функции

 

Приветствую, друзья!

Сегодня мы немного отдохнем от iCustom(). Думаю, Вам не помешает небольшой перерыв, чтобы потренироваться с уже обретенными знаниями вызова пользовательских индикаторов. С iCustom() мы продолжим на следующих уроках, а сейчас мы рассмотрим достаточно простую, но относительно важную тему - Устаревшие Функции.

 

Часто нам приходится разбирать код того или другого советника и индикатора, и бывают случаи, когда мы можем натолкнуться на неизвестную нам функцию. Функция используется в коде, а ее инициализации там нет. Также ее нет ни в одном из импортируемых в код файлов. Более того, эта функция не подсвечивается редактором MetaEditor, а когда мы ее выделяем и нажимаем F1 (для вызова справки) - ничего не происходит! Что за чудеса?!

 

Не пугайтесь, если Вы оказались в подобной ситуации - просто Вы наткнулись на устаревшую функцию!

Устаревшие функции, действительно, не подсвечиваются и не связаны со справкой MetaEditor. Эти функции имеют новые названия, но при этом старые названия функций можно использовать, так как компилятор правильно их воспримет.

 

Ниже приведен список устаревших функций и их новых названий:

 



Рис. 1 - Устаревшие Функции

 

Надеюсь, урок показался Вам полезным. В следующий раз мы продолжим изучение iCustom().

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

post-50854-1404216726,3339_thumb.gif

Share this post


Link to post
Share on other sites
Programmer

Урок 70 - Функция iCustom() (Часть 4)

 

Приветствую читаталей!

Сегодня мы продолжим работу с функцией iCustom(). Как обычно, сразу вспомним ее синтаксис:

 

double iCustom(     string symbol, int timeframe, string name, ..., int mode, int shift)

Как Вы помните, в Уроке 68 "Функция iCustom() (Часть 3)" мы рассмамтривали код индикатора "MyIndicator2", который использовал индикатор встроенный "Mooving Average" и индикатор "MyIndicator1", который мы написали в Уроке 69 "Функция iCustom() (Часть 2)".

Для сегодняшнего урока Вам необходимо удостовериться, что оба индикатора ("MyIndicator1" и "MyIndicator2") откомпилированы и находятся в папке /experts/indicators на Вашем компьютере.

 

Код советника, который мы будем разбирать:

 

//+------------------------------------------------------------------+
//|                                                    MyExpert2.mq4 |
//|                                Copyright © 2011, StockProgrammer |
//|                                          StockProgrammer@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, StockProgrammer"
#property link      "StockProgrammer@mail.ru"

extern int StopLoss = 50;
extern int TakeProfit = 50;

extern int    period =  18;
extern int    factor  = 70;
extern double percent = 0.15;

int ticket = 0;

int start()
{
  CheckTicket();
  if(ticket == 0)
  {
     double MyIndicator2_MAIN_1 = iCustom(Symbol(), Period(),"MyIndicator2",  period, factor, percent, 0, 1);
     double MyIndicator2_MAIN_2 = iCustom(Symbol(), Period(), "MyIndicator2",  period, factor, percent, 0, 2);
     double MyIndicator2_SIGNAL_1 = iCustom(Symbol(), Period(), "MyIndicator2",  period, factor, percent, 1, 1);
     double MyIndicator2_SIGNAL_2 = iCustom(Symbol(), Period(), "MyIndicator2",  period, factor, percent, 1, 2);

     if(MyIndicator2_SIGNAL_2 < MyIndicator2_MAIN_2 && MyIndicator2_SIGNAL_1 >= MyIndicator2_MAIN_1)
        ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, Bid-StopLoss*Point, Bid+TakeProfit*Point, "ICustomTest2");
     if(MyIndicator2_SIGNAL_2 > MyIndicator2_MAIN_2 && MyIndicator2_SIGNAL_1 <= MyIndicator2_MAIN_1)
        ticket = OrderSend(Symbol(), OP_SELL, 0.1, Bid, 3, Ask+StopLoss*Point, Ask-TakeProfit*Point, "ICustomTest2");      
  }
  return(0);
}


void CheckTicket()   //функция контроля переменной ticket
{
  int res;
  if(ticket != 0)
  {
     res = OrderSelect(ticket, SELECT_BY_TICKET);
     if(res!=0)
     {
        if(OrderCloseTime() != 0)
           ticket = 0;
     }
     else
        ticket = 0;     
  }


}



Рис. 1 - Пример работы советника

 

Попробуйте понять устройство и принцип работы данного советника самостоятельно, в следующем уроке мы я поясню, как он работает и Вы сможете себя проверить! Надеюсь, у Вас получится. Если возникнут трудности - обратитесь к урокам 13-17 "Ваш первый советник".

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

post-50854-1404216739,5909_thumb.gif

Share this post


Link to post
Share on other sites
Programmer

Урок 71 - Функция iCustom() (Часть 5)

 

Приветствую всех, друзья!

Надеюсь, Вы поразбирались с советником из предыдущего урока, потому что сегодня мы будем сравнивать результаты!

Итак, код советника, Вы можете смотреть в предыдущем уроке, а синтаксис iCustom() я напомню:

 

double iCustom(     string symbol, int timeframe, string name, ..., int mode, int shift)

Больше всего в данном советнике нас интересует блок кода с iCustom():

 

      double MyIndicator2_MAIN_1 = iCustom(Symbol(), Period(),"MyIndicator2",  period, factor, percent, 0, 1);
     double MyIndicator2_MAIN_2 = iCustom(Symbol(), Period(), "MyIndicator2",  period, factor, percent, 0, 2);
     double MyIndicator2_SIGNAL_1 = iCustom(Symbol(), Period(), "MyIndicator2",  period, factor, percent, 1, 1);
     double MyIndicator2_SIGNAL_2 = iCustom(Symbol(), Period(), "MyIndicator2",  period, factor, percent, 1, 2);

Здесь мы 4 раза обращаемся к индикатору "MyIndicator2". Мы запрашиваем расчет этого индикатора на том же графике, на котором запущен советник (параметры: Symbol(), Period()). В индикатор мы передаем три параметра: period, factor, percent - которые индикатор воспринимает (уже внутри себя) как period, adjustment_factor, adjustment_percent (но это нас уже не волнует).

Почему 4 раза? Потому что у этого индикатора имеется 2 буфера, и мы хотим знать значения каждого из них на двух барах (предыдущем и пред-предыдущем) 2x2 - итого 4. Напомню, что предпоследний параметр - это номер буфера (у нас: 0 - MAIN, 1 - SIGNAL), а последний - это сдвиг относительно правого конца буфера.

 

Вот так достаточно просто расщепляется весь блок работы с iCustom(). Возвращаемые значения мы сохраняем в локальные переменные и делаем с ними все, что хотим.

Как Вы, навреное, догадались из рисунка в предыдущем уроке, советник открывает сделки при пересечении синей и розовой линий. Это отображено в следующей части кода:

 

      if(MyIndicator2_SIGNAL_2 < MyIndicator2_MAIN_2 && MyIndicator2_SIGNAL_1 >= MyIndicator2_MAIN_1)
        ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, Bid-StopLoss*Point, Bid+TakeProfit*Point, "ICustomTest2");
     if(MyIndicator2_SIGNAL_2 > MyIndicator2_MAIN_2 && MyIndicator2_SIGNAL_1 <= MyIndicator2_MAIN_1)
        ticket = OrderSend(Symbol(), OP_SELL, 0.1, Bid, 3, Ask+StopLoss*Point, Ask-TakeProfit*Point, "ICustomTest2");     

Попробуйте сохранить у себя этот код и запустить советник в тестере. Посмотрите, как он будет работать - можете заодно закинуть на график тестера индикаторы "MyIndicator1" и "MyIndicator2" (параметры укажите те же, что укажите в советнике) и проследите, что сделки совершаются правильно! Помните, что хоть советник и не обращается напрямую к "MyIndicator1", обращение к этому индикатору происходит изнутри индикатора "MyIndicator2", так что индикатор "MyIndicator1" влияет на торговлю советника. Как все хитро-то, а? :D

 

Надеюсь, что материал понятно изложен! Эти 5 уроков должны достаточно хорошо объяснять основы и все ньюансы работы с iCustom() - очень полезным и нужным инструментом в руках программиста MQL4.

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 72 - Клиентский терминал

 

Здравствуйте, друзья!

Сегодня будет легкий урок, заслуженный после эпопеи iCustom(), длившейся целых пять уроков!

Ниже мы рассмотрим информмативные функции, уведомляющие программу о параметрах клиентского терминала: название компании, название терминала и имя директории, из которой запущен терминал.

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

 

 

1 - TerminalCompany()

 

Синтаксис:

string TerminalCompany( )

 

Описание:

Возвращает наименование компании-владельца клиентского терминала.

 

Параметры:

- отсутствуют -

 

 

2 - TerminalName()

 

Синтаксис:

string TerminalName( )

 

Описание:

Возвращает имя клиентского терминала.

 

Параметры:

- отсутствуют -

 

 

3 - TerminalPath()

 

Синтаксис:

string TerminalPath( )

 

Описание:

Возвращает директорий, из которого запущен клиентский терминал.

 

Параметры:

- отсутствуют -

 

 

Надеюсь, что Вам когда-нибудь пригодяться эти функции.

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 73 - OrderCloseBy()

 

Здравствуйте, друзья!

Недавно получил такой вопрос:

"Kirill, Объясни, пожалуйста, работу ф-ии OrderCloseBy(), и откуда брать 2-й тикет."

 

Итак, сегодня мы разберем функцию OrderCloseBy():

 

Синтаксис:

bool OrderCloseBy( int ticket, int opposite, color Color=CLR_NONE)

 

Описание:

Закрытие одной открытой позиции другой позицией, открытой по тому же самому инструменту, но в противоположном направлении. Возвращает TRUE при успешном завершении функции. Возвращает FALSE при неудачном завершении функции. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError().

 

Параметры:

ticket - Уникальный порядковый номер закрываемого ордера.

opposite - Уникальный порядковый номер противоположного ордера.

Color - Цвет стрелки закрытия на графике. Если параметр отсутствует или его значение равно CLR_NONE, то стрелка на графике не отображается.

 

Функция достаточно проста в обращении и используется для закрытия локированных ордеров. Например, если у Вас есть открытые ордера по EURUSD: ticket1 BUY 0.1 лот и ticket2 SELL 0.1 лот. Вместо того, чтобы их закрывать поотдельности, их можно закрыть через OrderCloseBy():

 

OrderCloseBy(ticket1,ticket2);

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

Надеюсь, что Вы найдете полезной эту функцию.

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 74 - Управление Капиталом (Часть 1)

 

Приветствую, уважаемые читатели!

Сегодняшний и несколько последующих уроков будут посвящены одной из наиважнейших тем в торговле - теме управления капиталом (манименеджмент). Для начала, мы рассмотрим теоретические аспекты и определим понятия, которыми мы будем оперировать, затем, я планирую разобрать несколько известных примеров изящных алгоритмов управления капиталом, а в заключение мы напишем несколько блоков кода для наших советников.

 

Итак, начнем!!

 

Управление Капиталом / Манименеджмент (англ. Money management) — процесс управления деньгами (личным капиталом). Мани-менеджмент включает в себя инструменты, приёмы и методы для приумножения (страхования, выгодного перераспределения) средств инвестирования, банковских сбережений, налогов и расходования бюджета.

Wikipedia

 

Глобально манименеджмент разделяется на два уровня - стратегический манименеджмент и тактический манименеджмент.

 

Стратегический манимеджмент мы рассматривать не будем, но для общего развития я скажу пару слов о том, что это такое. Данный уровень управления капиталом является весьма долгосрочным и включает в себя такие элементы, как выбор валюты, в которой будет храниться депозит, исследование макроэкономических показателей для фильтрации торгуемых валют, чтобы при входе в долгосрочные позиции минимизировать потери возникающие из-за падения покупаемой валюты. Также, некоторые инвесторы (особенно институциональные инвесторы) уделяют огромное внимание таким элементам стратегического манименеджмента, как хеждирование позиций.

 

Тактический манимеджмент

Именно этот вид манименеджмента мы будем рассматривать в данном курсе. Подобное управление капиталом акцентирует внимание на кажддой конкретной сделке: размер лота, величина стоп-лосса - вот основные параметры, с которыми мы будем играться ;)

 

Существует множество методов управления капиталом. Ниже представлены самые известные из них:

1. Метод Фиксированного лота - все позиции открываются некоторым постоянным количеством лотов (объёмом), определенным заранее (т.е., например 0.1, или 1, или 2.5, 10, 1000 и т.д. лотов - причем независимо от исхода предыдущего трейда, текущего размера депозита и других текущих показателей торговли).

2. Фиксированный процент (Ларии Вильямс (Larry Williams)) - в каждой сделке рискуем неким заранее выбранным, фиксированным процентом имеющегося депозита.

3. Фиксированная пропорция (Райан Джонс (Ryan Jones)) - вариант фиксировано-фракционной системы.

4. Торговля всем капиталом - тактика управления капиталом, согласно которой в каждой очередной сделке открываемся максимально возможным количеством лотов.

5. Мартингейл - удваивание позиции при понесении убытка

 

В заключение данного урока скажу, что, с моей точки зрения, современные трейдеры уделяют слишком мало внимания мани-менеджменту. Все сконцентрированы на стратегиях входа-выхода, которые, действительно, важны, но стратегия управления капиталом ровно столь же важна и является мощным оружием в арсенале умелого трейдера. Это будет более наглядно продемонстрировано, когда мы будем говорить о стратегии Райана Джонса.

 

Надеюсь, что Вы найдете полезным данный урок.

В следующий раз мы разберем стратегию управления капиталом Ларии Вильямса.

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 75 - Управление Капиталом (Часть 2)

 

Приветствую, друзья!

Сегодня мы разберем стратегию управления капиталом от Ларри Вильямса.

 

Формула Келли — формула, которая показывает оптимальную долю капитала, которой можно рискнуть в одной

 

сделке. Применяется в управлении капиталом при игре на финансовых рынках, в азартных играх и др.

 

Рассматривается следующая ситуация. Участник при каждой сделке может с вероятностью p получить прибыль в A раз

 

превышающую поставленный капитал x или с вероятностью q = 1 - p получить убыток в B раз превышающий ставку

 

x. Ставится задача — какую долю общего капитала K надо каждый раз ставить, чтобы максимизировать среднюю величину

 

логарифма прибыли при большом числе повторяемых сделок.

 

Обозначим долю капитала f = x / K.

 

Формула Келли гласит, что оптимальное значение:

 

 

 

(предполагается, что математическое ожидание сделки положительно, то есть pA - qB > 0).

 

Метод дробной части

 

Наиболее известными способами оценки рисков, основанными на определении некоторой фиксированной доли торгового

 

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

Формула Келли связывает величину риска на одну сделку со статистическими параметрами торговой стратегии следующим

 

выражением:

 

f = P - (1-P)/(W/L),

 

где f - часть капитала, которой можно рисковать в одной сделке, P - доля выигрышных сделок, W- средний размер

 

выигрыша и L - средний размер проигрыша.

Например, для системы, которая дает 65% выигрышей и показывает отношение W/L=1, можно получить f = 0,3

 

.

Таким образом, процент активов, который обеспечил бы максимальную отдачу - 30%.

Основным недостатком формулы Келли является ее неполное соответствие практике торговли. Формула Келли хорошо

 

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

 

остается одинаковым в отношении поставленной суммы. В торговле размеры и выигрышей и проигрышей постоянно

 

меняются, т.е. формула Келли не вполне адекватна для описания и оценки допустимых рисков при торговых стратегиях.

Для случая, когда величина выигрыша и проигрыша переменная, можно воспользоваться следующей оценкой минимального

 

размера капитала K(1), позволяющего торговать одним стандартным контрактом:

 

f = P - (1-P)/(W/L) =L/K(1),

 

откуда следует

 

K(1)=L*W/(PW-(1-P)L).

 

Более жесткое ограничение можно получить, если использовать не среднее значение потерь L, а максимальный

 

полученный при тестировании на истории (или при системной торговле в прошлом) убыток Lmax:

 

K(1)=Lmax*W/(PW-(1-P)L).

 

Модификацию формулы Келли для управления капиталом при торговых операциях разработал Ральф Винс (Ralph

 

Vince) и назвал ее формулой для fopt.

Метод Винса основан на достаточно сложном расчете величины fopt путем последовательных приближений на основании

 

серии сделок, характеризующих некоторую торговую систему.

Главная проблема при использовании как f, полученного с помощью формулы Келли, так и fopt, рассчитанного по методу

 

Винса, это просадки (дродаун). Наращивание количества торгуемых контрактов с ростом прибыли происходит достаточно

 

быстро, но тем быстрее последующее уменьшение торгового счета при серии убыточных сделок. Если учесть, что даже

 

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

 

подряд, то риск слишком высоким процентом от капитала может привести к катастрофическим последствиям для торгового

 

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

 

Винса, риски.

В частности, формула, применяемая для оценки допустимых рисков Л.Вильямсом, имеет вид:

 

n = f*K/Lmax,

 

где n - число торгуемых контрактов, f - процент риска, K - текущий остаток на торговом счете, Lmax - самый большой

 

проигрыш на одну сделку (один контракт).

Величина f может быть определена из формулы Келли или по методу Винса, но обычно принимается не более 25%.

 

Метод Ларри Вильямса

 

Л.Вильямс рекомендует использовать пределы величины f от 5% при консервативном стиле управления капиталом, 10-15%

 

при повышенном уровне риска и до 20% и более при рискованных торговых стратегиях.

Если торговая стратегия в качестве составного элемента содержит правила определения риска для каждой конкретной

 

сделки, то аналогичная формула будет иметь вид:

 

n = f*K/Lo,

 

где n - число контрактов для данной сделки, f - процент риска, K - текущий остаток на торговом счете, Lo - текущий

 

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

 

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

 

возможного убытка по данной транзакции.

 

Надеюсь, что Вы найдете полезным данный урок.

В следующий раз мы разберем практический пример применения метода Ларии Вильямса, а также обсудим более детально преимущества и недостатки метода.

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

  • Thanks 1

Share this post


Link to post
Share on other sites
Programmer

Урок 76 - Управление Капиталом (Часть 3)

 

Всех приветствую!

Продолжим обсуждение метода управления капиталом, придуманного Лари Вильямсом. Напомню основную формулу:

 

n = f*K/Lmax

 

Здесь n - число торгуемых контрактов, f - процент риска, K - текущий остаток на торговом счете, Lmax - самый большой проигрыш на одну сделку (один контракт).

 

Для наглядности предлагаю посчитать, какой результат даст нам эта формула в случае постоянного стоп-лосса:

Если Вы в каждой сделке используете один и тот же S/L, то, очевидно, max проигрыш будет ~ лоту. Возьмём S/L = 40 для примера:

 

Lmax = S/L * (цена 1 пункта) = 40 * 0.0001 * n * 100 000 [GBP] = 40 * 10 * n [GBP] = 40 * 10 * n * 1.5961 [uSD] = 63.8 * n [uSD]

 

где 0.0001 - 1п. для GBP/USD (для примера),

n - кол-во лотов,

100 000 - размер одного контракта (лота)

 

подставляем в ф-лу Вильямса:

 

n = f*K/Lmax

 

получаем:

 

n = f*K / (40 * 0.0001 * n * 100 000 * 1.5961)

 

преобразуем:

 

n^2 = f*K/638

 

n = sqrt (f*K/638)

 

берём f = 0,2 (20%)

 

n= sqrt(0.0003 * K)

 

Таким образом, мы получили интересный результат - при использовании постоянного S/L метод Ларри Вильямса подразумевает, что кол-во лотов, торгуемых в одной позиции, пропорционально КОРНЮ из текущего размера депозита.

 

Например, при K=10000$, имеем:

 

n=sqrt(0,0003*10000) = sqrt(3) = 1.73 лота

 

При кредитном плече 1:100 это вполне приемлимо (мы можем единовременно купить до 10 лотов при таком плече).

 

Вот так можно применять метод Ларри Вильямса на практике. Давайте теперь обсудим преимущества и недостатки метода Ларри Вильямса. Основное и самое очевидное преимущество - экспоненциальный рост депозита. Для сравнения ниже приведены результаты тестов одного и тоже советника:

 

1. Тест без ММ Ларри Вильямса

 

post-50854-1404217453,1453_thumb.gif

 

2. Тест без ММ Ларри Вильямса

 

post-50854-1404217453,1961_thumb.gif

 

Как видите, добавление ММ Ларри Вильямса превращает линейный рост депозита в экспоненциальный. В данном случае результат 591-й сделки был улучшен в 23 раза! Тем не менее, необходимо отметить, что за такой бешеный рост депозита приходится платить дорогой ценой. При использовании ММ Ларри Вильямса абсолютная величина потенциальной убыточности каждой сделки также растет экспоненциально:

 

post-50854-1404217453,2293_thumb.gif

 

Надеюсь, что Вы найдете полезным данный урок.

В следующем уроке мы обсудим, почему данная конфигурация, присущая ММ Ларри Вильямса, на самом деле во много много раз опасней чем кажется на первый взгляд!

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 77 - Управление Капиталом (Часть 4)

 

Приветствую, друзья!

Сегодня мы порассуждаем на очень Важную тему - скрытый риск метода управления капиталом Ларри Вильямса.

 

Как я писал в предыдущем уроке, при использовании ММ Ларри Вильямса (ММЛВ) с фиксированными SL и TP мы имеем:

 

  • Потенциальный лосс сделки растет пропорционально балансу счета: Potential.Loss ~ B
  • Потенциальный профит сделки растет пропорционально балансу счета: Potential.Profit ~ B

 

 

Отсюда, вероятно, Вы сделаете вывод, что потенциальный лосс сделки и потенциальный профит растут пропорционально:

 

  • Potential.Loss ~ Potential.Profit

 

 

И Вы будете НЕПРАВЫ!

То, что потенуиальный лосс и профит растут одинаково - визуальный обман!

Давайте разберемся подробнее. Дело в том, что когда лосс наступит... Секунду...

 

Поясню. давайте будем реалистичными - все наши советники не граали, а статистичкеские алгоритмы основанные на двух фундаментальных принципах:

1. Количество и размер прибыльных и убыточных сделок находятся в таком балансе, что мат. ожидание больше нуля

2. Количество сделок очень большое

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

Именно поэтому, я могу уверенно, что убыточная сделка (лосс) рано или поздно наступит в любой системе.

 

Вернемся к ММЛВ. Итак, когда лосс наступит, он будет после всех предыдущих профитов, в том числе и после самого последнего профита - а значит, он будет больше него! Подробнее: допустим, у нас было N профитов, а N+1-ая сделка - это лосс. Профиты 1,2,3,...,N-1 увеличили депозит и внесли свой вклад в увеличиние N-ого профита. Теперь посмотрим на лосс - профиты 1,2,3,...N-1,N внесли вклад в увеличение лосса, который принесла N+1-я сделка. А т.к. сами профиты тоже растут экспоненциально, то лосс будет намного больше последнего профита!

 

Именно в такую ловушку часто попадают новчики, и поэтому я не рекомендую использовать ММЛВ. Есть намного менее рискованный метод управления капиталом, который как и ММЛВ значительно лучше, чем отсутствие управления капиталом. Этот метод называется Фиксировано-пропорциональный метод (метод Райана Джонса) и мы его обсудим в следующий раз!

 

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

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 78 - Управление Капиталом (Часть 5)

 

Всем привет!

Сегодня будет весьма интересный урок! Мы познакомимся с методом управления капиталом Райана Джонса (РД) и сравним его с уже изученным методом управления капиталом Ларри Вильямса (ЛВ).

 

Метод РД также носит название "фиксированно-пропорциональный метод" и представляет собой ступенчатое увеличение риска по мере роста депозита. Данный метод подробно описан в книге Райана Джонса «Биржевая Игра – сделай миллионы играя числами».

 

post-50854-1404217497,8726_thumb.jpg

Рис.1 - Книга Райана Джонса

 

Райан Джонс – трейдер высшего класса, практически не уделяющий внимания ни техническому, ни фундаментальному анализу. Весь упор в своей торговле и исследованиях он делает исключительно на грамотном управлении капиталом. По его словам – «Управление капиталом – это 90% торговли».

 

Метод, предложенный Райаном Джонсом в качестве попытки "обойти многочисленные недостатки" системы фиксированного % ММ. Согласно т.н. фиксированно-пропорционного метода Джонса, для того, чтобы к уже имеющемуся количеству лотов прибавить ещё один, каждый из уже имеющихся должен "заработать" некое кол-во пунктов (последнее Джонс назвал "дельтой").

Например, если у нас есть депо в $1,000 и мы работаем 0.1 лотом, определив дельту равной, допустим, $1,000, мы перейдем на 0.2 лота, когда наберем (имеющимся 0.1 лотом) $1,000, а увеличение количества лотов до 0.3 произойдет только когда теперь уже 0.2 лота заработают – каждый – по дельте ($1,000) (т.е. переход с 0.2 на 0.3 будет, когда мы к имеющимся $2,000 добавим ещё 2 х $1,000 = $2,000, т.е. при балансе $4,000), с 0.3 на 0.4 лота – при депо в $4,000 + ($1,000 х 3) = $7,000 и т.д. Таким образом, "по мере роста числа контрактов сумма, необходимая для приобретения очередного кол-ва контрактов, увеличивается пропорционально", откуда и название метода. Ниже представлена таблица расчетов:

 

post-50854-1404217497,9054_thumb.gif

Рис.2 - Таблица расчетов метода РД

 

В таблице также представлен риск, который при постоянном SL пропорционален торгуемому лоту. В контексте данной статьи понятиями "лот" и "риск" мы будем пользоватсья взаимозаменяемо. Для наглядности я подготовил график, который должен все объяснить:

 

post-50854-1404217497,9395_thumb.gif

Рис.3 - Графическая иллюстрация ступенчатости метода

 

На Рис.3 синяя линяя - это метод Райна Джонса, а зеленым пунктиром обозначена линия аппроксимирующая метод РД. Заметьте, что на этом графике по оси X отложен текущий депозит, а по оси Y - лот (риск). Из данного графика видно, что метод РД аппроксимируется функцией подобной корню X. Т.е. риск растет, как примерно корень из депозитп (это грубая аппроксимация).

 

Теперь сравним риск в методе РД с риском в методе ЛВ:

 

post-50854-1404217497,967_thumb.gif

Рис.4 - Графическое сравнение рисков методоа ЛВ и РД

 

Как видите, торгуемый лот в методе ЛВ растет пропорционально депозиту, что весьма рискованно и одновременно намного быстрее, чем в методе РД.

Обращу Ваше внимание на то, что "риск" в данном случае вовсе не означает "плохо". Больший риск может принести как большую прибыль, так и больший убыток. Все зависит от того, какой Вы трейдер, и на какие риски готовы идти.

 

На сегодня все. Надеюсь, что Вы найдете полезным данный урок.

В следующий раз мы построим небольшую модели и сравним прибыльности стратегий Ларри Вильямса и Райана Джонса.

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 79 - Управление Капиталом (Часть 6)

 

Всем привет!

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

 

Модель

Мы рассмотрим три стратегии ММ: постоянный лот (отсутствие ММ), стратегия Райана Джонса (дельта 1000 - как в примере из урока 78) и стратегия Ларри Вильямса (риск - 25%). Начальный депозит во всех трех случаях $1,000. В целях этого эксперимента мы будем считать, что каждая сделка прибыльная. Модель будет состоять из 25 последовательных сделок. Наша задача - сравнить, как растет депозит во всех трех случаях.

 

post-50854-1404217694,6852_thumb.gif

Рис.1 - Модель из 25-ти шагов

 

Теперь давайте посмотрим на график роста балансов. Для начала сравненим результаты метода Райна-Джонса и метода постоянного лота:

 

post-50854-1404217694,7097_thumb.gif

Рис.2 - ММРД и постоянный лот

 

Как видим, в случае постоянного лота депозит растет линейно, а в случае ММРД депозит растет намного быстрее (замечу - не экспоненциально). Это естетвенно, т.к. в случае постоянного лота ММ отсутвует и мы просто-напросто не увеличиваем лот, поэтому каждая сделка приносит нам одну и ту же сумму прибыли. А в случае ММРД лот увеличивается поэтапно, отсюда и соответствующие изломы в линии баланса - при каждом увеличении лота кривая становится все круче. Также можно заметить, что изломы становятся все реже при росте депозита - данный феномен находится в согласии с концепцией Райана Джонса о падении частоты увеличения лота (см. рис.3 в Уроке 78).

 

Теперь сравним все три метода на одном графике:

 

post-50854-1404217694,7609_thumb.gif

Рис.3 - ММЛВ, ММРД и постоянный лот

 

Сразу бросается в глаза, что ММЛВ уже после 10й сделки забивает оба ММРД и Линейный Метод!! Это потому что при ММЛВ депозит растет экспоненциально! Вы думали, что в предыдущем изображении ММРД крут (в смысле наклона), но как оказывается результат ММРД пренебрежимо мал по сравнению с ММЛВ. Вот наглядный пример того, насколько экспонента сильнее многочленов.

 

При этом, надо помнить, что больший лот означает больший риск, и хоть со стороны роста депозита ММЛВ и выглядит очень привлекательно, за это приходится платить огромную цену в плане риска. Поэтому я не рекомендую ММЛВ. Лично я сторонник ММРД.

 

Надеюсь, что Вы найдете полезным данный урок.

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

Edited by Programmer

Share this post


Link to post
Share on other sites
Programmer

Урок 80 - Управление Капиталом (Часть 7)

 

Приветствую, друзья!

 

Мы долго обсуждали преимущества и недостатки различных методов манименеджмента. Мы сравнили метод постоянного лота, стратегию Ларри Вильямса (ЛВ) и стратегию Райна Джонса (РД). Уверяю Вас, что существует великое множество самых разнообразных стратегий управления капиталом и, соответственно, как мы выяснили, - риском. Я считаю, что примеров ЛВ и РД достаточно, чтобы понять, чем могут различаться подходы к риску, и на какие аспекты надо обращать внимание при выборе стратегии манименеджмента для своей торговли.

 

Сегодня мы, накоец-то, рассмотрим код модуля управления капиталом. Несмотря на то, что метод ЛВ более рисковый, чем метод РД, метод ЛВ концептуально более прост. С моей точки зрения лучше рассмотреть код реализации метода ЛВ, потому что большинству читателей будет проще его понять.

 

Итак, модуль управления капиталом ЛВ. Первый блок необходимо добавить в верхнюю часть советника - туда, где описываются все внешние переменные (extern).

 

extern string  L1                   = "Настройки Larry Williams Method";
extern bool    LarryWilliamsMethod  = false; // использовать метод управления капиталом Ларри Вильямса
extern double  LWrisk               = 10;    // [%] процент риска. определяется трейдером. рекомендуется от 5% до 20%
extern double  LWpart               = 100;   // [%] какая часть депозита отводится в распоряжение данного робота
extern double  LossMax              = 1000;  // Макс. потеря на 1лот. В USD. PS: если валюта депозита != USD - надо переделывать
extern string  L2                   = "-------------------------------";

 

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

 

//--------------------------------------- LarryWilliams ---------------------------------
double LarryWilliams()
{
  double xlots;
  double LotMin  = MarketInfo(Symbol(), MODE_MINLOT);
  double LotMax  = MarketInfo(Symbol(), MODE_MAXLOT);
  double LotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
  xlots  = (LWpart / 100) * AccountBalance() * (LWrisk / 100) / LossMax;
  xlots = MathRound(xlots / LotStep)  * LotStep;
  if(xlots == 0) Print("Not enough funds to open order");
  else if(NormalizeDouble(xlots-LotMin,2) < 0) {Print("Rounding lot up to LotMin"); xlots = LotMin;}
  else if(NormalizeDouble(xlots-LotMax,2) > 0) {Print("Rounding lot down to LotMax"); xlots = LotMax;}
  return (xlots);
}

 

Модуль управления капиталом устроен следующим образом. Пользователь вводить параметры (extern) при запуске советника, а функция LarryWilliams() обрабатывает эти параметры и принимает соответсвующее решение, когда ее вызывают. Для того, чтобы советник управлял капиталом по методу ЛВ, необходимо каждый раз при выставлении ордера вызывать функцию LarryWilliams(). Например:

 

...
double Lot=0.1;
if(LarryWilliamsMethod  == True)
  Lot = LarryWilliams();
OrderSend(Symbol(), OP_BUY, Lot, Ask, slip, Bid-SL*Point, Bid+TP*Point, "Test", Magic);
...

 

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

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 81 - Операции с графиками

 

Здравствуйте, уважаемые читатели!

 

Сегодня мы немного отдохнем от исследования методов управления капиталов и разберем более простую тему. Мы познакомимся с функциями, предназначенными для работы с окном текущего графика. Данные функции могут показаться полезными как в программировании советников, - например, всем известные функции Period() и Symbol(), - так и при написании индикаторов и скриптов, - например, функции WindowRedraw() и WindowOnDropped().

 

Начнем!

 

1 - HideTestIndicators()

 

Синтаксис:

void HideTestIndicators( bool hide)

 

Описание:

Функция выставляет флаг скрытия индикаторов, вызываемых экспертом. При открытии графика после тестирования индикаторы, помеченные флагом скрытия, не будут выведены на график тестирования. Перед каждым вызовом индикатор помечается текущим установленным флагом скрытия.

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

 

Параметры:

hide - TRUE - если нужно прятать индикаторы, иначе FALSE.

 

 

2 - Period()

 

Синтаксис:

int Period( )

 

Описание:

Возвращает значение числа минут периода для текущего графика.

 

Параметры:

- отсутствуют -

 

 

3 - RefreshRates()

 

Синтаксис:

bool RefreshRates( )

 

Описание:

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

 

Параметры:

- отсутствуют -

 

 

4 - Symbol()

 

Синтаксис:

string Symbol( )

 

Описание:

Возвращает текстовую строку с именем текущего финансового инструмента.

 

Параметры:

- отсутствуют -

 

 

5 - WindowBarsPerChart()

 

Синтаксис:

int WindowBarsPerChart( )

 

Описание:

Функция возвращает количество баров, помещающихся в окно текущего графика.

 

Параметры:

- отсутствуют -

 

 

6 - WindowExpertName()

 

Синтаксис:

string WindowExpertName( )

 

Описание:

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

 

Параметры:

- отсутствуют -

 

 

7 - WindowFind()

 

Синтаксис:

int WindowFind( string name)

 

Описание:

Возвращает номер подокна графика, содержащего индикатор с указанным именем name, если он найден, иначе возвращается -1.

WindowFind() возвращает -1, если пользовательский индикатор ищет сам себя в процессе инициализации init().

 

Параметры:

name - Короткое имя индикатора.

 

 

8 - WindowFirstVisibleBar()

 

Синтаксис:

int WindowFirstVisibleBar( )

 

Описание:

Функция возвращает номер первого видимого бара в окне текущего графика. Необходимо иметь в виду, что ценовые бары нумеруются задом наперед, от последнего к первому. Текущий бар, самый последний в ценовом массиве, имеет индекс 0. Самый старый бар имеет индекс Bars-1. Если номер первого видимого бара меньше, чем количество видимых баров на графике на 2 и более, это значит, что окно графика заполнено не до конца и имеется поле справа.

 

Параметры:

- отсутствуют -

 

 

9 - WindowHandle()

 

Синтаксис:

int WindowHandle( string symbol, int timeframe)

 

Описание:

Возвращает системный дескриптор окна (window handle), содержащего указанный график. Если график с symbol и timeframe на момент вызова функции не открыт, то возвращается 0.

 

Параметры:

symbol - Символ.

timeframe - Период. Может быть одним из периодов графика.

 

 

10 - WindowIsVisible()

 

Синтаксис:

bool WindowIsVisible( int index)

 

Описание:

Возвращает TRUE, если подокно графика видимо, иначе возвращает FALSE. Подокно графика может быть скрыто из-за свойств видимости помещенного в него индикатора.

 

Параметры:

index - Индекс подокна графика.

 

 

11 - WindowOnDropped()

 

Синтаксис:

int WindowOnDropped( )

 

Описание:

Возвращает индекс окна, в которое был брошен эксперт, пользовательский индикатор или скрипт. Это значение будет верным только в том случае, если эксперты, пользовательские индикаторы и скрипты прикреплены с помощью мыши (технология "drag and drop").

Для пользовательских индикаторов, находящихся в процессе инициализации (вызов из функции init()) этот индекс не определен.

Возвращаемый индекс является номером окна (0-главное окно графика, подокна индикаторов нумеруются с 1), в котором работает пользовательский индикатор. В процессе инициализации пользовательский индикатор может создать свое собственное новое подокно и его номер будет отличаться от номера окна, на которое действительно был брошен индикатор.

См. также WindowXOnDropped(), WindowYOnDropped()

 

Параметры:

- отсутствуют -

 

 

12 - WindowPriceMax()

 

Синтаксис:

double WindowPriceMax( int index=0)

 

Описание:

Возвращает максимальное значение вертикальной шкалы указанного подокна текущего графика (0-главное окно графика, подокна индикаторов нумеруются с 1). Если индекс подокна не указан, то возвращается максимальное значение ценовой шкалы главного окна графика.

 

Параметры:

index - Индекс подокна текущего графика (0 - основной график цены).

 

 

13 - WindowPriceMin()

 

Синтаксис:

double WindowPriceMin( int index=0)

 

Описание:

Возвращает минимальное значение вертикальной шкалы указанного подокна текущего графика (0-главное окно графика, подокна индикаторов нумеруются с 1). Если индекс подокна не указан, то возвращается минимальное значение ценовой шкалы главного окна графика.

 

Параметры:

index - Индекс подокна текущего графика (0 - основной график цены).

 

 

14 - WindowPriceOnDropped()

 

Синтаксис:

double WindowPriceOnDropped( )

 

Описание:

Возвращает значение цены в точке графика, на которой был брошен эксперт или скрипт. Значение будет верным только в случае, если эксперт или скрипт перемещены с помощью мыши (технология "drag and drop").

Для пользовательских индикаторов это значение не определено.

 

Параметры:

- отсутствуют -

 

 

(Продолжение в след. посте)

Share this post


Link to post
Share on other sites
Programmer

15 - WindowRedraw()

 

Синтаксис:

void WindowRedraw( )

 

Описание:

Принудительно перерисовывает текущий график. Обычно применяется после изменения свойств объектов.

 

Параметры:

- отсутствуют -

 

 

16 - WindowScreenShot()

 

Синтаксис:

bool WindowScreenShot( string filename, int size_x, int size_y, int start_bar=-1, int chart_scale=-1, int chart_mode=-1)

 

Описание:

Сохраняет изображение текущего графика в файле формата GIF. В случае неудачи возвращает FALSE. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError().

Скриншот сохраняется в папке каталог_терминала\experts\files (каталог_терминала\tester\files в случае тестирования эксперта) или ее подпапках.

 

Параметры:

filename - Имя файла для скриншота.

size_x - Ширина скриншота в пикселах.

size_y - Высота скриншота в пикселах.

start_bar - Номер первого видимого бара на скриншоте. Если указано значение 0, то скриншот снимается с текущего первого видимого бара. Если значение не указано, или указано отрицательное значение, то делается скриншот конца графика с учётом правого отступа.

chart_scale - Масштаб графика, выводимого на скриншот. Может принимать значение от 0 до 5. Если значение не указано, или указано отрицательное значение, то используется текущий масштаб графика.

chart_mode - Вид отображения графика. Может принимать значения: CHART_BAR (0 - последовательность баров), CHART_CANDLE (1 - японские свечи), CHART_LINE (2 - линия по ценам закрытия). Если значение не указано, или указано отрицательное значение, то график выводится в своем текущем виде.

 

 

17 - WindowTimeOnDropped()

 

Синтаксис:

datetime WindowTimeOnDropped( )

 

Описание:

Возвращает значение времени в точке графика, на которой был брошен эксперт или скрипт. Значение будет верным только в случае, если эксперт или скрипт перемещены с помощью мыши (технология "drag and drop").

Для пользовательских индикаторов это значение не определено.

 

Параметры:

- отсутствуют -

 

 

18 - WindowsTotal()

 

Синтаксис:

int WindowsTotal( )

 

Описание:

Возвращает количество окон индикаторов на графике, включая главное окно графика.

 

Параметры:

- отсутствуют -

 

 

19 - WindowXOnDropped()

 

Синтаксис:

int WindowXOnDropped( )

 

Описание:

Возвращает значение координаты по оси X в пикселах точки клиентской области окна графика, на которой был брошен эксперт или скрипт. Значение будет верным только в случае, если эксперт или скрипт перемещены с помощью мыши (технология "drag and drop").

 

Параметры:

- отсутствуют -

 

 

20 - WindowYOnDropped()

 

Синтаксис:

int WindowYOnDropped( )

 

Описание:

Возвращает значение координаты по оси Y в пикселах точки клиентской области окна графика, на которой был брошен эксперт или скрипт. Значение будет верным только в случае, если эксперт или скрипт перемещены с помощью мыши (технология "drag and drop").

 

Параметры:

- отсутствуют -

 

Надеюсь, что Вы найдете полезным данный урок.

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 82 - Управление Капиталом (Часть 8)

 

Добрый день, уважаемые читатели!

 

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

 

Итак, начнем!

 

Код:

extern string  L1                   = "Настройки Larry Williams Method";
extern bool    LarryWilliamsMethod  = false; // использовать метод управления капиталом Ларри Вильямса
extern double  LWrisk               = 10;    // [%] процент риска. определяется трейдером. рекомендуется от 5% до 20%
extern double  LWpart               = 100;   // [%] какая часть депозита отводится в распоряжение данного робота
extern double  LossMax              = 1000;  // Макс. потеря на 1лот. В USD. PS: если валюта депозита != USD - надо переделывать
extern string  L2                   = "-------------------------------";

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

 

 

  • L1 ничего не значит - она нужна только для того, чтобы пользователь увдидел текст "Настройки Larry Williams Method" в настройках советника.
  • LarryWilliamsMethod включает и выключает модуль. Если выставить значение "False", то советник не будет использовать метод ЛВ. Обработка данной переменной НЕ встроена в модуль ЛВ. Вам придется проверять значение данной переменной самостоятельно, как мы увидим позже.
  • LWrisk - процент риска. Это тот процент части депозита, доверенной советнику, который Вы готовы потерять при одной максимально убыточной сделке.
  • LWpart - часть депозита, доверенная советнику. Часть каждый раз рассчитывается исходя из значения депозита на момент вызова модуля.
  • LossMax - Вы должны рассчитать и прописать здесь максимальную потерю на одну сделку размером 1 лот, которую может принести Ваша торговая система.
  • L2 - как и переменная L1, эта переменная ничего не значит.

 

 

Второй блок кода.

//--------------------------------------- LarryWilliams ---------------------------------

Это просто комментарий в коде.

 

double LarryWilliams()

Описание функции. Она не требует никаких параметров и возвращает значение типа double.

 

   
  double xlots;

Эта переменная нам понадобятся для расчетов внутри функции.

 

   
  double LotMin  = MarketInfo(Symbol(), MODE_MINLOT);
  double LotMax  = MarketInfo(Symbol(), MODE_MAXLOT);
  double LotStep = MarketInfo(Symbol(), MODE_LOTSTEP);

Определяем значения ограничений счета и торгуемой валюты.

 

   
  xlots  = (LWpart / 100) * AccountBalance() * (LWrisk / 100) / LossMax;

Основной расчет. Мы рассчитываем лот так, чтобы даже при максимально убыточной сделке, потеря составила не более указанного процента от указанной части от текущего депозита. Здесь мы используем параметры, указанные пользователем в настройках и значение текущего баланса.

 

   
  xlots = MathRound(xlots / LotStep)  * LotStep;

Округляем значение лота до разрешенного количества знаков после запятой.

 

   
  if(xlots == 0) Print("Not enough funds to open order");
  else if(NormalizeDouble(xlots-LotMin,2) < 0) {Print("Rounding lot up to LotMin"); xlots = LotMin;}
  else if(NormalizeDouble(xlots-LotMax,2) > 0) {Print("Rounding lot down to LotMax"); xlots = LotMax;}

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

 

   
  return (xlots);

Функция возвращает количество лотов для торговли.

 

И в заключение, разберем вызов функции из тела советника.

...
double Lot=0.1;
if(LarryWilliamsMethod == True)
  Lot = LarryWilliams();
OrderSend(Symbol(), OP_BUY, Lot, Ask, slip, Bid-SL*Point, Bid+TP*Point, "Test", Magic);
...

Сначала мы создаем переменную Lot и инициализируем ее значением 0.1. Если в настройках советника пользователь указал LarryWilliamsMethod=True, значит, он хочет использовать модуль ЛВ. В таком случае, мы перезаписываем значение переменной Lot тем значением, которое нам вернет функция LarryWilliams(), детально разобранная выше. Затем, мы открываем ордер посредством функции OrderSend().

 

Надеюсь, что Вы найдете полезным данный урок, и что я достаточно понятно все объяснил. Если остались вопросы - задавайте! Разберемся!

 

До встречи на следующем уроке!

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 83 - Ожидание нового бара и простой пример

 

Добрый день, дорогие друзья!

 

Совсем недавно я получил следующий вопрос от одного из читателей курса: "Здравствуйте. Подскажите как написать индикатор, выводящий через Alert на каждом новом баре M1 значения индикатора MACD за предидущую минуту."

 

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

 

//+------------------------------------------------------------------+
//|                                                     Lesson83.mq4 |
//|                                Copyright © 2012, StockProgrammer |
//|                                          StockProgrammer@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2012, StockProgrammer"
#property link      "StockProgrammer@mail.ru"

int start()
{
  if(IsNewBar())
  {
     double Main = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
     double Signal = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
     Alert("Main = ", Main, " Signal = ", Signal);
  }

  return(0);
}

bool IsNewBar()
{
  static datetime BARflag = 0;
  datetime now = Time[0];
  if(BARflag < now)
  {
     BARflag = now;         
     return(1);
  }

  else
  {
     return(0);
  }
}



post-50854-1404217995,2161_thumb.gif

Рис.1 - Пример работы советника

 

Как видим из изображения выше - код работает исправно. Единственное замечание - по-хорошему, это не советник, а индикатор. Но раз читатель, попросил сделать советника, я решил, что у него есть на то свои причины. В конце-концов алгоритм от этого не меняется.

 

Думаю, данный урок был полезен как продвинутым трейдерам, так и новичкам. В следующий раз мы обсудим код.

До встречи на следующем уроке!

 

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Programmer

Урок 84 - Общие функции

 

Приветствую, уважаемые читатели!

Раз уж мы разбираем код с функцией Alert(), я решил, что стоит обратить внимание на семейство функций, к которым она принадлежит. Это семейство в MQL4 называется "Общие функции" и в него входят в основном обслуживающие функции терминала. Некоторые из них (например, Sleep() и Print()) Вы уже знаете, а некоторые покажутся Вам новыми. В любом случае, они часто бывают полезными и их желательно знать.

 

PS Официальное описание семейства этих функций звучит следующим образом:

Функции общего назначения, которые не вошли ни в одну из специализированных групп.

 

1 - Alert()

 

Синтаксис:

void Alert( ...)

 

Описание:

Отображает диалоговое окно, содержащие пользовательские данные. Параметры могут быть любого типа. Количество параметров не может превышать 64.

 

Массивы нельзя передавать в функцию Alert(). Массивы должны выводиться поэлементно.

 

Данные типа double выводятся с 4 десятичными цифрами после точки. Для вывода чисел с большей точностью используйте функцию DoubleToStr().

Данные типы bool, datetime и color будут выведены как числа.

Чтобы вывести данные типа datetime в виде строки, необходимо использовать функцию TimeToStr().

 

Для разделения выводимой информации на несколько строк можно использовать символ перевода строки "\n" либо "\r\n".

См. также функции Comment() и Print().

 

Параметры:

... - Любые значения, разделенные запятыми.

 

 

2 - Comment()

 

Синтаксис:

void Comment( ...)

 

Описание:

Функция выводит комментарий, определенный пользователем, в левый верхний угол графика. Параметры могут иметь любой тип. Количество параметров не может превышать 64.

 

Массивы нельзя передавать в функцию Comment(). Массивы должны печататься поэлементно.

 

Данные типа double выводятся с 4 десятичными цифрами после точки. Для вывода чисел с большей точностью необходимо использовать функцию DoubleToStr().

Типы bool, datetime и color будут напечатаны как числа.

Чтобы вывести данные типа datetime в виде строки используйте функцию TimeToStr().

 

Для разделения выводимой информации на несколько строк можно использовать символ перевода строки "\n" либо "\r\n".

См. также функции Alert() и Print().

 

Параметры:

... - Любые значения, разделенные запятыми.

 

 

3 - GetTickCount()

 

Синтаксис:

int GetTickCount( )

 

Описание:

Функция GetTickCount() возвращает количество миллисекунд, прошедших с момента старта системы. Счетчик ограничен разрешающей способностью системного таймера. Так как время хранится как беззнаковое целое, то он переполняется каждые 49.7 дней.

 

Параметры:

- отсутствуют -

 

 

4 - MarketInfo()

 

Синтаксис:

double MarketInfo( string symbol, int type)

 

Описание:

Возвращает различную информацию о финансовых инструментах, перечисленных в окне "Обзор рынка". Часть информации о текущем финансовом инструменте хранится в предопределенных переменных.

 

Параметры:

symbol - Символ инструмента.

type - Идентификатор запроса, определяющий тип возвращаемой информации. Может быть любым из значений идентификаторов запроса.

 

 

5 - MessageBox()

 

Синтаксис:

int MessageBox( string text=NULL, string caption=NULL, int flags=EMPTY)

 

Описание:

Функция MessageBox создает и отображает окно сообщений, а также управляет им. Окно сообщений содержит определенные приложением сообщение и заголовок, любую комбинацию предопределенных значков и командных кнопок. Если функция успешно выполняется, возвращаемое значение - одно из значений кодов возврата MessageBox().

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

 

Параметры:

text - Текст, содержащий сообщение для отображения.

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

flags - Необязательные флаги, определяющие вид и поведение диалогового окна. Флаги могут быть комбинацией флагов из следующих групп флагов.

 

 

6 - PlaySound()

 

Синтаксис:

void PlaySound( string filename)

 

Описание:

Функция воспроизводит звуковой файл. Файл должен быть расположен в каталоге каталог_терминала\sounds или его подкаталоге.

 

Параметры:

filename - путь к звуковому файлу.

 

 

7 - Print()

 

Синтаксис:

void Print( ...)

 

Описание:

Печатает некоторое сообщение в журнал экспертов. Параметры могут иметь любой тип. Количество параметров не может превышать 64.

 

Массивы нельзя передать в функцию Print(). Массивы должны быть напечатаны поэлементно.

 

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

Данные типов bool, datetime и color будут напечатаны в виде чисел.

Чтобы печатать значения datetime как строку с датой, следует использовать функцию TimeToStr().

См. также функции Alert() и Comment().

 

Параметры:

... - Любые значения, разделенные запятыми.

 

 

8 - SendFTP()

 

Синтаксис:

bool SendFTP( string filename, string ftp_path=NULL)

 

Описание:

Посылает файл по адресу, указанному в окне настроек на закладке "Публикация". В случае неудачи возвращает FALSE.

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

Отсылаемый файл должен находиться в папке каталог_терминала\experts\files или ее подпапках.

Отсылка не производится, если в настройках не указан адрес FTP и/или пароль доступа.

 

Параметры:

filename - Имя отсылаемого файла.

ftp_path - Каталог FTP. Если каталог не указан, то используется каталог, описанный в настройках.

 

 

9 - SendMail()

 

Синтаксис:

void SendMail( string subject, string some_text)

 

Описание:

Посылает электронное письмо по адресу, указанному в окне настроек на закладке "Почта".

Отсылка может быть запрещена в настройках, также может быть не указан адрес электронной почты. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError().

 

Параметры:

subject - Заголовок письма.

some_text - Тело письма.

 

 

10 - SendNotification()

 

Синтаксис:

bool SendNotification( string message)

 

Описание:

Посылает Push-уведомление на мобильные терминалы, чьи MetaQuotes ID указаны в окне настроек на закладке "Уведомления".

Отсылка может быть запрещена в настройках, также может быть не указан ID.

В случае ошибки возвращает false. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError().

 

Замечание: Для функции SendNotification() установлены жесткие ограничения по использованию: не более 2-х вызовов в секунду и не более 10 вызовов в минуту. Контроль за частотой использования осуществляется динамически, и функция может быть заблокирована при нарушении.

 

Параметры:

message - Текст сообщения длиною не более 255 символов.

 

 

11 - Sleep()

 

Синтаксис:

void Sleep( int milliseconds)

 

Описание:

Функция задерживает выполнение текущего эксперта или скрипта на определенный интервал.

Функцию Sleep() нельзя вызывать из пользовательских индикаторов, так как индикаторы выполняются в интерфейсном потоке и не должны его тормозить.

В функцию встроена проверка состояния флага остановки эксперта каждую 0.1 секунды.

 

Параметры:

milliseconds - Интервал задержки в миллисекундах.

 

 

Надеюсь, что данный урок показался Вам полезным.

До встречи на следующем уроке!

 

© Kirill. StockProgrammer@mail.ru

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.

  • Recently Browsing   0 members

    No registered users viewing this page.

×