Как научить МТ понимать пользовательские индюки?
а что его учить? он умеет, главное ему правильно объяснить. фукнкция iCustom поможет.
Как быдет выгледеть эта функция для этого индюка?
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 LightSeaGreen
#property indicator_color2 FireBrick
//---- input parameters
extern int EMA_period=3;
extern int MomPeriod=8;
extern int CountBars=999999;
//---- buffers
double Up[];
double Down[];
double Mom;
double e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12;
double c1,c2,c3,c4;
double n,n1,w1,w2,b2,b3,w3,w4,b;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicator line
IndicatorBuffers(2);
SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexBuffer(0,Up);
SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexBuffer(1,Down);
//----
//----
//---- variable reset
/*e1=0; e2=0; e3=0; e4=0; e5=0; e6=0;
c1=0; c2=0; c3=0; c4=0;
n=0;n1=0;
w1=0; w2=0; w3=0; w4=0;
b2=0; b3=0;*/
b = 0.7;
b2=b*b;
b3=b2*b;
c1=-b3;
c2=(3*(b2+b3));
c3=-3*(2*b2+b+b3);
c4=(1+3*b+b3+3*b2);
n=EMA_period;
n1=MomPeriod + MomPeriod + 1;
if (n<1) n=1;
n = 1 + 0.5*(n-1);
w1 = 2 / (n + 1);
w2 = 1 - w1;
if (n1<1) n1=1;
n1 = 1 + 0.5*(n1-1);
w3 = 2 / (n1 + 1);
w4 = 1 - w3;
return(0);
}
//+------------------------------------------------------------------+
//| T3_iAnchMom |
//+------------------------------------------------------------------+
int start()
{
if (CountBars>Bars) CountBars=Bars;
SetIndexDrawBegin(0,Bars-CountBars+(MomPeriod*2)*EMA_period);
SetIndexDrawBegin(1,Bars-CountBars+(MomPeriod*2)*EMA_period);
int i,counted_bars=IndicatorCounted();
double a,c;
if(Bars<=n1) return(0);
//---- initial zero
if(counted_bars<n1)
{
for(i=1;i<=n1;i++) Up[CountBars-i]=0.0;
for(i=1;i<=n1;i++) Down[CountBars-i]=0.0;
}
//----
i=CountBars-1;
// if(counted_bars>=1) i=Bars-counted_bars-1;
while(i>=0)
{
e1 = w1*Close[i] + w2*e1;
e2 = w1*e1 + w2*e2;
e3 = w1*e2 + w2*e3;
e4 = w1*e3 + w2*e4;
e5 = w1*e4 + w2*e5;
e6 = w1*e5 + w2*e6;
a=c1*e6 + c2*e5 + c3*e4 + c4*e3;
e7 = w3*Close[i] + w4*e7;
e8 = w3*e7 + w4*e8;
e9 = w3*e8 + w4*e9;
e10 = w3*e9 + w4*e10;
e11 = w3*e10 + w4*e11;
e12 = w3*e11 + w4*e12;
c=c1*e12 + c2*e11 + c3*e10 + c4*e9;
Mom = 100*((a / c)-1);
if (Mom>0) {Up[i]=Mom;Down[i]=0.0;} else {Down[i]=Mom;Up[i]=0.0;}
i--;
}
return(0);
}
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 LightSeaGreen
#property indicator_color2 FireBrick
//---- input parameters
extern int EMA_period=3;
extern int MomPeriod=8;
extern int CountBars=999999;
//---- buffers
double Up[];
double Down[];
double Mom;
double e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12;
double c1,c2,c3,c4;
double n,n1,w1,w2,b2,b3,w3,w4,b;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicator line
IndicatorBuffers(2);
SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexBuffer(0,Up);
SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexBuffer(1,Down);
//----
//----
//---- variable reset
/*e1=0; e2=0; e3=0; e4=0; e5=0; e6=0;
c1=0; c2=0; c3=0; c4=0;
n=0;n1=0;
w1=0; w2=0; w3=0; w4=0;
b2=0; b3=0;*/
b = 0.7;
b2=b*b;
b3=b2*b;
c1=-b3;
c2=(3*(b2+b3));
c3=-3*(2*b2+b+b3);
c4=(1+3*b+b3+3*b2);
n=EMA_period;
n1=MomPeriod + MomPeriod + 1;
if (n<1) n=1;
n = 1 + 0.5*(n-1);
w1 = 2 / (n + 1);
w2 = 1 - w1;
if (n1<1) n1=1;
n1 = 1 + 0.5*(n1-1);
w3 = 2 / (n1 + 1);
w4 = 1 - w3;
return(0);
}
//+------------------------------------------------------------------+
//| T3_iAnchMom |
//+------------------------------------------------------------------+
int start()
{
if (CountBars>Bars) CountBars=Bars;
SetIndexDrawBegin(0,Bars-CountBars+(MomPeriod*2)*EMA_period);
SetIndexDrawBegin(1,Bars-CountBars+(MomPeriod*2)*EMA_period);
int i,counted_bars=IndicatorCounted();
double a,c;
if(Bars<=n1) return(0);
//---- initial zero
if(counted_bars<n1)
{
for(i=1;i<=n1;i++) Up[CountBars-i]=0.0;
for(i=1;i<=n1;i++) Down[CountBars-i]=0.0;
}
//----
i=CountBars-1;
// if(counted_bars>=1) i=Bars-counted_bars-1;
while(i>=0)
{
e1 = w1*Close[i] + w2*e1;
e2 = w1*e1 + w2*e2;
e3 = w1*e2 + w2*e3;
e4 = w1*e3 + w2*e4;
e5 = w1*e4 + w2*e5;
e6 = w1*e5 + w2*e6;
a=c1*e6 + c2*e5 + c3*e4 + c4*e3;
e7 = w3*Close[i] + w4*e7;
e8 = w3*e7 + w4*e8;
e9 = w3*e8 + w4*e9;
e10 = w3*e9 + w4*e10;
e11 = w3*e10 + w4*e11;
e12 = w3*e11 + w4*e12;
c=c1*e12 + c2*e11 + c3*e10 + c4*e9;
Mom = 100*((a / c)-1);
if (Mom>0) {Up[i]=Mom;Down[i]=0.0;} else {Down[i]=Mom;Up[i]=0.0;}
i--;
}
return(0);
}
//+------------------------------------------------------------------+
Пример: пользовательский индикатор "My_Ind" вызывается на текущем символе, на текущем тайм-фрейме, значение берется на текущем баре сначала из его первого буфера, затем из второго:
Эксперт:
// ...
double some_value_a;
double some_value_b;
// ...
some_value_a = iCustom( NULL, 0, "My_Ind", EMA_period, MomPeriod, 0, 0);
some_value_b = iCustom( NULL, 0, "My_Ind", EMA_period, MomPeriod, 1, 0);
// ...
Особое внимание надо обратить на правильность порядка передачи аргументов и соответствию их типов при вызове iCustom в эксперте, иначе могут получиться чудеса.
См. справку по iCustom:
double iCustom( string symbol, int timeframe, string name, ..., int mode, int shift)
Эксперт:
// ...
double some_value_a;
double some_value_b;
// ...
some_value_a = iCustom( NULL, 0, "My_Ind", EMA_period, MomPeriod, 0, 0);
some_value_b = iCustom( NULL, 0, "My_Ind", EMA_period, MomPeriod, 1, 0);
// ...
Особое внимание надо обратить на правильность порядка передачи аргументов и соответствию их типов при вызове iCustom в эксперте, иначе могут получиться чудеса.
См. справку по iCustom:
double iCustom( string symbol, int timeframe, string name, ..., int mode, int shift)
Помогите пожалуйста написать советник, который бы работал по этому индюку. Пробовал сам(пробовал переделать MACD Sample), но из за недостаточного знания програмирования и MQ4 в частности он просто отказывается работать.
Этот индюк я хочу взять за основу.
Покупаем если гистограмма выше 0, продаем если гистограмма ниже 0. Закрываем сделку при смене цвета гистограммы. Профит = Х, стоп = У + Возможность оптимизации параметров индюка. Вот и всё. Если что то получится с моей задумкой, с радостью поделюсь своей наработкой.
Зарание спасибо.
Этот индюк я хочу взять за основу.
Покупаем если гистограмма выше 0, продаем если гистограмма ниже 0. Закрываем сделку при смене цвета гистограммы. Профит = Х, стоп = У + Возможность оптимизации параметров индюка. Вот и всё. Если что то получится с моей задумкой, с радостью поделюсь своей наработкой.
Зарание спасибо.
Переделанный под этот индюк пример Moving Average. Для тестирования годится, для демо и тем более для реала (если до него дойдет) необходимо снабдить "канделябрами" типа IsTradeAllowed( ), IsTradeContextBusy( ) и т.п. См. "Проверка состояния" в хелпе к МЕ. Результаты тестирования, мягко говоря, не впечатляют.
//+------------------------------------------------------------------+ //| MOM_MA_Expert_BareBone.mq4 | //| Copyright © 2006, HolyGrailUnderConstruction | //| http://www.holy_grails_huge_choice.lohotron.bazara.net/ | //+------------------------------------------------------------------+ // ---- properties #property copyright "Copyright © 2006, HolyGrailUnderConstruction" #property link "http://www.holy_grails_huge_choice.lohotron.bazara.net/" // ---- defines // ---- input parameters extern bool MM_Enabled = false; extern double Lots = 0.1; // extern double MaximumRisk = 0.02; // extern double DecreaseFactor = 3; // extern int EMA_period = 3; // extern int MomPeriod = 8; // extern int CountBars = 999999; // obsolete extern int Threshold = 0; // filter // ---- variables int MAGICMA; double mom_up; // indicator value "up" (when ind_value > 0) double mom_dw; // indicator value "down" (when ind_value < 0) //+------------------------------------------------------------------+ //| Calculate open positions | //+------------------------------------------------------------------+ int CalculateCurrentOrders(string symbol) { int buys=0,sells=0; //---- for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA) { if(OrderType()==OP_BUY) buys++; if(OrderType()==OP_SELL) sells++; } } //---- return orders volume if(buys>0) return(buys); else return(-sells); } //+------------------------------------------------------------------+ //| Calculate optimal lot size | //+------------------------------------------------------------------+ double LotsOptimized() { double lot=Lots; int orders=HistoryTotal(); // history orders total int losses=0; // number of losses orders without a break //---- if (!MM_Enabled) return(Lots); // if MM disabled, return input lots value //---- select lot size, if MM enabled lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1); //---- calculate number of losses orders without a break if(DecreaseFactor>0) { for(int i=orders-1;i>=0;i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; } if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue; //---- if(OrderProfit()>0) break; if(OrderProfit()<0) losses++; } if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1); } //---- return lot size if(lot<0.1) lot=0.1; return(lot); } /* custom indicator external variables: // extern int EMA_period = 3; // extern int MomPeriod = 8; // extern int CountBars = 999999; // */ //+------------------------------------------------------------------+ //| Check for open order conditions | //+------------------------------------------------------------------+ void CheckForOpen() { int res; //---- go trading only for first tiks of new bar if(Volume[0]>1) return; //---- get MOM Up and Down mom_up = iCustom( NULL, 0, "MOM", EMA_period, MomPeriod, CountBars, 0, 0); mom_dw = iCustom( NULL, 0, "MOM", EMA_period, MomPeriod, CountBars, 1, 0); //---- buy conditions if(mom_up > Threshold*Point) // filter mom_up { res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue); return; } //---- sell conditions if(mom_dw < -Threshold*Point) // filter mom_dw { res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red); return; } //---- } //+------------------------------------------------------------------+ //| Check for close order conditions | //+------------------------------------------------------------------+ void CheckForClose() { //---- go trading only for first tiks of new bar if(Volume[0]>1) return; //---- get MOM Up and Down mom_up = iCustom( NULL, 0, "MOM", EMA_period, MomPeriod, CountBars, 0, 0); mom_dw = iCustom( NULL, 0, "MOM", EMA_period, MomPeriod, CountBars, 1, 0); //---- for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue; //---- check order type if(OrderType()==OP_BUY) { if(mom_dw < -Threshold*Point) // filter mom_dw OrderClose(OrderTicket(),OrderLots(),Bid,3,White); break; } if(OrderType()==OP_SELL) // filter mom_up { if(mom_up > Threshold*Point) OrderClose(OrderTicket(),OrderLots(),Ask,3,White); break; } } //---- return; } //+------------------------------------------------------------------+ //| Start function | //+------------------------------------------------------------------+ void start() { //---- check for history and trading if(Bars<100 || IsTradeAllowed()==false) return; //---- calculate open orders by current symbol if(CalculateCurrentOrders(Symbol())==0) CheckForOpen(); else CheckForClose(); //---- return; } //+------------------------------------------------------------------+ //| Init function | //+------------------------------------------------------------------+ void init() { MAGICMA = AccountNumber(); // TODO: add your code here return; } //+------------------------------------------------------------------+ //| DeInit function | //+------------------------------------------------------------------+ void deinit() { // TODO: add your code here return; } //+------------------------------------------------------------------+
Вот сам индюк:
//+------------------------------------------------------------------+ //| MOM.mq4 | //| Copyright © 2006, HolyGrailUnderConstruction | //| http://www.holy_grails_huge_choice.lohotron.bazara.net/ | //+------------------------------------------------------------------+ // ---- properties #property copyright "Copyright © 2006, HolyGrailUnderConstruction" #property link "http://www.holy_grails_huge_choice.lohotron.bazara.net/" // ---- indicator properties #property indicator_separate_window #property indicator_buffers 2 #property indicator_color1 LightSeaGreen #property indicator_color2 FireBrick //---- input parameters extern int EMA_period=3; extern int MomPeriod=8; extern int CountBars=999999; //---- buffers double Up[]; double Down[]; double Mom; double e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12; double c1,c2,c3,c4; double n,n1,w1,w2,b2,b3,w3,w4,b; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- indicator line IndicatorBuffers(2); SetIndexStyle(0,DRAW_HISTOGRAM); SetIndexBuffer(0,Up); SetIndexStyle(1,DRAW_HISTOGRAM); SetIndexBuffer(1,Down); //---- //---- //---- variable reset /*e1=0; e2=0; e3=0; e4=0; e5=0; e6=0; c1=0; c2=0; c3=0; c4=0; n=0;n1=0; w1=0; w2=0; w3=0; w4=0; b2=0; b3=0;*/ b = 0.7; b2=b*b; b3=b2*b; c1=-b3; c2=(3*(b2+b3)); c3=-3*(2*b2+b+b3); c4=(1+3*b+b3+3*b2); n=EMA_period; n1=MomPeriod + MomPeriod + 1; if (n<1) n=1; n = 1 + 0.5*(n-1); w1 = 2 / (n + 1); w2 = 1 - w1; if (n1<1) n1=1; n1 = 1 + 0.5*(n1-1); w3 = 2 / (n1 + 1); w4 = 1 - w3; return(0); } //+------------------------------------------------------------------+ //| T3_iAnchMom | //+------------------------------------------------------------------+ int start() { if (CountBars>Bars) CountBars=Bars; SetIndexDrawBegin(0,Bars-CountBars+(MomPeriod*2)*EMA_period); SetIndexDrawBegin(1,Bars-CountBars+(MomPeriod*2)*EMA_period); int i,counted_bars=IndicatorCounted(); double a,c; if(Bars<=n1) return(0); //---- initial zero if(counted_bars<n1) { for(i=1;i<=n1;i++) Up[CountBars-i]=0.0; for(i=1;i<=n1;i++) Down[CountBars-i]=0.0; } //---- i=CountBars-1; // if(counted_bars>=1) i=Bars-counted_bars-1; while(i>=0) { e1 = w1*Close[i] + w2*e1; e2 = w1*e1 + w2*e2; e3 = w1*e2 + w2*e3; e4 = w1*e3 + w2*e4; e5 = w1*e4 + w2*e5; e6 = w1*e5 + w2*e6; a=c1*e6 + c2*e5 + c3*e4 + c4*e3; e7 = w3*Close[i] + w4*e7; e8 = w3*e7 + w4*e8; e9 = w3*e8 + w4*e9; e10 = w3*e9 + w4*e10; e11 = w3*e10 + w4*e11; e12 = w3*e11 + w4*e12; c=c1*e12 + c2*e11 + c3*e10 + c4*e9; Mom = 100*((a / c)-1); if (Mom>0) {Up[i]=Mom;Down[i]=0.0;} else {Down[i]=Mom;Up[i]=0.0;} i--; } return(0); } //+------------------------------------------------------------------+
Успехов!
Замена
mom_up = iCustom( NULL, 0, "MOM", EMA_period, MomPeriod, CountBars, 0, 0);
mom_dw = iCustom( NULL, 0, "MOM", EMA_period, MomPeriod, CountBars, 1, 0);
на
mom_up = iCustom( NULL, 0, "MOM", EMA_period, MomPeriod, CountBars, 0, 1);
mom_dw = iCustom( NULL, 0, "MOM", EMA_period, MomPeriod, CountBars, 1, 1);
к радикальным изменениям и сверхприбыли не приводит.
mom_up = iCustom( NULL, 0, "MOM", EMA_period, MomPeriod, CountBars, 0, 0);
mom_dw = iCustom( NULL, 0, "MOM", EMA_period, MomPeriod, CountBars, 1, 0);
на
mom_up = iCustom( NULL, 0, "MOM", EMA_period, MomPeriod, CountBars, 0, 1);
mom_dw = iCustom( NULL, 0, "MOM", EMA_period, MomPeriod, CountBars, 1, 1);
к радикальным изменениям и сверхприбыли не приводит.
А можно сделать, что бы советник совершал одну сделку по сигналу. А то их просто миллион. Можно было бы попробовать отфильтровать сигналы походим на него индюком. Эксперт вообщето мне нужен для подбора наилучших параметров индюков.
//+------------------------------------------------------------------+ //| iTrend.mq4 | //| Copyright © 2004, MetaQuotes Software Corp. | //| http://www.metaquotes.net | //+------------------------------------------------------------------+ #property copyright "unknown" #property link "unknown" #property indicator_separate_window #property indicator_buffers 2 #property indicator_color1 LimeGreen #property indicator_color2 Red //---- input parameters extern int Bands_Period= 20; extern int Bands_Deviation= 2; extern int Power_Period= 13; extern int Bands_Mode_0_2= 0; // =0-2 MODE_MAIN, MODE_LOW, MODE_HIGH extern int Power_Price_0_6= 0; // =0-6 PRICE_CLOSE,PRICE_OPEN,PRICE_HIGH,PRICE_LOW,PRICE_MEDIAN,PRICE_TYPICAL,PRICE_WEIGHTED extern int Price_Type_0_3= 0; // =0-3 PRICE_CLOSE,PRICE_OPEN,PRICE_HIGH,PRICE_LOW //---- buffers double TrendBuf1[]; double TrendBuf2[]; #include "fxoe-lib.mqh" //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { // string short_name; //---- indicator line IndicatorBuffers(2); SetIndexStyle(0,DRAW_HISTOGRAM); SetIndexBuffer(0,TrendBuf1); SetIndexDrawBegin(0, Bands_Period+1); SetIndexStyle(1,DRAW_HISTOGRAM); SetIndexBuffer(1,TrendBuf2); SetIndexDrawBegin(1, Bands_Period+1); IndicatorShortName("FXOE-ITrendHistogram(" + Bands_Period + ", " + Bands_Deviation + ", " + Power_Period + ")= "); //---- return(0); } //+------------------------------------------------------------------+ //| Trend | //+------------------------------------------------------------------+ int start() { double dummy1[], dummy2[]; int counted_bars= IndicatorCounted(), lastbar; if (Bars<=Bands_Period) return(0); if (counted_bars>0) counted_bars--; lastbar= Bars - counted_bars; ITrend(0, lastbar, dummy1, dummy2, TrendBuf1, TrendBuf2, Bands_Period, Bands_Deviation, Power_Period); return (0); }
Может быть сюда можно было бы приписать АС. Точно не знаю. Пока еще тестирую
Еще хотелось бы, что бы сделки совершались либо по закрытию бара, либо по его открытию, т.е. сигналы индикаторов внутри бара не учитываются.
if(Volume[0]>1) return;
- это и есть торговля при открытии нового бара.
Лучше сделать так (советуют разработчики):
- это и есть торговля при открытии нового бара.
Лучше сделать так (советуют разработчики):
// ... datetime prev_bar_time; // ... int init() { // ... prev_bar_time = LocalTime(); // ... return(0); } // ... int start() { // ... if (prev_bar_time == Time[0]) { return(0); } else { prev_bar_time = Time[0]; } // ... TODO what we ought to return(0); }
Твори, выдумывай, пробуй! (с) Удачи и успехов.
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь