Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Стохастический Осциллятор (Stochastic Oscillator). 2 страница




Ticket; // Номер ордера

double

MA_1_t, // Значен. МА_1 текущее

MA_2_t, // Значен. МА_2 текущее

Lot, // Колич. лотов в выбран.ордере

Lts, // Колич. лотов в открыв.ордере

Min_Lot, // Минимальное количество лотов

Step, // Шаг изменения размера лота

Free, // Текущие свободные средства

One_Lot, // Стоимость одного лота

Price, // Цена выбранного ордера

SL, // SL выбранного ордера

TP; // TP выбранного ордера

bool

Ans =false, // Ответ сервера после закрытия

Cls_B=false, // Критерий для закрытия Buy

Cls_S=false, // Критерий для закрытия Sell

Opn_B=false, // Критерий для открытия Buy

Opn_S=false; // Критерий для открытия Sell

//--------------------------------------------------------------- 3 --

// Предварит.обработка

if(Bars < Period_MA_2) // Недостаточно баров

{

Alert("Недостаточно баров в окне. Эксперт не работает.");

return; // Выход из start()

}

if(Work==false) // Критическая ошибка

{

Alert("Критическая ошибка. Эксперт не работает.");

return; // Выход из start()

}

//--------------------------------------------------------------- 4 --

// Учёт ордеров

Symb=Symbol(); // Название фин.инстр.

Total=0; // Количество ордеров

for(int i=1; i<=OrdersTotal(); i++) // Цикл перебора ордер

{

if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий

{ // Анализ ордеров:

if (OrderSymbol()!=Symb)continue; // Не наш фин. инструм

if (OrderType()>1) // Попался отложенный

{

Alert("Обнаружен отложенный ордер. Эксперт не работает.");

return; // Выход из start()

}

Total++; // Счётчик рыночн. орд

if (Total>1) // Не более одного орд

{

Alert("Несколько рыночных ордеров. Эксперт не работает.");

return; // Выход из start()

}

Ticket=OrderTicket(); // Номер выбранн. орд.

Tip =OrderType(); // Тип выбранного орд.

Price =OrderOpenPrice(); // Цена выбранн. орд.

SL =OrderStopLoss(); // SL выбранного орд.

TP =OrderTakeProfit(); // TP выбранного орд.

Lot =OrderLots(); // Количество лотов

}

}

//--------------------------------------------------------------- 5 --

// Торговые критерии

MA_1_t=iMA(NULL,0,Period_MA_1,0,MODE_LWMA,PRICE_TYPICAL,0); // МА_1

MA_2_t=iMA(NULL,0,Period_MA_2,0,MODE_LWMA,PRICE_TYPICAL,0); // МА_2

 

if (MA_1_t > MA_2_t + Rastvor*Point) // Если разница между

{ //..МА 1 и 2 большая

Opn_B=true; // Критерий откр. Buy

Cls_S=true; // Критерий закр. Sell

}

if (MA_1_t < MA_2_t - Rastvor*Point) // Если разница между

{ //..МА 1 и 2 большая

Opn_S=true; // Критерий откр. Sell

Cls_B=true; // Критерий закр. Buy

}

//--------------------------------------------------------------- 6 --

// Закрытие ордеров

while(true) // Цикл закрытия орд.

{

if (Tip==0 && Cls_B==true) // Открыт ордер Buy..

{ //и есть критерий закр

Alert("Попытка закрыть Buy ",Ticket,". Ожидание ответа..");

RefreshRates(); // Обновление данных

Ans=OrderClose(Ticket,Lot,Bid,2); // Закрытие Buy

if (Ans==true) // Получилось:)

{

Alert ("Закрыт ордер Buy ",Ticket);

break; // Выход из цикла закр

}

if (Fun_Error(GetLastError())==1) // Обработка ошибок

continue; // Повторная попытка

return; // Выход из start()

}

 

if (Tip==1 && Cls_S==true) // Открыт ордер Sell..

{ // и есть критерий закр

Alert("Попытка закрыть Sell ",Ticket,". Ожидание ответа..");

RefreshRates(); // Обновление данных

Ans=OrderClose(Ticket,Lot,Ask,2); // Закрытие Sell

if (Ans==true) // Получилось:)

{

Alert ("Закрыт ордер Sell ",Ticket);

break; // Выход из цикла закр

}

if (Fun_Error(GetLastError())==1) // Обработка ошибок

continue; // Повторная попытка

return; // Выход из start()

}

break; // Выход из while

}

//--------------------------------------------------------------- 7 --

// Стоимость ордеров

RefreshRates(); // Обновление данных

Min_Lot=MarketInfo(Symb,MODE_MINLOT); // Миним. колич. лотов

Free =AccountFreeMargin(); // Свободн средства

One_Lot=MarketInfo(Symb,MODE_MARGINREQUIRED);// Стоимость 1 лота

Step =MarketInfo(Symb,MODE_LOTSTEP); // Шаг изменен размера

 

if (Lots > 0) // Если заданы лоты,то

Lts =Lots; // с ними и работаем

else // % свободных средств

Lts=MathFloor(Free*Prots/One_Lot/Step)*Step;// Для открытия

 

if(Lts < Min_Lot) Lts=Min_Lot; // Не меньше минимальн

if (Lts*One_Lot > Free) // Лот дороже свободн.

{

Alert(" Не хватает денег на ", Lts," лотов");

return; // Выход из start()

}

//--------------------------------------------------------------- 8 --

// Открытие ордеров

while(true) // Цикл закрытия орд.

{

if (Total==0 && Opn_B==true) // Открытых орд. нет +

{ // критерий откр. Buy

RefreshRates(); // Обновление данных

SL=Bid - New_Stop(StopLoss)*Point; // Вычисление SL откр.

TP=Bid + New_Stop(TakeProfit)*Point; // Вычисление TP откр.

Alert("Попытка открыть Buy. Ожидание ответа..");

Ticket=OrderSend(Symb,OP_BUY,Lts,Ask,2,SL,TP);//Открытие Buy

if (Ticket > 0) // Получилось:)

{

Alert ("Открыт ордер Buy ",Ticket);

return; // Выход из start()

}

if (Fun_Error(GetLastError())==1) // Обработка ошибок

continue; // Повторная попытка

return; // Выход из start()

}

if (Total==0 && Opn_S==true) // Открытых орд. нет +

{ // критерий откр. Sell

RefreshRates(); // Обновление данных

SL=Ask + New_Stop(StopLoss)*Point; // Вычисление SL откр.

TP=Ask - New_Stop(TakeProfit)*Point; // Вычисление TP откр.

Alert("Попытка открыть Sell. Ожидание ответа..");

Ticket=OrderSend(Symb,OP_SELL,Lts,Bid,2,SL,TP);//Открытие Sel

if (Ticket > 0) // Получилось:)

{

Alert ("Открыт ордер Sell ",Ticket);

return; // Выход из start()

}

if (Fun_Error(GetLastError())==1) // Обработка ошибок

continue; // Повторная попытка

return; // Выход из start()

}

break; // Выход из while

}

//--------------------------------------------------------------- 9 --

return; // Выход из start()

}

//-------------------------------------------------------------- 10 --

int Fun_Error(int Error) // Ф-ия обработ ошибок

{

switch(Error)

{ // Преодолимые ошибки

case 4: Alert("Торговый сервер занят. Пробуем ещё раз..");

Sleep(3000); // Простое решение

return(1); // Выход из функции

case 135:Alert("Цена изменилась. Пробуем ещё раз..");

RefreshRates(); // Обновим данные

return(1); // Выход из функции

case 136:Alert("Нет цен. Ждём новый тик..");

while(RefreshRates()==false) // До нового тика

Sleep(1); // Задержка в цикле

return(1); // Выход из функции

case 137:Alert("Брокер занят. Пробуем ещё раз..");

Sleep(3000); // Простое решение

return(1); // Выход из функции

case 146:Alert("Подсистема торговли занята. Пробуем ещё..");

Sleep(500); // Простое решение

return(1); // Выход из функции

// Критические ошибки

case 2: Alert("Общая ошибка.");

return(0); // Выход из функции

case 5: Alert("Старая версия терминала.");

Work=false; // Больше не работать

return(0); // Выход из функции

case 64: Alert("Счет заблокирован.");

Work=false; // Больше не работать

return(0); // Выход из функции

case 133:Alert("Торговля запрещена.");

return(0); // Выход из функции

case 134:Alert("Недостаточно денег для совершения операции.");

return(0); // Выход из функции

default: Alert("Возникла ошибка ",Error); // Другие варианты

return(0); // Выход из функции

}

}

//-------------------------------------------------------------- 11 --

int New_Stop(int Parametr) // Проверка стоп-прик.

{

int Min_Dist=MarketInfo(Symb,MODE_STOPLEVEL);// Миним. дистанция

if (Parametr < Min_Dist) // Если меньше допуст.

{

Parametr=Min_Dist; // Установим допуст.

Alert("Увеличена дистанция стоп-приказа.");

}

return(Parametr); // Возврат значения

}

//-------------------------------------------------------------- 12 --

 

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

В блоке 1-2 описаны внешние и глобальные переменные.

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

Блок предварительной обработки

 

В данном примере предварительная обработка ситуации состоит из двух частей (блок 3-4). Программа заканчивает работу в случае, если в окне финансового инструмента мало баров; в этом случае не представляется возможным правильно определить (в блоке 5-6) значения скользящих средних, необходимых для вычисления торговых критериев. Кроме того, здесь анализируется значение глобальной переменной Work. При нормальной работе эксперта значение этой переменной всегда равно true (устанавливается один раз при инициализации). Если же при выполнении программы возникла критическая (непреодолимая) ошибка, то эта переменная получает значение false, в результате чего специальная функция start() заканчивает работу. В дальнейшем это значение никогда не изменяется, поэтому и последующий код программы не исполняется. В этом случае необходимо остановить исполнение программы и установить причину возникновения критической ошибки (при необходимости связаться с дилинговым центром). После того, как ситуация будет разрешена, можно снова запустить программу в работу, присоединив эксперт к окну финансового инструмента.

Учёт ордеров

 

Рассматриваемый эксперт предполагает возможность работы только с одним рыночным ордером. Задачей блока учёта ордеров (блок 4-5) является определение характеристик открытого ордера, если такой ордер есть. В цикле перебора ордеров for опрашиваются все имеющиеся рыночные и отложенные ордера, а именно от первого (int i=1) до последнего (i<=OrdersTotal()). На каждой итерации этого цикла с помощью функции OrderSelect() выбирается очередной ордер. Выбор производится из источника открытых и отложенных ордеров (SELECT_BY_POS).

if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий

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

if (OrderSymbol()!=Symb)continue; // Не наш фин. инструм

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

Если функция OrderType() возвращает значение больше 1 (см. Типы торговых операций), то выбранный ордер - отложенный. Но в данном эксперте не предусмотрено управление отложенными ордерами. Это значит, что необходимо закончить исполнение специальной функции start(), т.к. сложилась конфликтная ситуация. В этом случае после сообщения об окончании работы исполнение функции start() заканчивается с помощью оператора return.

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

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

Вычисление торговых критериев

 

В рассматриваемом примере определение торговых критериев (блок 5-6) вычисляется на основе разницы значений скользящих средних с различными периодами усреднения. В соответствии с принятыми критериями ценовой график имеет бычье направление, если текущее значение МА малого периода усреднения больше, чем значение МА большего периода, и разница между значениями средних превышает некоторую величину. При медвежьем движении рынка МА малого периода находится ниже, чем МА большого периода, и разница между этими значениями также превышает некоторую критическую величину.

В начале блока вычисляются значения средних с периодами усреднения Period_MA_1 и Period_MA_2. Факт значимости какого-либо торгового критерия выражается через значение соответствующей переменной. Переменные Opn_B и Opn_S означают срабатывание критерия для открытия ордеров Buy и Sell, а переменные Cls_В и Cls_S - для закрытия. Например, если критерий для открытия ордера Buy не сработал, то значение переменной Opn_B остаётся равным false (установленным при инициализации переменной), а если критерий сработал, то переменная Opn_B получает значение true. В данном случае критерий закрытия ордера Sell совпадает с критерием открытия ордера Buy и критерий открытия Sell совпадает с критерием закрытия Buy.

Принятые в данном эксперте торговые критерии используются в учебных целях и не должны рассматриваться как руководство к действию при торговле на реальном счёте.

Закрытие ордеров

 

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

Блок закрытия построен на основе бесконечного цикла while, тело которого состоит из двух аналогичных частей: первая часть предназначена для закрытия ордера Buy, а вторая - для закрытия Sell. Цикл while используется здесь для того, чтобы в случае неудачного завершения торговой операции её можно было повторить.

В заголовке первого оператора if вычисляется условие для закрытия ордера Buy (закрытие рыночных ордеров Sell происходит по аналогичному алгоритму). Если тип ранее открытого ордера соответствует типу Buy (см. Типы торговых операций) и признак закрытия ордера Buy является значимым, то управление передаётся в тело оператора if, где формируется торговый приказ на закрытие. В качестве цены закрытия ордера в функции OrderClose() указывается значение двухсторонней котировки, соответствующее типу ордера (см. Требования и ограничения торговых операций). Если торговая операция выполнена успешно, то после сообщения о закрытии ордера текущая итерация цикла while прерывается, и, таким образом, исполнение блока закрытия ордеров заканчивается. Если же операция закрытия закончилась неудачей, то вызывается для исполнения пользовательская функция обработки ошибок Fun_Error() (блок 10-11).

Обработка ошибок

 

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

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

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

Вычисление количества лотов для новых ордеров

 

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

В начале блока определения количества лотов для новых ордеров (блок 7-8) вычисляются необходимые значения некоторых переменных - минимально допустимое количество лотов и шаг изменения лота, установленные брокером, количество свободных средств и стоимость одного лота для данного финансового инструмента.

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

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

Открытие ордеров

 

Блок открытия ордеров (блок 8-9) также, как и блок закрытия, представляет бесконечный цикл while. В заголовке первого оператора if вычисляются условия для открытия ордера Buy: если по финансовому инструменту нет ордеров (переменная Total равна 0) и признак для открытия ордера Buy является значимым (Opn_B равно true), то управление передаётся в тело оператора if для открытия ордера. В этом случае после обновления данных вычисляются заявленные цены для стоп-приказов.

Значения стоп-приказов изначально задаются пользователем во внешних переменных StopLoss и TakeProfit. В общем случае пользователь может установить значение для этих параметров меньшее, чем позволяет брокер. Кроме того, брокер в любой момент по своему усмотрению может изменить минимально допустимую дистанцию (это нередко случается при сильных движениях рынка, например, перед выходом важных новостей). Поэтому перед каждым открытием ордера значения стоп-приказов должны быть вычислены с учётом значений, установленных пользователем, а также минимально допустимого значения, установленного брокером.

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

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

Некоторые особенности кода

 

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

Например, в соответствии с принятой стратегией, эксперт ориентирован на работу только с одним ордером. Это позволило использовать переменную Ticket как для идентификации номера закрываемого ордера (в блоке закрытия 6-7), так и для идентификации успешности исполнения торговой операции при открытии ордера (в блоке открытия 8-9). В данном случае такое решение вполне приемлемо. Вместе с тем, если рассматриваемый код взять за основу для реализации другой стратегии (например, позволять встречные ордера), то придётся дополнительно ввести ещё одну или несколько переменных, чтобы иметь возможность различать номера открытых ордеров и идентифицировать успешность торговых операций.

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

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

Создание пользовательских индикаторов

 

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

Пользовательский индикатор - это программа, составленная на языке MQL4, основным назначением которой является графическое отображение на экране рассчитанных зависимостей.

 

Устройство пользовательского индикатора

 

Необходимость буферов

 

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

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

Стандартом языка MQL4 предусмотрена возможность построения с помощью одного пользовательского индикатора до восьми индикаторных линий. Каждой из индикаторных линий ставится в соответствие один индикаторный массив и один буфер. Каждый из буферов имеет свой индекс. Индекс первого буфера - 0, второго - 1, и т.д., а последнего - 7. На Рис. 115 показано как информация из пользовательского индикатора через буферы передаётся клиентскому терминалу для построения индикаторных линий.


Рис. 115. Передача значений индикаторных массивов через буфер клиентскому терминалу.

 

Общий порядок построения индикаторных линий состоит в следующем:

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

2. Значения элементов индикаторных массивов через буферы сообщаются клиентскому терминалу.

3. На основе массивов значений, полученных из буферов, клиентский терминал воспроизводит изображение индикаторных линий.

 

Из чего состоит пользовательский индикатор

 

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

Пример простого пользовательского индикатора userindicator.mq4

 

//--------------------------------------------------------------------

// userindicator.mq4

// Предназначен для использования в качестве примера в учебнике MQL4.

//--------------------------------------------------------------------

#property indicator_chart_window // Индик. рисуется в основном окне

#property indicator_buffers 2 // Количество буферов

#property indicator_color1 Blue // Цвет первой линии

#property indicator_color2 Red // Цвет второй линии

 

double Buf_0[],Buf_1[]; // Объявление массивов (под буферы индикатора)

//--------------------------------------------------------------------

int init() // Специальная функция init()

{

SetIndexBuffer(0,Buf_0); // Назначение массива буферу

SetIndexStyle (0,DRAW_LINE,STYLE_SOLID,2);// Стиль линии

SetIndexBuffer(1,Buf_1); // Назначение массива буферу

SetIndexStyle (1,DRAW_LINE,STYLE_DOT,1);// Стиль линии

return; // Выход из спец. ф-ии init()

}

//--------------------------------------------------------------------

int start() // Специальная функция start()

{

int i, // Индекс бара

Counted_bars; // Количество просчитанных баров

//--------------------------------------------------------------------

Counted_bars=IndicatorCounted(); // Количество просчитанных баров

i=Bars-Counted_bars-1; // Индекс первого непосчитанного

while(i>=0) // Цикл по непосчитанным барам

{

Buf_0[i]=High[i]; // Значение 0 буфера на i-ом баре




Поделиться с друзьями:


Дата добавления: 2014-12-29; Просмотров: 336; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.104 сек.