BlinGoblin
BlinGoblin
Home
Я, как дилетант, в области программирования вообще и на MQL4 и MQL5 в частности, тем не менее, с чувством любопытства, начал изучать азы программирования сначала на MQL4 с сентября 2009 года а затем и на MQL5 с лета 2010. Намаявшись самому, из чувства солидарности хотя бы, мне хотелось бы помочь всему сообществу трейдеров, которые тоже только начинают осваивать азы программирования в MQL5 и поделиться опытом изучения советников используя, скажем так, метод от обратного, почёрпнутый мною ещё в пору студенчества в машиностроительном институте в 80-х годах прошлого века. Что касается формулировки и определений, то тут метода от обратного не получается. Формулировки и определения необходимо выучить назубок, или, хотя бы, зазубрить, если не понятен смысл. Вплоть до того, что можно даже записывать определения на бумажку и ложить их под подушку на ночь. Как ни странно, этот метод, порекомендованный когда то нашим преподом по философии, изобилующей тоже массой человеческому уму непостижимых понятий, действовал. Непонятно каким образом, но действовал. Язык же программирования для обычного человека, далёкого от программирования, вообще воспринимается как инопланетный язык. Отсюда и возникла идея изучения языка методом от обратного, который сейчас активно и использую при составлении своих советников. Как? Сейчас объясню. Сначала методом аналогии, а потом и по детально.

Итак, аналогия:

Тем, кому посчастливилось учиться в институте, аналогию предоставить не представляет никакого труда. Им просто достаточно вспомнить процесс написания диплома и курсовых работ. А именно – берётся заготовка и туда “просто” подставляются свои значения. В процессе подстановки своих значений и происходит процесс постепенного усваивания материала. Тем более, что просто так – механически, подставить значения всё равно не получится, потому что кроме этого, всегда требуется какая то переработка курсовой работы с целью получения хоть какого то приемлемого для препода результата. Вот почему я немного выше и сделал оговорку о том, что определения и формулировки нужно знать назубок. Итак, аналогия, я думаю, понятна. Теперь, пока нас не покинуло “просветление”, быстренько переходим к следующему этапу, а именно – переходим к конкретному примеру для того что бы на этом конкретном примере подтвердились счастливые догадки “просветлённого” бывшего студента.

Итак, пример. В качестве примера берём заготовку (вспомнили студенческие навыки), а в качестве заготовки возьмём какой ни будь советник из числа тех что предлагаются на различных форумах профессиональными программистами. Залезаем, например, на https://www.mql5.com/ru/articles/examples_experts и возмём Пример торговой системы на основе индикатора Heiken-Ashi или залезаем, например, на https://www.mql5.com/ru/code и возьмём пример, ну, допустим, Советник "Night" (Автор: AM2)

Заготовку выбранного нами советника Night мы как истые экс студенты тут же разбиваем на блоки похожих элементов:

Итак:

//БЛОК 1: неизменяемый блок

//+------------------------------------------------------------------+
//| Night.mq5 |
//| Copyright 2010, AM2 Group. |
//| http://www.am2_group.net |
//+------------------------------------------------------------------+

//БЛОК 2: неизменяемый блок

#property copyright "Copyright 2010, AM2 Group."
#property link "http://www.am2_group.net"
#property version "1.00"

//БЛОК 3: входные параметры

input int StopLoss=40; // Stop Loss
input int TakeProfit=20; // Take Profit
input int Stoch_OverSold=30; // Уровень перепроданности Stochastic
input int Stoch_OverBought=70;// Уровень перекупленности Stochastic
input double Lot=1; // Количество лотов для торговли
input int EA_Magic=1072010; // Magic Number советника

//БЛОК 4: глобальные переменные

int stochHandle; // хэндл индикатора Stochastic
double stochVal[5]; // статический массив для хранения значений индикатора Stochastic для каждого бара
int STP,TKP; // будут использованы для значений Stop Loss и Take Profit
double Lots=0.1; // количество лотов для торговли

//БЛОК 5: получение указателей на индикаторы

stochHandle=iStochastic(NULL,PERIOD_M15,5,3,3,MODE_EMA,STO_CLOSECLOSE);

//БЛОК 6: неизменяемый блок

//--- Для работы с брокерами, использующими 3-х и 5-ти значные котировки,
//--- умножаем на 10 значения SL и TP
STP = StopLoss;
TKP = TakeProfit;
if(_Digits==5 || _Digits==3)
{
STP = STP*10;
TKP = TKP*10;
}
return(0);
}

//БЛОК 7: Освобождение от мусора


void OnDeinit(const int reason)
{
//--- Освобождаем хэндлы индикаторов
IndicatorRelease(stochHandle);
}

//БЛОК 8: неизменяемый блок


void OnTick()
{
//---
//--- Объявляем структуры, которые будут использоваться для торговли
MqlTradeRequest mrequest; // Будет использоваться для отсылки торговых запросов
MqlTradeResult mresult; // Будет использоваться для получения результатов выполнения торговых запросов
MqlDateTime dt;
datetime t[];

//БЛОК 9: установка индексации



/*
Установим индексацию в массивах котировок и индикаторов
как в таймсериях
*/

ArraySetAsSeries(stochVal,true);
ArraySetAsSeries(t,true);
TimeCurrent(dt);

//БЛОК 10: неизменяемый блок

int i=(dt.hour+1)*60;
if(CopyTime(Symbol(),0,0,i,t)<0)
{
Print("Не удалось скопировать таймсерию!");
return;
}

//БЛОК 11: Получение исторических данных 3-х баров

//--- Получаем исторические данные последних 3-х баров
if(CopyBuffer(stochHandle,0,0,3,stochVal)<0)
{
Alert("Ошибка копирования буферов индикатора Stochastic - номер ошибки:",GetLastError(),"!!");
return;
}

//БЛОК 12: неизменяемый блок :



double Ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK); // лучшее предложение на покупку
double Bid = SymbolInfoDouble(_Symbol,SYMBOL_BID); // лучшее предложение на продажу

//БЛОК 13: объявление переменных для покупки



//--- объявляем переменные типа boolean, они будут использоваться при проверке условий для покупки

bool Buy_Condition = (stochVal[1]=21 || dt.hour Stoch_OverBought); // Stochastic выше уровня перекупленности


//БЛОК 16: неизменяемый блок



//--- собираем все вместе
if(Sell_Condition && (!PositionSelect(_Symbol)))
{
if(dt.hour >=21 || dt.hour <6)
{
mrequest.action = TRADE_ACTION_DEAL; // немедленное исполнение
mrequest.price = Bid; // последняя цена Bid
mrequest.sl = NormalizeDouble(Bid + STP*_Point,_Digits); // Stop Loss
mrequest.tp = NormalizeDouble(Bid - TKP*_Point,_Digits); // Take Profit
mrequest.symbol = _Symbol; // символ
mrequest.volume = CalculateVolume(); // количество лотов для торговли
mrequest.magic = EA_Magic; // Magic Number
mrequest.type= ORDER_TYPE_SELL; // ордер на продажу
mrequest.type_filling = ORDER_FILLING_AON; // тип исполнения ордера - все или ничего
mrequest.deviation=5; // проскальзывание от текущей цены
OrderSend(mrequest,mresult); // отсылаем ордер
// анализируем код возврата торгового сервера
if(mresult.retcode==10009 || mresult.retcode==10008)
{
Alert("Ордер Sell успешно помещен, ордер №:",mresult.order);
}
else
{
Alert("Запрос на установку ордера Sell не выполнен - код ошибки:",GetLastError());
return;
}
}
}
}
//+------------------------------------------------------------------+
//--- Вычисляем размер лота
double CalculateVolume()
{
Lots=AccountInfoDouble(ACCOUNT_FREEMARGIN)/100000*10;
Lots=MathMin(5,MathMax(0.1,Lots));
if(Lots<0.1)
Lots=NormalizeDouble(Lots,2);
else
{
if(Lots<1) Lots=NormalizeDouble(Lots,1);
else Lots=NormalizeDouble(Lots,0);
}
return(Lots);
}




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

Из этих 16 блоков 8 блоков не требуют никакого изменения, что нас радует. Это блоки 1, 2, 6, 8, 10, 12, 14, 16 то есть практически каждый второй блок не требует нашего вмешательства. 50% всей работы уже проделана за нас автором советника который мы взяли в качестве заготовки. С благодарностью отнесёмся к проделанной кропотливой работе профессионала, написавшего выбранный нами советник и перейдём к следующему этапу – этапу подстановки своих значений. Ведь у нас есть свои оригинальные идеи по поводу того какие должны быть торговые сигналы для входа в рынок на самом деле. А именно о торговых сигналах сейчас и идёт речь. Потому что единственное что нас интересует в передранном советнике это то, что мы можем просто подставить в него наши секретные торговые сигналы для входа в рынок. И это именно те торговые сигналы, которые способны озолотить нас ))).

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

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

Да простит меня читатель и да поймёт меня студент за студенческий же сленг.
BlinGoblin
Оставил отзыв на исполнителя за работу Новый индикатор
BlinGoblin
Зарегистрировался в MQL5.community