Студопедия

КАТЕГОРИИ:


Архитектура-(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)

Названия цветов 13 страница




Text[4]="четыре "; Text[18]="восемнадцать ";

Text[5]="пять "; Text[19]="девятнадцать ";

Text[6]="шесть "; Text[20]="двадцать ";

Text[7]="семь "; Text[30]="тридцать ";

Text[8]="восемь "; Text[40]="сорок ";

Text[9]="девять "; Text[50]="пятьдесят ";

Text[10]="десять "; Text[60]="шестьдесят";

Text[11]="одиннадцать "; Text[70]="семьдесят ";

Text[12]="двенадцать "; Text[80]="восемьдесят ";

Text[13]="тринадцать "; Text[90]="девяносто";

Text[14]="четырнадцать "; Text[100]= "сто";

// Вычисление значений

for(int i=20; i<=90; i=i+10) // Цикл по десяткам

{

for(int j=1; j<=9; j++) // Цикл по единицам

Text[i+j]=Text[i] + Text[j]; // Вычисление значения

}

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

}

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

int start() // Спец. ф-ия start()

{

int Delta=NormalizeDouble((Bid-Level)Point,0);// Превышение

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

if (Delta<=0) // Цена не выше уровня

{

Alert("Цена ниже уровня"); // Сообщение

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

}

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

if (Delta>100) // Цена более 100

{

Alert("Более ста пунктов"); // Сообщение

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

}

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

Alert("Плюс ",Text[Delta],"pt."); // Вывод на экран

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

}

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

Для решения Задачи 25 используется строковый массив Text[]. Во время исполнения программы значения элементов этого массива не изменяются. Массив объявлен на глобальном уровне (за пределами специальных функций), а первоначальное заполнение массива осуществляется в специальной функции init(). Таким образом, в специальной функции start() выполняются только те вычисления, которые необходимо исполнить на каждом тике.

Некоторой части элементов массива Text[] присваиваются значения строковых констант. Другой части элементов массива присваиваются значения, вычисленные во вложенных циклах путём суммирования строк.

for (int i = 20; i<=90; i=i+10) // Цикл по десяткам

{

for (int j=1; j<=9; j++) // Цикл по единицам

Text[i+j] = Text[i] + Text[j]; // Вычисление значения

}

Смысл этих вычислений понять легко: для каждого элемента массива с индексом, начиная с 21 и заканчивая 99 (исключая значения индексов, кратных 10), вычисляются соответствующие строковые значения. Обратите внимание на значения индексов, указанные в строке:

Text[i+j] = Text[i] + Text[j]; // Вычисление значения

В качестве значений индексов используются переменные (значения которых в цикле изменяются) и выражение. В зависимости значений переменных i и j программа будет обращаться к соответствующим элементам массива Text[], суммировать их значения и присваивать результат элементу массива с индексом, значение которого также вычисляется (i+j) Например, если на некотором этапе вычислений значение переменной i равно 30, а переменной j равно 7, то название элементов, значения которых суммируются, соответственно, Text[30] и Text[7], а элемента, которому присваивается результат, - Text[37]. В качестве значения индекса элемента массива может использоваться и любая другая переменная целого типа. В данном примере в функции start() используется название элемента того же массива с индексом Delta, а именно - Text[Delta].

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


Рис. 60. Вывод на экран искомых значений экспертом stringarray.mq4.

Обратите внимание на решение Задачи 18. Если бы и Задача 25 была решена тем же способом, то тело оператора switch содержало бы около 100 строк, - по одной строке для каждого варианта решения. Такой подход к составлению программ нельзя считать удовлетворительным. Тем более подобные способы решения оказываются непригодными, если приходится обрабатывать десятки, а иногда и сотни тысяч значений переменных. В таких случаях использование массивов оправдано и очень удобно.

Массивы-таймсерии

 

Массив-таймсерия - это массив с предопределённым названием (Open, Close, High, Low, Volume или Time), элементы которого содержат значения соответствующих характеристик исторических баров.

Данные, содержащиеся в массивах-таймсериях, несут очень важную информацию и широко используются в практике программирования на MQL4. Каждый массив-таймсерия является одномерным массивом и содержит исторические сведения о какой-то одной характеристике бара. Каждый бар характеризуется ценой открытия Open[], ценой закрытия Close[], максимальной ценой High[], минимальной ценой Low[], объёмом Volume[] и временем открытия Time[]. Например, массив-таймсерия Open[] несёт информацию о цене открытия всех баров, имеющихся в окне финансового инструмента: значением элемента массива Open[1] является цена открытия первого бара, Open[2] - цена открытия второго бара и т.д. То же справедливо и для всех других таймсерий.

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

Отсчёт баров (и поставленных им в соответствие индексов массивов-таймсерий) начинается с нулевого бара. Значениями элементов всех массивов-таймсерий, имеющих индекс [0], являются значения, характеризующие нулевой бар. Например, значением элемента Open[0] является цена открытия нулевого бара. На Рис. 61 показан порядок нумерации баров и характеристики бара (отражаемые в окне финансового инструмента при наведении на изображение бара курсора мыши).

 


Рис. 61. Каждый бар характеризуется набором значений, содержащихся в массивах-таймсериях.
Отсчёт баров начинается с нулевого бара.

Нулевой бар на Рис. 61 имеет следующие характеристики:

Индекс Open[] Close[] High[], Low[], Time[]
[0] 1.2755 1.2752 1.2755 1.2752 2006.11.01 14:34

По истечении некоторого времени текущий бар сформируется, а в окне финансового инструмента появится новый бар. Теперь нулевым будет этот новый бар, а тот, который только что сформировался, станет первым (с индексом 1):


Рис. 62. Бары смещаются с течением времени, но нумерация баров не смещается.

Теперь значения элементов массивов-таймсерий станут следующими:

Индекс Open[] Close[] High[], Low[], Time[]
[0] 1.2751 1.2748 1.2752 1.2748 2006.11.01 14:35
[1] 1.2755 1.2752 1.2755 1.2752 2006.11.01 14:34

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

Таким образом, важнейшая особенность, касающаяся массивов-таймсерий, состоит в следующем:

Значения элементов массивов-таймсерий являются собственными характеристиками бара и никогда не изменяются (за исключением следующих характеристик нулевого бара: Close[0], High[0], Low[0], Volume [0]), а индекс бара отражает его углубление в историю на текущий момент и меняется с течением времени.

Отдельно нужно заметить, что время открытия бара исчисляется кратно календарным минутам, секунды при этом не учитываются. Иными словами, если в период между 14:34 и 14:35 первый тик пришёл в 14 час. 34 мин. 07 сек, то в минутном таймфрейме образуется новый бар со временем открытия 14:34. Соответственно, время открытия бара в 15-минутном таймфрейме кратно 15 минутам, при этом первый бар в течение часового интервала открывается в n час.00 мин, второй в n:15, третий в n:30 и четвёртый - в n:45.

Чтобы правильно понять роль индексов в массивах-таймсериях, решим следующую простую задачу:

Задача 26.Найти минимальное и максимальное значения цены среди последних n баров.

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

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

// extremumprice.mq4

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

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

extern int Quant_Bars=30; // Количество баров

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

int start() // Спец. функция start

{

int i; // Номер бара

double Minimum=Bid, // Минимальная цена

Maximum=Bid; // Максимальная цена

 

for(i=0;i<=Quant_Bars-1;i++) // От нуля (!) до..

{ //..Quant_Bars-1 (!)

if (Low[i]< Minimum) // Если < известного

Minimum=Low[i]; // то оно и будет мин

if (High[i]> Maximum) // Если > известного

Maximum=High[i]; // то оно и будет макс

}

Alert("За последние ",Quant_Bars, // Вывод на экран

" баров Min= ",Minimum," Max= ",Maximum);

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

}

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

В программе extremumprice.mq4 используется простой алгоритм. Количество баров, предназначенных для анализа, задано во внешней переменной Quant_Bars. В начале программы искомым значениям Minimum и Maximum присваиваются значения текущей цены. Поиск минимального и максимального значений выполняется в операторе цикла:

for(i=0;i<=Quant_Bars-1;i++) // От нуля (!) до..

{ //..Quant_Bars-1 (!)

if (Low[i]< Minimum) // Если < известного

Minimum = Low[i]; // то оно и будет мин

if (High[i]> Maximum) // Если > известного

Maximum = High[i]; // то оно и будет макс

}

Здесь показательным является интервал значений индексов (целая переменная i) обрабатываемых элементов массивов-таймсерий Low[i] и High[i]. Обратите внимание на Выражение_1 и Условие в заголовке оператора цикла:

for(i=0;i<=Quant_Bars-1;i++) // От нуля (!) до..

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

Последним индексом элементов таймсерий, обрабатываемых в цикле, является индекс, на 1 меньший, чем количество обрабатываемых баров. В нашем примере указано количество баров, равное 30. Это значит, что максимальное значение индекса должно быть равно 29. Таким образом, в цикле будут обработаны значения элементов таймсерий с индексами от 0 до 29, т.е. всего для 30 баров.

Легко понять и смысл вычислений в теле оператора цикла:

if (Low[i]< Minimum) // Если < известного

Minimum = Low[i]; // то оно и будет мин

if (High[i]> Maximum) // Если > известного

Maximum = High[i]; // то оно и будет макс

Если текущее значение Low[i] (т.е. в период текущей итерации с текущим значением индекса) оказывается меньше известного минимального значения, то оно и становится минимальным значением. Аналогично вычисляется и максимальное значение. К моменту окончания цикла переменные Minimum и Maximum получат искомые значения. В последующих строках эти значения выводятся на экран.

Запустив эту программу на выполнение можно получить результат, аналогичный следующему:


Рис. 63. Результаты работы эксперта extremumprice.mq4.

Обратите внимание, эксперт может работать бесконечно долго, показывая правильный результат, причём в программе всё время используются одни и те же значения индексов (в данном случае от 0 до 29). При этом значения элементов массивов-таймсерий с ненулевыми индексами будут изменяться в момент появления нового бара, а значения элементов массивов-таймсерий, характеризующих нулевой бар, могут поменяться на любом следующем тике (за исключением значений Open[0] и Time[0], которые на нулевом баре не изменяются).

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

Задача 27.В начале каждого бара 1 раз вывести на экран минимальное и максимальное значения цены среди последних сформировавшихся n баров.

Чтобы решить задачу, прежде всего необходимо определить факт начала нового бара, т.е. выявить первый тик на нулевом баре. Для этой цели существует очень простой и надёжный способ - анализировать время открытия нулевого бара. Время открытия нулевого бара - это такая характеристика бара, которая не изменяется в течение времени его формирования. Новые тики, поступающие в процессе развития нулевого бара, могут изменить его максимальную цену High[0], минимальную цену Low[0], цену закрытия Close[0] и объём Volume0]. Но такие характеристики нулевого бара, как цена открытия Open[0] и время открытия Time[0], не изменяются.

Поэтому достаточно запомнить время открытия нулевого бара и на каждом тике сравнивать это значение с последним известным временем открытия нулевого бара. Как только обнаружится несовпадение, это будет означать факт образования нового бара (и завершение предыдущего). В эксперте newbar.mq4 алгоритм обнаружения нового бара реализован в виде пользовательской функции:

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

// newbar.mq4

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

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

extern int Quant_Bars=15; // Количество баров

bool New_Bar=false; // Флаг нового бара

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

int start() // Спец. функция start

{

double Minimum, // Минимальная цена

Maximum; // Максимальная цена

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

Fun_New_Bar(); // Обращение к ф-ии

if (New_Bar==false) // Если бар не новый..

return; //..то уходим

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

int Ind_max =ArrayMaximum(High,Quant_Bars,1);// Индекс бара макс.ц.

int Ind_min =ArrayMinimum(Low, Quant_Bars,1);// Индекс бара мин. ц.

Maximum=High[Ind_max]; // Искомая макс цена

Minimum=Low[Ind_min]; // Искомая мин. цена

Alert("За последние ",Quant_Bars, // Вывод на экран

" баров Min= ",Minimum," Max= ",Maximum);

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

}

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

void Fun_New_Bar() // Ф-ия обнаружения..

{ //.. нового бара

static datetime New_Time=0; // Время текущего бара

New_Bar=false; // Нового бара нет

if(New_Time!=Time[0]) // Сравниваем время

{

New_Time=Time[0]; // Теперь время такое

New_Bar=true; // Поймался новый бар

}

}

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

В программе используется глобальная переменная New_Bar. Полагается, что если её значение равно true, то это означает, что последний известный тик - это первый тик нового бара. Если же значение New_Bar равно false, то последний известный тик появился в период развития текущего нулевого бара.

Флаг - это переменная, значение которой ставится в соответствие каким-либо событиям или фактам.

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

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

if(New_Time!= Time[0]) // Сравниваем время

{

New_Time = Time[0]; // Теперь время такое

New_Bar = true; // Поймался новый бар

}

Если значение переменной New_Time (вычисленное в предыдущей истории), не равно времени открытия нулевого бара Time[0], то это означает факт образования нового бара. В этом случае управление передаётся в тело оператора if, где запоминается новое значение времени открытия нового нулевого бара и переменной New_Bar присваивается значение true (условно можно сказать, что флаг устанавливается в положение вверх).

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

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

if (New_Bar == false) // Если бар не новый..
return; //..то уходим

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

Вычисление максимального и минимального значений осуществляется с помощью стандартных функций ArrayMaximum() и ArrayMinimum(). Каждая из этих функций возвращает индекс элемента массива (соответственно максимального и минимального значения) для заданного интервала индексов. По условию задачи необходимо исследовать только полностью сформировавшиеся бары, поэтому в качестве граничных значений индексов выбраны значения 1 и Quant_Bars - заданное количество баров (нулевой бар не сформировался, т.е. в решении данной задачи не учитывается). Для получения подробной информации о работе этих и других функций доступа к таймсериям обратитесь к справочной документации на сайте производителя (http://docs.MQL4.com/ru) или к разделу "Справка" в редакторе MetaEditor.

На Рис. 64 можно проследить как менялись минимальное и максимальное значения цены на заданном интервале в период исполнения программы:


Рис. 64. Результаты работы эксперта newbar.mq4.

Практическое программирование на языке MQL4

 

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

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

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




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


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


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



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




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