Помощь по кодированию... Как заставить индикатор фильтровать вместо алерта? - страница 3

 
elihayun:
Я думаю, что лучший способ - это НЕ использовать индикатор. Это просто самый простой способ. Для начала он достаточно хорош.

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

Если вы знаете, в каком буфере лежит нужная вам информация, то неважно, сколько индикаторов в коде.

Хорошо, вы говорите, что простота не обязательно лучше... и что лучшим способом будет написать индикатор внутри советника... но для этого, следуя примерам из уроков, единственная часть, которую нужно скопировать в советник, это часть функции итерации, а буферы находятся в части кода функции инициализации... так мне скопировать весь код индикатора в советник? Как мне сделать это наилучшим образом?... с индикатором в советнике? Не могли бы вы показать мне, пожалуйста? Я думаю, что я учусь. Мне это нравится!

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

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

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

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

Файлы:
ytt2_ea.mq4  6 kb
 
elihayun:
Отлично!!! Вы поняли идею!!!!

Он будет работать идеально. И если вы хотите проверить, что 5M и 15M достигают края в одно и то же время, вы можете получить значения от каждого TF и проверить их вместе.

Но оставьте это на потом....

У меня хороший учитель.

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

сколько из этого на самом деле должно быть скопировано в советнике?

//+------------------------------------------------------------------+

//| Custom indicator initialization function |

//+------------------------------------------------------------------+

#property indicator_chart_window

#property indicator_buffers 5

#property indicator_color1 Red

#property indicator_color2 Black

#property indicator_color3 Blue

#property indicator_color4 Red

#property indicator_color5 Blue

double upper[], middle1[], middle2, lower[];

double Xup[], Xdown[];

extern int period = 34;

int init()

{

SetIndexStyle(0,DRAW_LINE,EMPTY,2);

SetIndexShift(0,0);

SetIndexDrawBegin(0,0);

SetIndexBuffer(0,upper);

SetIndexStyle(1,DRAW_LINE,EMPTY,2);

SetIndexShift(1,0);

SetIndexDrawBegin(1,0);

SetIndexBuffer(1,middle1);

SetIndexStyle(2,DRAW_LINE,EMPTY,2);

SetIndexShift(2,0);

SetIndexDrawBegin(2,0);

SetIndexBuffer(2,lower);

SetIndexStyle(3,DRAW_ARROW,EMPTY,2);

SetIndexArrow(3, 162);

SetIndexShift(3,0);

SetIndexDrawBegin(3,0);

SetIndexBuffer(3,Xdown);

SetIndexStyle(4,DRAW_ARROW,EMPTY,2);

SetIndexArrow(4, 162);

SetIndexShift(4,0);

SetIndexDrawBegin(4,0);

SetIndexBuffer(4,Xup);

//---- indicators

//----

return(0);

}

Может мне пока сделать так, как вы показали, и назвать индикатор.... так проще.

 
Aaragorn:
У меня есть хороший учитель.

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

Как много из этого на самом деле должно быть скопировано в советнике?

//+------------------------------------------------------------------+

//| Custom indicator initialization function |

//+------------------------------------------------------------------+

.......

//---- indicators

//----

return(0);

}
Может быть, мне стоит пока сделать так, как вы показали, и назвать индикатор.... - это проще.

Никак. Это не логика, это визуальная часть индикатора.

 

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

первая половина...

//+------------------------------------------------------------------+

//| EMA_CROSS_2.mq4 |

//| Coders Guru |

//| https://www.forex-tsd.com |

//+------------------------------------------------------------------+

// ultima versiune cu micro lots! H1 si D1

#property copyright "Coders Guru"

#property link "https://www.forex-tsd.com"

//---- Trades limits

extern double

TakeProfit = 10,

TrailingStop = 20,

StopLoss = 20;

extern bool

UseStopLoss = false;

//---- EMAs paris

extern int

ShortEma = 1,

LongEma = 5;

//---- Crossing options

extern bool

immediate_trade = true, //Open trades immediately or wait for cross.

reversal = false, //Use the originally reversal crossing method or not

ConfirmedOnEntry = false;

//---- Money Management

extern double

Lots = 1,

HedgePercent = 1; // Used to calcualte the what percent of the lots the user wants to be

// used in the hedged position

extern bool

MM = true, //Use Money Management or not

AccountIsMicro = true; //Use Micro-Account or not

extern int

StartHour = 0, //Indicates when the user wants the EA to start trading

StopHour = 23; //Indicates when the user wants the EA to stop trading

extern int

Risk = 10; //10%

extern int

MAGICMA = 20060301;

extern bool

Show_Settings = true;

//---- Global varaibles

static int

TimeFrame = 0;

datetime

CheckValueTime;

//---- Trend bands

double upper[], middle1[], middle2, lower[];

double Xup[], Xdown[];

extern int period = 34;

//---- Filter Parameters

extern double longrange = 25;

extern double shortrange = 20;

//+------------------------------------------------------------------+

//| expert initialization function |

//+------------------------------------------------------------------+

int init()

{

if(Show_Settings) Print_Details();

else Comment("");

return(0);

}

//+------------------------------------------------------------------+

//| expert deinitialization function |

//+------------------------------------------------------------------+

int deinit()

{

TimeFrame=Period(); //Prevent counting the cross while the user changing the timeframe

return(0);

}

bool isNewSumbol(string current_symbol)

{

//loop through all the opened order and compare the symbols

int total = OrdersTotal();

for(int cnt = 0 ; cnt < total ; cnt++)

{

OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

string selected_symbol = OrderSymbol();

if (current_symbol == selected_symbol)

return (False);

}

return (True);

}

int Crossed (double line1 , double line2)

{

static int last_direction = 0;

static int current_direction = 0;

if(TimeFrame!=Period())

{

TimeFrame=Period();

return (0);

}

if(line1>line2)current_direction = 1; //up

if(line1<line2)current_direction = 2; //down

if(immediate_trade==false)

{

if(last_direction == 0) //first use

{

last_direction = current_direction;

return(0);

}

}

if(current_direction != last_direction) //changed

{

last_direction = current_direction;

return (last_direction);

}

else

{

return (0); //not changed

}

}

//--- Bassed on Alex idea! More ideas are coming

double LotSize()

{

double lotMM = MathCeil(AccountFreeMargin() * Risk / 1000) / 100;

if(AccountIsMicro==false) //normal account

{

if (lotMM < 0.1) lotMM = Lots;

if ((lotMM > 0.5) && (lotMM < 1)) lotMM=0.5;

if (lotMM > 1.0) lotMM = MathCeil(lotMM);

if (lotMM > 100) lotMM = 100;

}

else //micro account

{

if (lotMM < 0.01) lotMM = Lots;

if (lotMM > 1.0) lotMM = MathCeil(lotMM);

if (lotMM > 100) lotMM = 100;

}

return (lotMM);

}

string BoolToStr ( bool value)

{

if(value) return ("True");

else return ("False");

}

void Print_Details()

{

string sComment = "";

string sp = "----------------------------------------\n";

string NL = "\n";

sComment = sp;

sComment = sComment + "TakeProfit=" + DoubleToStr(TakeProfit,0) + " | ";

sComment = sComment + "TrailingStop=" + DoubleToStr(TrailingStop,0) + " | ";

sComment = sComment + "StopLoss=" + DoubleToStr(StopLoss,0) + " | ";

sComment = sComment + "UseStopLoss=" + BoolToStr(UseStopLoss) + NL;

sComment = sComment + sp;

sComment = sComment + "immediate_trade=" + BoolToStr(immediate_trade) + " | ";

sComment = sComment + "reversal=" + BoolToStr(reversal) + NL;

sComment = sComment + sp;

sComment = sComment + "Lots=" + DoubleToStr(Lots,0) + " | ";

sComment = sComment + "MM=" + BoolToStr(MM) + " | ";

sComment = sComment + "Risk=" + DoubleToStr(Risk,0) + "%" + NL;

sComment = sComment + sp;

Comment(sComment);

}

//+------------------------------------------------------------------+

//| expert start function |

//+------------------------------------------------------------------+

 

вторая половина...

//+------------------------------------------------------------------+

//| expert start function |

//+------------------------------------------------------------------+

int start() {

//+------------------------------------------------------------------+

//| Custom indicator iteration function |

//+------------------------------------------------------------------+

int limit;

int counted_bars=IndicatorCounted();

if(counted_bars<0) return(-1);

if(counted_bars>0) counted_bars--;

limit=Bars-counted_bars;

double avg;

for(int x=0; x<limit; x++) {

Xdown[x] = 0; Xup[x] = 0;

middle1[x] = iMA(NULL, 0, period, 0, MODE_EMA, PRICE_TYPICAL, x);// drawn line

middle2= iMA(NULL, 0, period, 0, MODE_SMA, PRICE_TYPICAL, x);// only used to calculate outer bands

avg = findAvg(period, x);

upper[x] = middle2 + (3.5*avg);

lower[x] = middle2 - (3.5*avg);

if (MathAbs(upper[x] - High[x]) < 2*Point)

{

Xdown[x] = upper[x];

if (NewBar() && x == 0)

Alert(Symbol()," ",Period()," reach upper edge");

}

if (MathAbs(lower[x] - Low[x]) < 2*Point)

{

Xup[x] = lower[x];

if (NewBar() && x == 0)

Alert(Symbol()," ",Period()," reach lower edge");

}

}

return(0);

}

//+------------------------------------------------------------------+

double findAvg(int period, int shift) {

double sum=0;

for (int x=shift;x<(shift+period);x++) {

sum += High[x]-Low[x];

}

sum = sum/period;

return (sum);

}

bool NewBar()

{

static datetime dt = 0;

if (dt != Time[0])

{

dt = Time[0];

return(true);

}

return(false);

//end of trend bands custom indicator

//+------------------------------------------------------------------+

//+------------------------------------------------------------------+

{

if(Hour() >= StartHour && Hour() <= StopHour){ //Nothing will happen unless the time is within the trading time

int cnt, ticket, total;

double SEma, LEma, SEmaLAST, LEmaLAST;

string comment = "";

if(reversal==true) comment = "EMA_CROSS_Counter-Trend";

if(reversal==false) comment = "EMA_CROSS_Trend-Following";

if(Bars<100)

{

Print("bars less than 100");

return(0);

}

if(TakeProfit<1)

{

Print("TakeProfit less than 1");

return(0); // check TakeProfit

}

static int isCrossed = 0;

if(ConfirmedOnEntry)

{

if(CheckValueTime==iTime(NULL,TimeFrame,0)) return(0); else CheckValueTime = iTime(NULL,TimeFrame,0);

SEma = iMA(NULL,0,ShortEma,0,MODE_EMA,PRICE_CLOSE,1);

LEma = iMA(NULL,0,LongEma ,0,MODE_EMA,PRICE_CLOSE,1);

SEmaLAST = iMA(NULL,0,ShortEma,0,MODE_EMA,PRICE_CLOSE,2);

LEmaLAST = iMA(NULL,0,LongEma ,0,MODE_EMA,PRICE_CLOSE,2);

if(SEmaLASTLEma) isCrossed = 1;

if(SEmaLAST>LEmaLAST && SEma<LEma) isCrossed = 2;

}

else

{

SEma = iMA(NULL,0,ShortEma,0,MODE_EMA,PRICE_CLOSE,0);

LEma = iMA(NULL,0,LongEma ,0,MODE_EMA,PRICE_CLOSE,0);

isCrossed = Crossed (LEma,SEma);

}

if(reversal==false)

{

if(isCrossed==1) isCrossed = 2;

else if(isCrossed==2) isCrossed = 1;

}

if(MM==true) Lots = LotSize(); //Adjust the lot size

total = OrdersTotal();

// TRAILING STOP

for(cnt=0;cnt<total;cnt++)

{

OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())

{

if(OrderType()==OP_BUY) // long position is opened

{

// check for trailing stop

if(TrailingStop>0)

{

if(Bid-OrderOpenPrice()>Point*TrailingStop)

{

if(OrderStopLoss()<Bid-Point*TrailingStop)

{

OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);

return(0);

}

}

}

}

else // go to short position

{

// check for trailing stop

if(TrailingStop>0)

{

if((OrderOpenPrice()-Ask)>(Point*TrailingStop))

{

if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))

{

OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);

return(0);

}

}

}

}

}

}

// ENTRY

if(total < 2 || isNewSumbol(Symbol())) //I have modified the if condition too: it was total<1 (orBanAway aka cucurucu)

{

double HedgeLots = (HedgePercent/100)*Lots; //calculates the Lots for the hedged position

if(isCrossed == 1 && Point < toplinevalue-longrange)

{

if(UseStopLoss)

ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Ask-StopLoss*Point,Ask+TakeProfit*Point,comment,MAGICMA,0,Green);

else

ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,comment,MAGICMA,0,Green);

if(ticket>0)

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());

}

else Print("Error opening BUY order : ",GetLastError());

//###################################################################### the added code starts here

if(UseStopLoss)

ticket=OrderSend(Symbol(),OP_SELL,HedgeLots,Bid,3,Bid+StopLoss*Point,Bid-TakeProfit*Point,comment,MAGICMA,0,Red);

else

ticket=OrderSend(Symbol(),OP_SELL,HedgeLots,Bid,3,0,Bid-TakeProfit*Point,comment,MAGICMA,0,Red);

if(ticket>0)

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());

}

else Print("Error opening SELL order : ",GetLastError());

//###################################################################### ends here

return(0);

}

if(isCrossed == 2)

{

if(UseStopLoss)

ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,Bid+StopLoss*Point,Bid-TakeProfit*Point,comment,MAGICMA,0,Red);

else

ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,comment,MAGICMA,0,Red);

if(ticket>0)

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());

}

else Print("Error opening SELL order : ",GetLastError());

//###################################################################### the added code starts here

if(UseStopLoss)

ticket=OrderSend(Symbol(),OP_BUY,HedgeLots,Ask,3,Ask-StopLoss*Point,Ask+TakeProfit*Point,comment,MAGICMA,0,Green);

else

ticket=OrderSend(Symbol(),OP_BUY,HedgeLots,Ask,3,0,Ask+TakeProfit*Point,comment,MAGICMA,0,Green);

if(ticket>0)

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());

}

else Print("Error opening BUY order : ",GetLastError());

//###################################################################### ends here

return(0);

}

return(0);

}

return(0);

}

return(0);

}

}

//+------------------------------------------------------------------+

теперь, когда я перехожу к этой строке...

if(isCrossed == 1 && Point < toplinevalue-longrange)

здесь я хочу поместить значение из индикатора для текущего бара...

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

 

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

for(int x=0; x<limit; x++) {

Xdown[x] = 0; Xup[x] = 0;

middle1[x] = iMA(NULL, 0, period, 0, MODE_EMA, PRICE_TYPICAL, x);// drawn line

middle2= iMA(NULL, 0, period, 0, MODE_SMA, PRICE_TYPICAL, x);// only used to calculate outer bands

avg = findAvg(period, x);

upper[x] = middle2 + (3.5*avg);

lower[x] = middle2 - (3.5*avg);

if (MathAbs(upper[x] - High[x]) < 2*Point)

{

Xdown[x] = upper[x];

if (NewBar() && x == 0)

Alert(Symbol()," ",Period()," reach upper edge");

}

if (MathAbs(lower[x] - Low[x]) < 2*Point)

{

Xup[x] = lower[x];

if (NewBar() && x == 0)

Alert(Symbol()," ",Period()," reach lower edge");

}

}

[/PHP]

Why not just calculate the last bar

[PHP]

int x = 0;

//Xdown[x] = 0; Xup[x] = 0;

//

// we are not using middle line

//middle1[x] = iMA(NULL, 0, period, 0, MODE_EMA, PRICE_TYPICAL, x);// drawn line

double middle2= iMA(NULL, 0, period, 0, MODE_SMA, PRICE_TYPICAL, x);// only used to calculate outer bands

avg = findAvg(period, x);

double upper = middle2 + (3.5*avg);

double lower = middle2 - (3.5*avg);

if (MathAbs(upper - High) < 2*Point)

{

// no need just alert (or open a trade)

//Xdown[x] = upper[x];

if (NewBar())

Alert(Symbol()," ",Period()," reach upper edge");

}

if (MathAbs(lower - Low) < 2*Point)

{

//Xup[x] = lower[x];

if (NewBar()) // I remove " && x == 0" because we know that x == 0

Alert(Symbol()," ",Period()," reach lower edge");

}

}

 
int x = 0;

double middle2= iMA(NULL, 0, period, 0, MODE_SMA, PRICE_TYPICAL, x);// only used to calculate outer bands

avg = findAvg(period, x);

double upper = middle2 + (3.5*avg);

double lower = middle2 - (3.5*avg); [/php]

ok that makes sense, I don't need the whole array just the current bar, so this (above code) is all that is required to calculate the top and bottom lines that needs to be in the EA?

this part (code below) confused me. I don't get the logic of it..I know it's sending alerts when the line is crossed but that's not what I need to use this for. I don't understand how it works to make the Xdown = upper , nor do I understand the logic of upper - high <2*point . To me it is a mass of confusion.

all I need to do with the top and bottom lines is know where they are in the current bar so I can determine how close to allow the point to approach them before it disallows the trade? that is the logic I want to create with the right code. I don't need alerts. Also I have not been able to find 'newbar()' in the metaeditor dictionary and the search function in metaeditor isn't working for me it's not responsive.

[php] if (MathAbs(upper - High) < 2*Point)

{

// no need just alert (or open a trade)

//Xdown[x] = upper[x];

if (NewBar())

Alert(Symbol()," ",Period()," reach upper edge");

}

if (MathAbs(lower - Low) < 2*Point)

{

//Xup[x] = lower[x];

if (NewBar()) // I remove " && x == 0" because we know that x == 0

Alert(Symbol()," ",Period()," reach lower edge");

}

}

Я просмотрел MEdictionary и увидел 'bool IsTradeAllowed( )' - это то, что я могу использовать для ограничения открытия сделок, если они слишком близки?

 

Если вы хотите узнать, близка ли верхняя линия к цене, один из способов узнать это - если разница между ними невелика (скажем, 2 пункта).

Меня не волнует (что не очень хорошая идея), находится ли цена под линией или над ней. Для меня расстояние в 2 пункта - это все, что нужно.

upper - High даст вам разницу, но не в пунктах (что-то вроде 0.0004 или -0.0004). Чтобы убедиться, что разница положительна, мы используем функцию MathAbs, которая возвращает абсолютное (положительное) значение. Теперь нам нужно проверить, меньше ли это 2 пунктов. Зарезервированное слово Point вернет значение, когда цена поднимется на 1 пункт. Для каждой пары это значение разное.

Сложим все вместе

if (MathAbs(upper - High) < 2*Point) означает, что разница меньше 2 пунктов, и для нас это достаточно близко.

На самом деле использовать High не очень хорошо, потому что High может быть выше, а текущая цена далеко. Мы должны использовать Ask вместо High (в индикаторе мы должны использовать Close[x]).

Чтобы убедиться, что цена находится выше линии, мы можем сделать следующее

if ((Ask > upper) && (Ask - upper < 2 * Point))

.....(alert or open a trade)

 

Я свел все к этому... но подождите...

если это просто использование простой скользящей средней этого одного бара, умноженной на 3,5, чтобы найти высокую точку. Как это возможно, что точка может когда-либо достичь этого? Разве значение линии не рассчитывается из того же бара, который должен коснуться ее, чтобы подать сигнал? По мере того, как бар растет, растет и линия границы?

//----------channel filter

double middle2= iMA(NULL, 0, back, 0, MODE_SMA, PRICE_TYPICAL, 0);// only used to calculate outer bands

double avg;

avg = findAvg(back, x);

double upper = middle2 + (3.5*avg);

double lower = middle2 - (3.5*avg);
Причина обращения: