
Price Action. Automatización de la estrategia de la barra interna (Inside Bar)
Introducción
Todos los traders en Forex habrán utilizado la técnica Price Action (Comportamiento del precio) en algún momento. Esto no es una simple técnica de análisis de gráficos, sino todo un sistema para determinar la posible dirección del movimiento del precio en el futuro. En este artículo, veremos el patrón de la barra interna (Inside Bar) en detalle y desarrollaremos un Asesor Experto para hacer el seguimiento de la barra interna y llevar a cabo operaciones en base al patrón.
Acerca de Price Action
Price Action es un método de detección del movimiento del precio que no se basa en los indicadores y que usa patrones sencillos o complejos, además otras herramientas gráficas (líneas horizontales, verticales y de tendencia, niveles de Fibonacci, niveles de soporte y resistencia, etc).
A primera vista, el método puede parecer muy complicado, pero en realidad no lo es. Este método es cada vez más popular, ya que sus ventajas son obvias, por ejemplo, en comparación con los métodos que implican los indicadores técnicos.
La barra interna (Inside Bar)
La barra interna es una barra cuyo cuerpo y sombras están completamente contenidos en la barra anterior (madre). El máximo de la barra interna es inferior al máximo de la barra anterior y el mínimo es superior al mínimo de la barra anterior. La barra madre y la barra interna forman un patrón considerado como una posible señal de entrada.
Es un patrón con dos opciones, ya que puede indicar una inversión o una continuidad de la tendencia.
Fig. 1 Barra interna (Inside Bar)
Fig. 2 Representación del patrón de la barra interna
Reglas de la barra interna:- El patrón de la barra interna tiene más sentido en los períodos de tiempo mayores, como H4 y D1.
- El patrón puede sugerir una inversión o una continuidad de la tendencia.
- Se puede obtener una señal de entrada más clara mediante el uso de herramientas adicionales del análisis gráfico, incluyendo las líneas de tendencia, los niveles de soporte y resistencia, los niveles de Fibonacci, otros patrones Price Action, etc.
- Para evitar las entradas prematuras o erróneas al mercado, hay que utilizar las órdenes pendientes.
- No se deben utilizar las barras internas repetidas como señales de entrada en un mercado plano.
Fig. 3 Determinar la barra interna real en GBPUSD D1
En base a todo lo anterior, vamos a tratar de definir una barra interna real. En el gráfico anterior, podemos observar que se formó una barra alcista después de un fuerte movimiento bajista. No obstante, la barra está completamente contenida en los límites de la barra anterior. Se confirma el patrón por el hecho de estar formado en el nivel de soporte. La otra prueba es la ausencia de una zona plana. Puesto que el patrón cumple con las condiciones, se puede considerar que es real.
Definir los puntos de entrada y establecer las órdenes Stop
Así que hemos encontrado una barra interna real en el gráfico (figura 3). ¿Cómo tenemos que entrar al mercado y dónde tenemos que establecer nuestras órdenes Stop? Examinemos la figura 4.
Fig. 4 Establecimiento de las órdenes Buy Stop y Stop Loss
En primer lugar, hay que tener en cuenta las reglas para establecer los niveles Stop mediante el ejemplo anterior:
- Establecemos una orden pendiente Buy Stop ligeramente por encima del máximo de la barra madre (algunos puntos por encima, para asegurarnos).
- Establecemos el nivel Stop Loss por debajo del nivel de soporte y del mínimo de la barra madre. Esto proporciona una protección adicional en caso de activar una orden pendiente y el precio rebota y alcanza el nivel de soporte antes de volver a la dirección correcta.
- Establecemos el nivel Take Profit ligeramente por debajo del nivel de resistencia más cercano.
Fig. 5 Establecimiento de las órdenes Sell Stop y Stop Loss
En primer lugar, hay que tener en cuenta las reglas para establecer los niveles Stop mediante el ejemplo anterior:
- Establecemos una orden pendiente Sell Stop ligeramente por debajo del mínimo de la barra madre (algunos puntos por debajo, para asegurarnos).
- Establecemos el nivel Stop Loss por encima del máximo de la barra madre.
- Establecemos el nivel Take Profit ligeramente por encima del nivel de soporte más cercano.
Desarrollo de un Asesor Experto basado en el Trading con la barra interna
Ahora que conocemos todas las reglas necesarias para definir una barra interna, entrar al mercado y establecer las órdenes Stop, podemos por fin implementar el Asesor Experto adecuado para operar mediante el patrón de la barra interna.
Abrimos MetaEditor a partir del terminal de MetaTrader 4 y creamos un nuevo Asesor Experto (no voy a entrar en los detalles de cómo crear Asesores Expertos, ya que hay bastante información sobre este tema en el sitio web). De momento, se dejan todos los parámetros en blanco. Puede poner el nombre que quiera. Este sería el código:
//+------------------------------------------------------------------+ //| InsideBar.mq4 | //| Copyright 2015, Iglakov Dmitry. | //| cjdmitri@gmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, Iglakov Dmitry." #property link "cjdmitri@gmail.com" #property version "1.00" #property strict //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+
Convertir el patrón en un algoritmo MQL4
Después de haber creado el Asesor Experto, tenemos que definir una barra interna al cerrarse una vela. Para ello, introducimos nuevas variables y les asignamos unos valores. Véase el siguiente código:
//+------------------------------------------------------------------+ //| InsideBar.mq4 | //| Copyright 2015, Iglakov Dmitry. | //| cjdmitri@gmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, Iglakov Dmitry." #property link "cjdmitri@gmail.com" #property version "1.00" #property strict double open1,//first candle Open price open2, //second candle Open price close1, //first candle Close price close2, //second candle Close price low1, //first candle Low price low2, //second candle Low price high1, //first candle High price high2; //second candle High price //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- define prices of the necessary bars open1 = NormalizeDouble(iOpen(Symbol(), Period(), 1), Digits); open2 = NormalizeDouble(iOpen(Symbol(), Period(), 2), Digits); close1 = NormalizeDouble(iClose(Symbol(), Period(), 1), Digits); close2 = NormalizeDouble(iClose(Symbol(), Period(), 2), Digits); low1 = NormalizeDouble(iLow(Symbol(), Period(), 1), Digits); low2 = NormalizeDouble(iLow(Symbol(), Period(), 2), Digits); high1 = NormalizeDouble(iHigh(Symbol(), Period(), 1), Digits); high2 = NormalizeDouble(iHigh(Symbol(), Period(), 2), Digits); } //+------------------------------------------------------------------+
Como ejemplo, vamos a considerar que la barra madre es bajista (barra 2), mientras que la barra interna es alcista (barra 1). Vamos a añadir unas condiciones al código de la función OnTick():
void OnTick() { //--- define prices of the necessary bars open1 = NormalizeDouble(iOpen(Symbol(), Period(), 1), Digits); open2 = NormalizeDouble(iOpen(Symbol(), Period(), 2), Digits); close1 = NormalizeDouble(iClose(Symbol(), Period(), 1), Digits); close2 = NormalizeDouble(iClose(Symbol(), Period(), 2), Digits); low1 = NormalizeDouble(iLow(Symbol(), Period(), 1), Digits); low2 = NormalizeDouble(iLow(Symbol(), Period(), 2), Digits); high1 = NormalizeDouble(iHigh(Symbol(), Period(), 1), Digits); high2 = NormalizeDouble(iHigh(Symbol(), Period(), 2), Digits); //--- if the second bar is bearish, while the first one is bullish if(open2>close2 && //the second bar is bullish close1>open1 && //the first bar is bearish high2>high1 && //the bar 2 High exceeds the first one's High open2>close1 && //the second bar's Open exceeds the first bar's Close low2<low1) //the second bar's Low is lower than the first bar's Low { //--- we have listed all the conditions defining that the first bar is completely within the second one } }
- Creamos unas variables personalizables: órdenes Stop, deslizamiento (slippage), tiempo de expiración de órdenes, número mágico del Asesor Experto, lote del trading. Se puede omitir Stop Loss, puesto que se establece de acuerdo con las reglas de la barra interna.
- Introducimos las variables locales para normalizar el formato de las variables.
- Se establecen las órdenes Stop a cierta distancia de los valores del precio de la barra. Para ello, añadimos la variable Interval que se encarga del intervalo entre los precios máximo/mínimo de las barras y de los niveles de las órdenes Stop, además de los niveles de las órdenes pendientes.
- Añadimos la variable timeBarInside para evitar la reapertura de órdenes en este patrón.
- Añadimos la variable bar2size para asegurarnos de que la barra madre es bastante grande, lo que indica que el mercado actual no es plano.
Como resultado, obtenemos el siguiente código:
//+------------------------------------------------------------------+ //| InsideBar.mq4 | //| Copyright 2015, Iglakov Dmitry. | //| cjdmitri@gmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, Iglakov Dmitry." #property link "cjdmitri@gmail.com" #property version "1.00" #property strict extern int interval = 20; //Interval extern double lot = 0.1; //Lot Size extern int TP = 300; //Take Profit extern int magic = 555124; //Magic number extern int slippage = 2; //Slippage extern int ExpDate = 48; //Expiration Hour Order extern int bar2size = 800; //Bar 2 Size double buyPrice,//define BuyStop price buyTP, //Take Profit BuyStop buySL, //Stop Loss BuyStop sellPrice, //define SellStop price sellTP, //Take Profit SellStop sellSL; //Stop Loss SellStop double open1,//first candle Open price open2, //second candle Open price close1, //first candle Close price close2, //second candle Close price low1, //first candle Low price low2, //second candle Low price high1, //first candle High price high2; //second candle High price datetime _ExpDate=0; //local variable to define a pending order expiration time double _bar2size; datetime timeBarInside; //time of the bar, at which inside bar orders were opened, to avoid re-opening //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { double _bid = NormalizeDouble(MarketInfo(Symbol(), MODE_BID), Digits); //define a lower price double _ask = NormalizeDouble(MarketInfo(Symbol(), MODE_ASK), Digits); //define an upper price double _point = MarketInfo(Symbol(), MODE_POINT); //--- define prices of the necessary bars open1 = NormalizeDouble(iOpen(Symbol(), Period(), 1), Digits); open2 = NormalizeDouble(iOpen(Symbol(), Period(), 2), Digits); close1 = NormalizeDouble(iClose(Symbol(), Period(), 1), Digits); close2 = NormalizeDouble(iClose(Symbol(), Period(), 2), Digits); low1 = NormalizeDouble(iLow(Symbol(), Period(), 1), Digits); low2 = NormalizeDouble(iLow(Symbol(), Period(), 2), Digits); high1 = NormalizeDouble(iHigh(Symbol(), Period(), 1), Digits); high2 = NormalizeDouble(iHigh(Symbol(), Period(), 2), Digits); //--- _bar2size=NormalizeDouble(((high2-low2)/_point),0); //--- if the second bar is bearish, while the first one is bullish if(timeBarInside!=iTime(Symbol(),Period(),1) && //no orders have been opened at this pattern yet _bar2size>bar2size && //the second bar is big enough, so the market is not flat open2>close2 && //the second bar is bullish close1>open1 && //the first bar is bearish high2>high1 && //the bar 2 High exceeds the first one's High open2>close1 && //the second bar's Open exceeds the first one's Close low2<low1) //the second bar's Low is lower than the first one's Low { //--- we have listed all the conditions defining that the first bar is completely within the second one timeBarInside=iTime(Symbol(),Period(),1); //indicate that orders are already placed on this pattern } } //+------------------------------------------------------------------+
Determinar los niveles de las órdenes Stop
Ahora que está todo preparado, sólo nos falta determinar los niveles de las órdenes Stop y los precios de las órdenes. Además, no hay que olvidar calcular el tiempo de expiración de las órdenes.
Vamos a añadir el siguiente código a la función OnTick():
buyPrice=NormalizeDouble(high2+interval*_point,Digits); //define an order price considering the interval buySL=NormalizeDouble(low2-interval*_point,Digits); //define a stop loss considering the interval buyTP=NormalizeDouble(buyPrice+TP*_point,Digits); //define a take profit _ExpDate=TimeCurrent()+ExpDate*60*60; //a pending order expiration time calculation sellPrice=NormalizeDouble(low2-interval*_point,Digits); sellSL=NormalizeDouble(high2+interval*_point,Digits); sellTP=NormalizeDouble(sellPrice-TP*_point,Digits);
Corrección de los errores de ejecución
Si ya ha desarrollado algunos Asesores Expertos, seguro que sabe que los errores ocurren a menudo al cerrar y establecer las órdenes, incluyendo el tiempo de espera, los valores erróneos, etc. Para eliminar estos errores tenemos que escribir una función por separado que incluye un pequeño procesador de errores básicos.
//+----------------------------------------------------------------------------------------------------------------------+ //| The function opens or sets an order | //| symbol - symbol, at which a deal is performed. | //| cmd - a deal (may be equal to any of the deal values). | //| volume - amount of lots. | //| price - Open price. | //| slippage - maximum price deviation for market buy or sell orders. | //| stoploss - position close price when an unprofitability level is reached (0 if there is no unprofitability level).| //| takeprofit - position close price when a profitability level is reached (0 if there is no profitability level). | //| comment - order comment. The last part of comment can be changed by the trade server. | //| magic - order magic number. It can be used as a user-defined ID. | //| expiration - pending order expiration time. | //| arrow_color - open arrow color on a chart. If the parameter is absent or equal to CLR_NONE, | //| the open arrow is not displayed on a chart. | //+----------------------------------------------------------------------------------------------------------------------+ int OrderOpenF(string OO_symbol, int OO_cmd, double OO_volume, double OO_price, int OO_slippage, double OO_stoploss, double OO_takeprofit, string OO_comment, int OO_magic, datetime OO_expiration, color OO_arrow_color) { int result = -1; //result of opening an order int Error = 0; //error when opening an order int attempt = 0; //amount of performed attempts int attemptMax = 3; //maximum amount of attempts bool exit_loop = false; //exit the loop string lang=TerminalInfoString(TERMINAL_LANGUAGE); //trading terminal language, for defining the language of the messages double stopllvl=NormalizeDouble(MarketInfo(OO_symbol,MODE_STOPLEVEL)*MarketInfo(OO_symbol,MODE_POINT),Digits); //minimum stop loss/ take profit level, in points //the module provides safe order opening. //--- check stop orders for buying if(OO_cmd==OP_BUY || OO_cmd==OP_BUYLIMIT || OO_cmd==OP_BUYSTOP) { double tp = (OO_takeprofit - OO_price)/MarketInfo(OO_symbol, MODE_POINT); double sl = (OO_price - OO_stoploss)/MarketInfo(OO_symbol, MODE_POINT); if(tp>0 && tp<=stopllvl) { OO_takeprofit=OO_price+stopllvl+2*MarketInfo(OO_symbol,MODE_POINT); } if(sl>0 && sl<=stopllvl) { OO_stoploss=OO_price -(stopllvl+2*MarketInfo(OO_symbol,MODE_POINT)); } } //--- check stop orders for selling if(OO_cmd==OP_SELL || OO_cmd==OP_SELLLIMIT || OO_cmd==OP_SELLSTOP) { double tp = (OO_price - OO_takeprofit)/MarketInfo(OO_symbol, MODE_POINT); double sl = (OO_stoploss - OO_price)/MarketInfo(OO_symbol, MODE_POINT); if(tp>0 && tp<=stopllvl) { OO_takeprofit=OO_price -(stopllvl+2*MarketInfo(OO_symbol,MODE_POINT)); } if(sl>0 && sl<=stopllvl) { OO_stoploss=OO_price+stopllvl+2*MarketInfo(OO_symbol,MODE_POINT); } } //--- while loop while(!exit_loop) { result=OrderSend(OO_symbol,OO_cmd,OO_volume,OO_price,OO_slippage,OO_stoploss,OO_takeprofit,OO_comment,OO_magic,OO_expiration,OO_arrow_color); //attempt to open an order using the specified parameters //--- if there is an error when opening an order if(result<0) { Error = GetLastError(); //assign a code to an error switch(Error) //error enumeration { //order closing error enumeration and an attempt to fix them case 2: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt Sleep(3000); //3 seconds of delay RefreshRates(); break; //exit switch } if(attempt==attemptMax) { attempt=0; //reset the amount of attempts to zero exit_loop = true; //exit while break; //exit switch } case 3: RefreshRates(); exit_loop = true; //exit while break; //exit switch case 4: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt Sleep(3000); //3 seconds of delay RefreshRates(); break; //exit switch } if(attempt==attemptMax) { attempt = 0; //reset the amount of attempts to zero exit_loop = true; //exit while break; //exit switch } case 5: exit_loop = true; //exit while break; //exit switch case 6: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt Sleep(5000); //3 seconds of delay break; //exit switch } if(attempt==attemptMax) { attempt = 0; //reset the amount of attempts to zero exit_loop = true; //exit while break; //exit switch } case 8: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt Sleep(7000); //3 seconds of delay break; //exit switch } if(attempt==attemptMax) { attempt = 0; //reset the amount of attempts to zero exit_loop = true; //exit while break; //exit switch } case 64: exit_loop = true; //exit while break; //exit switch case 65: exit_loop = true; //exit while break; //exit switch case 128: Sleep(3000); RefreshRates(); continue; //exit switch case 129: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt Sleep(3000); //3 seconds of delay RefreshRates(); break; //exit switch } if(attempt==attemptMax) { attempt = 0; //reset the amount of attempts to zero exit_loop = true; //exit while break; //exit switch } case 130: exit_loop=true; //exit while break; case 131: exit_loop = true; //exit while break; //exit switch case 132: Sleep(10000); //sleep for 10 seconds RefreshRates(); //update data //exit_loop = true; //exit while break; //exit switch case 133: exit_loop=true; //exit while break; //exit switch case 134: exit_loop=true; //exit while break; //exit switch case 135: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt RefreshRates(); break; //exit switch } if(attempt==attemptMax) { attempt = 0; //set the number of attempts to zero exit_loop = true; //exit while break; //exit switch } case 136: if(attempt<attemptMax) { attempt=attempt+1; //define one more attempt RefreshRates(); break; //exit switch } if(attempt==attemptMax) { attempt = 0; //set the amount of attempts to zero exit_loop = true; //exit while break; //exit switch } case 137: if(attempt<attemptMax) { attempt=attempt+1; Sleep(2000); RefreshRates(); break; } if(attempt==attemptMax) { attempt=0; exit_loop=true; break; } case 138: if(attempt<attemptMax) { attempt=attempt+1; Sleep(1000); RefreshRates(); break; } if(attempt==attemptMax) { attempt=0; exit_loop=true; break; } case 139: exit_loop=true; break; case 141: Sleep(5000); exit_loop=true; break; case 145: exit_loop=true; break; case 146: if(attempt<attemptMax) { attempt=attempt+1; Sleep(2000); RefreshRates(); break; } if(attempt==attemptMax) { attempt=0; exit_loop=true; break; } case 147: if(attempt<attemptMax) { attempt=attempt+1; OO_expiration=0; break; } if(attempt==attemptMax) { attempt=0; exit_loop=true; break; } case 148: exit_loop=true; break; default: Print("Error: ",Error); exit_loop=true; //exit while break; //other options } } //--- if no errors detected else { if(lang == "Russian") {Print("Ордер успешно открыт. ", result);} if(lang == "English") {Print("The order is successfully opened.", result);} Error = 0; //reset the error code to zero break; //exit while //errorCount =0; //reset the amount of attempts to zero } } return(result); } //+------------------------------------------------------------------+
Como resultado, obtenemos el siguiente código:
//+------------------------------------------------------------------+ //| InsideBar.mq4 | //| Copyright 2015, Iglakov Dmitry. | //| cjdmitri@gmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, Iglakov Dmitry." #property link "cjdmitri@gmail.com" #property version "1.00" #property strict extern int interval = 20; //Interval extern double lot = 0.1; //Lot Size extern int TP = 300; //Take Profit extern int magic = 555124; //Magic number extern int slippage = 2; //Slippage extern int ExpDate = 48; //Expiration Hour Order extern int bar2size = 800; //Bar 2 Size double buyPrice,//define BuyStop price buyTP, //Take Profit BuyStop buySL, //Stop Loss BuyStop sellPrice, //define SellStop price sellTP, //Take Profit SellStop sellSL; //Stop Loss SellStop double open1,//first candle Open price open2, //second candle Open price close1, //first candle Close price close2, //second candle Close price low1, //first candle Low price low2, //second candle Low price high1, //first candle High price high2; //second candle High price datetime _ExpDate=0; //local variable to define a pending order expiration time double _bar2size; datetime timeBarInside; //time of the bar, at which inside bar orders were opened, to avoid re-opening //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { double _bid = NormalizeDouble(MarketInfo(Symbol(), MODE_BID), Digits); //define a lower price double _ask = NormalizeDouble(MarketInfo(Symbol(), MODE_ASK), Digits); //define an upper price double _point = MarketInfo(Symbol(), MODE_POINT); //--- define prices of the necessary bars open1 = NormalizeDouble(iOpen(Symbol(), Period(), 1), Digits); open2 = NormalizeDouble(iOpen(Symbol(), Period(), 2), Digits); close1 = NormalizeDouble(iClose(Symbol(), Period(), 1), Digits); close2 = NormalizeDouble(iClose(Symbol(), Period(), 2), Digits); low1 = NormalizeDouble(iLow(Symbol(), Period(), 1), Digits); low2 = NormalizeDouble(iLow(Symbol(), Period(), 2), Digits); high1 = NormalizeDouble(iHigh(Symbol(), Period(), 1), Digits); high2 = NormalizeDouble(iHigh(Symbol(), Period(), 2), Digits); //--- _bar2size=NormalizeDouble(((high2-low2)/_point),0); //--- if the second bar is bearish, while the first one is bullish if(timeBarInside!=iTime(Symbol(),Period(),1) && //no orders have been opened at this pattern yet _bar2size>bar2size && //the second bar is big enough, so the market is not flat open2>close2 && //the second bar is bullish close1>open1 && //the first bar is bearish high2>high1 && //the bar 2 High exceeds the first one's High open2>close1 && //the second bar's Open exceeds the first one's Close low2<low1) //the second bar's Low is lower than the first one's Low { buyPrice=NormalizeDouble(high2+interval*_point,Digits); //define an order price considering the interval buySL=NormalizeDouble(low2-interval*_point,Digits); //define a stop loss considering the interval buyTP=NormalizeDouble(buyPrice+TP*_point,Digits); //define a take profit _ExpDate=TimeCurrent()+ExpDate*60*60; //pending order expiration time calculation sellPrice=NormalizeDouble(low2-interval*_point,Digits); sellSL=NormalizeDouble(high2+interval*_point,Digits); sellTP=NormalizeDouble(sellPrice-TP*_point,Digits); OrderOpenF(Symbol(),OP_BUYSTOP,lot,buyPrice,slippage,buySL,buyTP,NULL,magic,_ExpDate,Blue); OrderOpenF(Symbol(),OP_SELLSTOP,lot,sellPrice,slippage,sellSL,sellTP,NULL,magic,_ExpDate,Blue); //--- we have listed all the conditions defining that the first bar is completely within the second one timeBarInside=iTime(Symbol(),Period(),1); //indicate that orders are already placed on this pattern } } //+------------------------------------------------------------------+
Vamos compilar el código y comprobar si hay mensajes de error en el registro.
Prueba del asesor experto
Es el momento de probar nuestro Asesor Experto. Vamos a ejecutar la prueba de estrategias y establecer los parámetros de entrada. He establecido los parámetros de la siguiente manera:
Fig. 6 Parámetros de entrada para la prueba
- Seleccionamos un símbolo (en este caso es CADJPY).
- Hay que asegurarse de elegir el modo "Cada tick" y seleccionar la casilla "Utilizar datos" para llevar a cabo la prueba. He seleccionado todo el año 2014.
- Establecemos el período de tiempo D1.
- Iniciamos la prueba.
- Una vez finalizada la prueba, comprobamos el diario. Como se puede observar, no se ha producido ningún error durante el proceso.
La siguiente figura muestra el diario de la prueba del Asesor Experto:
Fig. 7 Diario de la prueba del Asesor Experto
Nos aseguramos de que no hay ningún error y optimizamos el Asesor Experto
Optimización
He seleccionado los siguientes parámetros para la optimización:
Fig. 8 Parámetros de la optimización
Fig. 9 Ajustes de la optimización
Como resultado, obtenemos el Asesor Experto listo para su uso.
Resultados de la optimización y la prueba
Fig. 10 Resultados de la prueba
Fig. 11. Gráfico de los resultados de la prueba
Conclusión
- Hemos desarrollado un Asesor Experto para el trading con el patrón de la barra interna.
- Hemos visto que los patrones Price Action pueden funcionar incluso sin filtros adicionales para entrar al mercado.
- No hemos recurrido a ningún truco (tipo martingala o promediado).
- Al establecer correctamente las órdenes Stop, se ha reducido la disminución al mínimo.
- No se ha utilizado ningún indicador técnico. Se basa el Asesor Experto únicamente en la lectura del gráfico "básico".
¡Gracias por leer el artículo! Espero que le haya resultado útil.
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/1771





- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso