Ayuda con la codificación... ¿Cómo puedo hacer que el indicador filtre en lugar de alertar? - página 3
Está perdiendo oportunidades comerciales:
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Registro
Entrada
Usted acepta la política del sitio web y las condiciones de uso
Si no tiene cuenta de usuario, regístrese
Creo que la mejor manera de hacerlo es NO usando el indicador. Es la forma más sencilla. Para empezar es suficiente.
Usted está viendo los cambios que hice en el indicador. Si quieres usar este, asegúrate de escribir el nombre correcto dentro de tu código.
mientras sepas en que buffer se encuentra la información que quieres, no importa cuantos indicadores haya en el códigook así que estas diciendo que lo más simple no es necesariamente lo mejor...y que la mejor manera sería escribir el indicador dentro del EA...pero para hacer eso siguiendo los ejemplos de las lecciones la única parte que decía que se copiara en el EA era la parte de la función de iteración y los buffers están en la parte de la función de inicialización del código...entonces ¿copio TODO el código del indicador en el EA? Como lo hago para hacerlo de la mejor manera...con el indicador en el EA? ¿Podría mostrarme por favor? Creo que estoy aprendiendo. Me gusta.
En el caso de los indicadores, el código es el mismo que el de los indicadores, pero no es el mismo que el de los indicadores, sino que es el mismo que el de los indicadores, pero no es el mismo que el de los indicadores. Como lo hago para hacerlo de la mejor manera...con el indicador en el EA? ¿Podría mostrarme por favor?
Por supuesto que no. Sólo la parte lógica. En realidad, tengo un ejemplo que hacer precisamente eso (Traté de escribir que yo mismo, pero estoy trabajando ahora en una nueva forma de ver el precio, y que toma todo mi tiempo)
Puedes tenerlo aquí. (no es woking bueno, necesita tiempo para arreglarlo, pero u puede ver cómo combinar el código juntos)
En este EA u puede establecer el TF que u quiere llegar al borde al mismo tiempo, o utilizar sólo un TF
¡¡¡Genial!!! ¡¡¡¡Usted tiene la idea!!!!
Funcionará perfectamente. y si quieres comprobar que 5M y 15M alcanzan el borde al mismo tiempo puedes obtener los valores de cada TF y probarlos juntos.
Pero deja eso para después....Tengo un buen maestro.
Ahora que tengo 'esa' idea ilumíname el resto del camino sobre cómo hacer esto de la 'mejor' manera y escribir el indicador dentro de la EA ... He hecho que en cierta medida ya .... pero no conseguí los búferes copiados en la EA ... supongo que tiene que ser insertado eh?
¿cuánto de esto realmente tiene que ser copiado en la EA?
//| 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);
}tal vez debería hacerlo de la manera que me mostraste por ahora y llamar al indicador.... es más simple.
Tengo un buen maestro.
Ahora que tengo 'esa' idea ilumíname el resto del camino sobre cómo hacer esto de la 'mejor' manera y escribir el indicador dentro del EA...ya lo he hecho hasta cierto punto....pero no conseguí que los buffers se copiaran en el EA...supongo que hay que insertarlo eh?
¿cuánto de esto realmente tiene que ser copiado en la EA?
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
.......
//---- indicators
//----
return(0);
}Nada. Esto no es la lógica, es la parte visual del indicador
Serán necesarios dos posts para mostrar todo lo que he hecho hasta ahora....site no aceptará todo de una vez... no dejes que te sobrecargue de información... sólo quiero mostrarte lo que he hecho hasta ahora...
primera mitad...
//| 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 |
//+------------------------------------------------------------------+
la segunda mitad...
//| 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);
}
}
//+------------------------------------------------------------------+ahora cuando llego a esta línea...
if(isCrossed == 1 && Point < toplinevalue-longrange)
aquí es donde quiero poner el valor del indicador para la barra actual...
¿cómo llamo a la información del código anterior para la barra actual cuando ya está dentro del EA? En realidad esto lo había hecho mucho ayer antes de que me enseñaras a llamar al indicador con el icustom(). Antes de deshacer todo lo que ya he hecho me pregunto si se puede completar tal cual y funcionar mejor que deshacerlo todo y luego hacer que llame al indicador?
Como he dicho, no tienes que lidiar con la historia. estás llenando todo el buffer sólo para obtener el último valor
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");
}
}
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");
}
}He estado mirando en el MEdictionary y y veo un 'bool IsTradeAllowed( )' es que lo que podría utilizar para limitar los oficios de la apertura si es demasiado cerca?
Si quieres saber si la línea superior está cerca del precio, una forma de averiguarlo es si la diferencia entre ellos es pequeña (digamos 2 puntos).
No me importa (que no es una buena idea) si el precio está por debajo de la línea o por encima de la línea. Para mí 2 puntos de distancia es todo lo que se necesita. por lo que la diferencia es
upper - High te dará la diferencia pero no en puntos (es algo así como 0.0004 o -0.0004) . Para asegurarnos de que la diferencia es positiva usamos la función MathAbs que devuelve el valor absoluto (positivo). Ahora tenemos que comprobar si es menos de 2 puntos. La palabra reservada Point devolverá el valor cuando el precio suba 1 pip. Es diferente con cada par.
Ponerlo todo junto
if (MathAbs(upper - High) < 2*Point) significa que la diferencia es menor a 2 pips, y para nosotros es suficiente.
En realidad usar High no es bueno, porque el High puede estar por encima, pero el precio actual está muy lejos. Tenemos que usar Ask en lugar de High (en el indicador tenemos que usar Close[x])
Para asegurarnos de que el precio está por encima de la línea podemos hacer lo siguiente
if ((Ask > upper) && (Ask - upper < 2 * Point))
.....(alert or open a trade)
Lo reduje a esto... pero espera...
si esto es solo usar la media móvil simple de esta barra multiplicada por 3.5 para encontrar un punto alto. ¿Cómo es posible que el punto pueda llegar a esto? ¿no se está calculando el valor de la línea desde la misma barra que tendría que tocarla para dar la señal? A medida que la barra sube también lo hace la línea de borde???
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);