Mi primer "Grial"
"...el arte no se puede programar, no se pueden crear
dos sentidos de una poesía. Los talentos no se pueden
plantar
. Nacen. Son riqueza
nacional, como depósitos de radio,
como septiembre en Sigulda, o Bethesda..."
(Andrey Voznesenskiy)
Generalmente se cree que el Santo Grial es la copa de la Cristo bebió en La Última Cena y la que utilizó José de Arimatea para coger su grande cuando estaba colgado en la cruz. Algunos escritores presentan el grial como una piedra que emana una sustancia que evita que quien la tenga, muera en esa semana. Puede leer más aquí o usar cualquier herramienta de búsqueda en internet.
La palabra "grial" se utiliza a menudo irónicamente entre los programadores modernos. Para ellos significa la imposibilidad de crear un programa "universal" para cualquier ocasión. En cuanto a la programación en MQL4, esta palabra significa la imposibilidad de crear un experto que dé buenos resultados en el trading real.
En realidad, forex es el reflejo de un complejo conglomerado de fenómenos económicos y relaciones industriales, caracteres humanos, política, etc. Es más, es tan importante que no se puede formalizar sin más. Los traders con más experiencia recomiendan entrar en el mercado sólo si hay de tres a cinco (o incluso más) señales que indican que un trend es posible.
Al mismo tiempo, las regularidades determinadas hoy en día, no pueden proporcionar una base profunda para los pronósticos de mercado con altas probabilidades de éxito. El pronóstico contradictorio que hacen los principales analistas de los bancos y organizaciones financieras más importantes lo confirman. Todos los analistas, sin excepción, pueden interpretar muy bien los eventos que ya han ocurrido, pero sólo unos cuantos pueden dar una serie de pronósticos seguros.
Vamos a hablar de ellos: Estas personas hacen lo que pueden hacer, la mayoría de ellos tienen mucha experiencia en trading y tienen muchos conocimientos que nosotros querríamos tener. Sin embargo, vamos a llamar a las cosas por su nombre: prácticamente todos ellos se equivocan a menudo. Pueden ver muchas cosas, disfrutar de más o menos popularidad, crear a veces mucho dinero (en el libro de Alexander Elder ,Ganarse la vida haciendo trading: Psicología, tácticas de trading, gestión del dinerose describen muy bien a los "gurús" de distintos tipos) pero el hecho es que, incluso los analistas con más experiencia, se equivocan a menudo.
Así que, teniendo en cuenta estas circunstancias, ¿cuáles son las posibilidades de un programador novel que está dando sus primeros pasos en el trading en Forex? Vamos a marcar el camino que hace el principiante en su búsqueda del "Grial".
1. De qué está formado el "Grial"
En la lógica formal, hacer referencia a una autoridad no se considera una prueba. Sabiendo esto, las razones del primer "grialer" van más o menos en esta dirección: "¿Puedes demostrar que la creación del "grial" es imposible? ¿No? Entonces, ¡es posible!" El principiante no tiene en cuenta que la posibilidad de la creación de algo así tampoco se ha demostrado todavía. Y, por lo tanto, sin considerar o, a menudo, sin estudiar las experiencias de otros "cazadores de tesoros", sino inspirados por el pensamiento de "¡Voy a poder hacerlo!", basándose exclusivamente en su entusiasmo y poca experiencia, empieza a programar.
1,1. Estrategia formal
En la mayoría de los casos, el programador principiante no se otorga la tarea de crear una estrategia de trading con muchos beneficios en poco tiempo. Llevado por el sueño de grandes beneficios en Forex en poco tiempo, sin embargo, se da cuenta de que se requieren una serie de criterios precisos de trading para un experto que dé beneficios.
Para encontrar los buenos criterios, el programados abre la Terminal de Cliente de Meta Trader 4 y mira el gráfico de EURUSD en el periodo de tiempo M1. Es muy fácil darse cuenta que el tipo de moneda varia en curvas: arria y abajo, arriba y abajo. El programador decide sacar beneficio a estas ondas. Pero, para "atrapar" una onda, hay que saber, de alguna manera, que la onda ha parado, por ejemplo, de subir y ha empezado a bajar.
- Considerar que hay que entrar al mercado en dirección hacia abajo (Venta) si la tasa ha subido algunos puntos; por ejemplo, de 10 a 15 (movimiento A-B en la img alt="". 1) y luego ha dejado de subir y ha bajado unos tres puntos (movimiento B-C en la img alt="".1). En este momento, se puede pronosticar el movimiento descendente del mercado (C-D en la img alt="". 1). Para la Compra se usa el mismo criterio.
-
Considerar que hay que entrar al mercado en dirección hacia arriba (Compra) si la tasa ha bajado algunos puntos; por ejemplo, de 10 a 15 (movimiento C-D en la img alt="". 1) y luego ha dejado de bajar y ha subido unos tres puntos (movimiento D-E en la img alt="".1). En este momento, se puede pronosticar el movimiento ascendente del mercado (E-F en la img alt="". 1). Para cerrar la venta se usa el mismo criterio.
img 1. Los criterios de trading para el Grial Experto_1 (Grial 1).
La vida siempre nos prepara experiencias increíbles e inesperadas. El programador principiante sólo tardó 3 días en crear su primer "grial".
extern int TP=100; extern int SL=100; extern int lim=1; extern int prodvig=3; extern double Prots= 10; int total, bb=0,ss=0; double max,min,lmax,lmin,Lot; int start(){ total=OrdersTotal(); if (total==0){bb=0;ss=0;} if (max<Bid) max=Bid;if (min>Ask) min=Ask; if (((max-Bid)>=lim*Point)&&(Bid>lmax )) { for (int i=total;i>=0;i--) { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderType()==OP_BUY) {OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE); bb=0;}} Strateg(1); } if (((Ask-min)>=lim*Point)&&(lmin>Ask )) { for (i=total;i>=0;i--) { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderType()==OP_SELL) {OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE);ss=0;}} Strateg(2);}return;} void Strateg (int vv) {if (vv==1 && ss==0) {OrderSend(Symbol(),OP_SELL,Lots(),Bid,3,Bid+SL*Point,Bid-TP*Point,"",0,0,Red); ss=1;} if (vv==2 && bb==0) {OrderSend(Symbol(),OP_BUY, Lots(),Ask,3,Ask-SL*Point,Ask+TP*Point,"",0,0,Blue);bb=1;} lmax=Ask+prodvig*Point; lmin=Bid-prodvig*Point; return; } double Lots(){ Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1); double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); if (Lot==0 ) Lot=Min_Lot; return(Lot); }
Eso es lo que hay. Vamos a ser buenos - esta es la primera experiencia del programador principiante, que todavía tiene un estilo sin moldear. Y vamos a respetar este experto, ya que funciona y muestra un resultado fantástico.
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // Graal_1.mq4 (Grail 1). // Used as an example in the article My First "Grail". // Sergey Kovalyov, Dnepropetrovsk (Ukraine),sk@mail.dnepr.net,ICQ 64015987, http://autograf.dp.ua/ //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж extern int TP = 100; // TakeProfit orders extern int SL = 100; // StopLoss orders extern int lim= 1; // Distance of the rate return extern int prodvig=3; // Distance of the rate progress extern double Prots= 10; // Percentage of the liquid assets //-------------------------------------------------------------------------------------------- int total, // Count of lots bb=0, // 1 = the Buy order is available ss=0; // 1 = the Sell order is available //-------------------------------------------------------------------------------------------- double max, // Maximum price at the peak (abs.) min, // Minimum price in the trough(abs.) lmax, // Limiting price after the exceeding // of which we consider selling(abs.) lmin, // The same for buying Lot; // Count of lots //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int start() { //============================================================================================ total=OrdersTotal(); // Count of lots if (total==0) // If there are no orders, .. { bb=0; // .. no Buys ss=0; // .. no Sells } if (max<Bid) max=Bid; // Calculate the max. price at the peak if (min>Ask) min=Ask; // Calculate the min. price in the trough //------------------------------------------------------------- The price turns down ---- if (((max-Bid)>=lim*Point)&&(Bid>lmax )) // Turn at a high level { for (int i=total;i>=0;i--) // On all orders { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderType()==OP_BUY) { OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE);// Close Buy bb=0; // No Buys anymore } } Strateg(1); // Opening function } //------------------------------------------------------------ The price turns up ---- if (((Ask-min)>=lim*Point)&&(lmin>Ask )) // Turn at the deep bottom { for (i=total;i>=0;i--) // On all orders { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderType()==OP_SELL) { OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE);// Close Sell ss=0; // No Sells anymore } } Strateg(2); // Opening function } //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж void Strateg (int vv) // Opening function { //============================================================================================ if (vv==1 && ss==0) // Sell situation and no Sells { OrderSend(Symbol(),OP_SELL,Lots(),Bid,3,Bid+SL*Point,Bid-TP*Point,"",0,0,Red);// Откр ss=1; // Now, there is a Sell } //-------------------------------------------------------------------------------------------- if (vv==2 && bb==0) // Buy situation and no Buys { OrderSend(Symbol(),OP_BUY, Lots(),Ask,3,Ask-SL*Point,Ask+TP*Point,"",0,0,Blue);// Откр bb=1; // Now, there is a Buy } //-------------------------------------------------------------------------------------------- lmax=Ask+prodvig*Point; // Redefine the new limiting .. lmin=Bid-prodvig*Point; // .. levels for open and close //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж double Lots() // Calculation of lots { //============================================================================================ Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Calculate the amoung of lots double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); // Minimum permissible cost of lots if (Lot == 0 ) Lot = Min_Lot; // For testing on const.min.lots //============================================================================================ return(Lot); } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж /*
Generalmente, los contenidos del experto son algo incomprensibles.
En la parte superior, antes de la función start(), se recopilan variables. En la función start(), primero se calcula la posición actual de la divisa en la pendiente de un pico, y se analiza la situación para iniciar los criterios de trading. Y, si los criterios se inician, se cierra la orden que ya se ha procesado. En el experto se usan otras dos funciones: Strateg(), para abrir nuevas órdenes; y Lots(), para determinar la cantidad de lotes. Para registrar las órdenes abiertas, se utilizan las variables ss y bb.
El Tester de estrategia es muy importante en la Terminal de Cliente de MetaTrader 4. Nuestro programador ha probado el experto detalladamente para mejorar las entradas y uno de los mejores resultados ha sido el siguiente:Nos podemos imaginar la alegría del programador: ¡Ha creado esta obra de arte con sus propias manos! Aquí está: Nueva, sustancial y brillante con todas sus facetas perfectas, ¡su primer "grial"! Y llega a una conclusión simple: "¡Solo yo!"
1.2. Gran inversión
img . 3. Las inversiones agresivas pueden resultar en pérdidas injustificadas
Nuestro héroe estaba muy sorprendido con el resultado. Razonó así: "Si el experto da beneficios, ¡cuanto más inviertas, más consigues!". Pero los resultados del tester muestran que no es así a menudo.
1.2.1 Progresión geométrica
Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Calculate the amount of lots double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); // Minimum allowed lot value if (Lot == 0 ) Lot = Min_Lot; // For testing on const.min.lots
Este algoritmo representa una progresión geométrica. La variable de Prots (porcentaje) permite regular el valor de la orden dependiendo de la cantidad actual de liquidez. De este modo, calcular el valor de la orden no es correcto del todo, ya que no tiene en cuenta las llamadas de margen cuando se trabaja con un vendedor específico. Al mismo tiempo, el fragmento del código de arriba permite solucionar el problema principal: el problema de las inversiones proporcionales. Por lo que el valor de cada orden siguiente dependerá proporcionalmente en los resultados obtenidos: el valor crecerá después de cada trade con beneficios y se reducirá después de cada trade sin beneficios. El valor de la orden en del código del Grial_1.mq4 (Grial 1) representa el 10% de la liquidez.
Vamos a establecer el valor de la variable Prost a 0 y, según el código de abajo,
if (Lot == 0 ) Lot = Min_Lot; // For testing on const.min. lots
vamos a probar el experto en el valor del de la orden constante.
En este caso, el resultado será el siguiente:
img. 4. Resultados de la prueba del experto Graal_1.mq4 (Grial 1) en los valores de lote constante.
La exclusión de los valores progresivos de la orden visualiza la verdadera naturaleza de los cambios de las curvas: aumento, caídas profundas, etc.
1.2.2 Reinversión agresiva
Cualquier experto con beneficios, siempre irá a por su ventana entre beneficio y pérdida. Actualmente, no existe ninguna tecnología que permita realizar sólo trades con beneficios. Los trades con pérdidas son una norma en cualquier estrategia de trading que funcione de verdad. Lo que importa sólo es el proporción entre las operaciones con beneficios y pérdidas.
B. Abajo hay un ejemplo de las situaciones más probables de distribución no uniforme de los trades con beneficios y pérdidas durante trading real:
Se muestra una serie de 5 pérdidas consecutivas, aunque estas series pueden ser incluso más largas. Tiene que tener en cuenta que, en este caso, la proporción entre pedidos con beneficios y con pérdidas se ha mantenido en 3: 1.
Entonces, ¿en qué puede resultar esta aleatoriedad regular? La respuesta a esta pregunta depende de la calidad de la estrategia de trading que haya elegido el trader. Una cosa es, si el trader hace trading de forma deliberada, teniendo las precauciones razonables, donde el valor total de sus pedidos no excede el 10 o 15% del depósito; y otra cosa es que el trader permita las inversiones agresivas: invierte la gran parte de su depósito, sólo una vez, pero cada vez que lo hace, gana beneficios.
-
Alternativa 1. El valor de una orden es el 10% de la liquidez (Prost=10). Con estas condiciones, la prueba permite que el experto consiga un buen ritmo de trabajo, aumentando deliberadamente la balance, pero de forma pernante. Se pueden ver los resultados de este trabajo en la img alt="".2. También puede verse en la Fig.2 que el experto ha estado mucho tiempo trabajando (unos 10 000 pedidos)
-
Alternativa 2. El valor de una orden es el 70% de la liquidez (Prost=70). Los resultados de la prueba se ven en la Fig.3. En esta prueba, resultan dos o tres series de pérdidas sucesivas, por lo que el depósito se ha vaciado por completo antes de que el experto hiciera 400 trades.
Por favor, preste atención al informe de los resultados de la prueba. La cantidad máxima de pérdidas consecutivas (una serie de pedidos con pérdidas) para el experto Grial_1mq4 (Grial 1) es sólo 10. Durante todo el periodo de prueba, ocurrieron otras series de pérdidas, pero la cantidad de pérdidas en cada uno de ellos no sobrepasó 10. Estas series de pérdidas no influenciaron mucho al resultado total del trading en la Alternativa 1, pero han sido desastrosas en la Alternativa 2.
Por lo tanto, una serie corta de pérdidas con las inversiones erróneas puede resultar en un completo desastre. Se ha desarrollado un sistema efectivo para la gestión correcta del capital - Money Management. Según este sistema, el valor de una orden no debería superar el 15% del balance total, y la cantidad total de la inversión no debería superar el 50%. Este sistema ofrece algunas otras reglas útiles que ha leído nuestro programador.
Por lo tanto, una vez que ha probado su "grial" y se ha asegurado de que todo funciona bien, el programador abre una cuenta real y empieza a "hacer dinero". Después de abrir y cerrar satisfactoriamente un número de pedidos, resulta que la balanza no está creciendo, sino descendiendo constantemente. Es más, el equipo del centro de operaciones ha desactivado su cuenta.
El programador está bastante enfadado. Quiere saber las razones de tal injusticia y no está de acuerdo con ninguna explicación. Está perplejo: ¿Qué "limitaciones técnicas"? ¿Qué tiene que ver con "pérdida"? Como resultado de una primera experiencia en trading así, el programador ha llegado a la conclusión de que este es un "mal centro de operaciones", y que le han engañado..Rompe el contacto con el centro de operaciones.
Sin embargo, no se rinde, y decide ver los detalles del proceso, y se pone en contacto con compañeros con más experiencia en el foro especializado en MQL4 donde lo primero que hacen es proponerle que muestre el código. Al principio se lo guarda, pero al final accede, ya que, el experto parece no estar generando beneficios de todos modos... El programador entiende lo siguiente después de las cosas que se han hablado en el foro.
1.3. Errores
El Meta Editor confirmaba constantemente que no había ningún error.
pero nunca los hubo.
1.3.1 Digresión de la Estrategia Formal
Aunque hay un poco de conocimiento de la estrategia en la creación del experto, se cambió durante la codificación y la optimización de las variables genéricas. Así que, la idea inicial se presenta ahora en un "grial" bastante reducido. De hecho, la idea era ganar ondas de 15 a 20 puntos de largo, pero este parámetro obtuvo un valor miserable de 3 en la versión actual del "grial". Quién iba a querer hablar aquí de altibajos...
Fíjese en cómo se consideran las órdenes en las variables ss y bb. No es la forma correcta de considerarlas. Se considera que el pedido ya está abierto cuando aún se está formando. Pero no se puede saber con antelación si se abrirá o no. Para estar seguro de esto, hay que esperar hasta que el servidor conteste y analizar entonces la disponibilidad de la orden en la terminal. Para el trading real, esta parte del código debería volver a escribirse, aunque las modificaciones que se han hecho funcionarán en la mayoría de los casos, incluso en la prueba de estrategia (ver el artículo Considering Orders ina Large Program ).
1.4. Restricciones de hardware
El experto se probó en el periodo de tiempo para el que estaba destinado: en M1. Hay que prestar mucha atención cuando se moldea el trading de los expertos en el periodo de tiempo M1, sobre todo en los expertos sensibles a los precios.
La diferencia principal entre el modelo de prueba y la estrategia de trading real, es que el modo de prueba no provoca desfase ni recotización (cuando el vendedor da otro precio diferente al que está en el pedido del trader).
Los diferentes centros de operaciones trabajan con diferentes proveedores (de los que se hablará después). Cuando más y con más frecuencia cambie la divisa, más probabilidades hay de que el vendedor proponga al trader realizar el pedido con otro precio. Por otro lado, cuanto más "suavizado" parezca el tráfico, menos probable será la recotización, pero menos espacio habrá para el experto que hace trading con frecuencia y con logros pequeños.
El programador probó el Grial_1 (Grial 1) en un historial de 1-minuto de otro centro de operaciones (con la misma extensión) y vio con sus propios ojos que el resultado depende muchísimo del tipo de tráfico.
img. 6. Los resultados de la prueba del Grial_1.mq4 (Grial 1) en el historial M1 de EURUSD del 4 de abril al 26 de julio de 2006 en los términos de trading del servidor demo FX_Integralbank con pedidos de ódenes constantes
La presencia de caídas profundas, el desarollo inestable de los beneficios, muestran las balances del experto al límite de la pérdida.
Como norma general, la los precios de la recotización varían 1 o 2 puntos (aunque pueden ser más en un mercado rápido). Este fenómeno no puede influir esencialmente en el éxito del experto si se esperan recompensas mucho más grandes, por ejemplo, entre 10/15. Pero si se espera que la recompensa de un experto sea pequeña, especialmente si es menos de 2, no se puede esperar un éxito general, ya que depende mucho de la naturaleza de la cotización y la recotización en cuestión.
Que el vendedor recotice o no el tick actual, es una cuestión a parte que sólo puede responder él. Pero, al empezar a trabajar en el mercado real, hay que asumir que la recotización es algo normal, un fenómeno natural, y que la tecnología de trading que trabaje en una cuenta real, tiene que tenerlo en cuenta.
1.5. Aspectos económicos
- Precios pequeños de pedidos
Esta situación es más común cuando la atención del trader está totalmente enfocada a su cuenta de trading y sus eventos, como estrategias, expertos, etc. Sin embargo, a parte de la preocupación del trader, también hay una preocupación económica por parte del vendedor.
En el trading "normal", las dos partes pueden salir ganando: el trader que usa una buena estrategia, y el vendedor, que obtiene intereses de la operación que realice el trader. En este caso, ambas partes se preocupan la una de la otra y ambas están preparadas para apoyarse mutuamente.
Sin embargo, puede ocurrir que las actividades de una de las partes sea contraria a los intereses de la otra. Por ejemplo, si el vendedor aumenta la difusión, deshabilita el trading automático, o no abre pedidos (cerrados) al primer momento del precio, etc. esto va contra los intereses del trader.
Al mismo tiempo, el trader puede hacer algunas cosas que vayan contra los intereses económicos del vendedor. Una de ellas son las operaciones de trade frecuentes con cantidades pequeñas de dinero.
La tecnología de trabajo del vendedor es más bien siemple. El vendedor recoge las órdenes del trader para comprar y vender, y se relaciona con un banco u otra institución financiera para procesar las diferencias en los precios. Vamos a examinar un ejemplo muy simple. Suponga que el vendedor tiene un total de 100 trades, 60 de los cuales han comprado por 1 lote EURUSD, y los otros 40 han vendido por 1 lote el mismo par de divisas. En este caso, el vendedor debe comprar 20 lotes (la diferencia entre 60 y 40) al banco. En ese momento, da lo mismo en qué dirección mueva el vendedor los precios. En cualquier caso, el vendedor obtendrá la extensión completa por 80 lotes (40+40) y una extensión parcial de 20 lotes (una parte se le dará al banco por sus servicios).
En este caso, la fuente de beneficios/pérdidas para 40 traders es la pérdida/beneficio de otros 40 traders. La fuente de beneficio/pérdida del los otros 20 traders es el banco o, para ser más exactos, las personas legales proporcionadas por el banco, y las monedas de venta/compra de sus operaciones de exportación-importación. Esta es la forma normal de interacción entre los participantes del mercado del dinero.
Pero hay un detalle raro más en la forma de interactuar del vendedor con el banco o la institución financiera. El problema es que el vendedor no interactúa con el banco en cada operación de compra o venta, si el trader vende o compra una cantidad de dinero insignificante. Las operaciones de trade entre el vendedor y el banco se hacen con menos frecuencia que los clics que hace el trader en la terminal de MT4. Normalmente, la cantidad mínima de relaciones entre el vendedor y el banco no excede los 50 000 dólares americanos, que se traduce en el precio de la orden con un aprovechamiento de 1:100 por un lote de 0,5. Es por esto que, si el trader trabaja siempre con una cantidad pequeña de dinero, de hecho, hace el trading con el vendedor. En este caso, la fuente del beneficio del trader es el dinero del vendedor.
El vendedor es tan participante del dinero del mercado como los demás. El vendedor debe observar y analizar el trabajo de todos los traders. Por supuesto, los vendedores, en su preocupación económica, pueden hacer la vista gorda con las inversiones irregulares repetidas si resultan en pérdidas evidentes para el trader, o su resultado total durante un periodo de tiempo concreto (por ejemplo, el resultado diario) es neutral. Pero ningún vendedor razonable permitirá que continúen estas interrelaciones si éstas resultan en pérdidas para él. En este caso, el vendedor tiene que reaccionar de alguna manera, sino no hay nada para él en el territorio económico del mercado monetario.
Por favor, tenga en cuenta que la rutina moderna del mercado monetario no es la mala voluntad de los vendedores. Las relaciones del vendedor con el banco también son contraídas. Y el vendedor se esfuerza por ganar la extensión de manera justa (en este artículo no se habla de los abusos de los vendedores). El vendedor se alegrará, probablemente, de hacer trading con el banco a cada segundo, pero no existe esa posibilidad en este momento.
Bajo las condiciones de operaciones frecuentes de trade pequeñas que realiza un trader, el vendedor tiene que tomar ciertas medidas. Puede enviar una notificación al trader en la que le diga que su trabajo es de locos. El vendedor también puede deshabilitar el trading automático de este trader o aumentar la cantidad de las operaciones recotizadas.
- Precios grandes de pedidos
Hay una limitación más que diferencia el trading real de las pruebas o el trading en las cuentas demo. El valor máximo del precio del lote. Ningún centro de operaciones, ya sea un banco, la oficina de un corredor de apuestas, o una institución financiera, puede hacer operaciones con cantidades muy grandes de dinero.
Si las órdenes cuestan de 10 000 a 20 000 dólares americanos (por favor, tenga en cuenta que hay un aprovechamiento que normalmente es igual a 100), el centro de operaciones venderá/comprará a 1 000 000 dólares americanos. Esta cantidad es muy grande, pero los vendedores han aprendido a trabajar con cantidades así de grandes y tienen bastante éxito.
En una institución financiera pequeña o mediana, pueden surgir algunas dificultades si el precio de la orden supera los 50 000 o incluso los 100 000 dólares americanos. En este caso, en el mercado intebancario, la cantidad que aparece es de 5 a 10 millones de dólares americanos. Esta cantidad de dinero no es fácil de vender/comprar en un sólo movimiento.
Pueden ocurrir situaciones difíciles si el precio de la orden supera los 300 000 a 500 000 dólares americanos. En este caso, el centro de operaciones trabajará individualmente con el trader. 50 millones de dólares es muchísimo dinero en cualquier situación.
En el caso de precios muy elevados, la firma de garantía del centro de operaciones no se cuestiona, y el trading se realiza basándose en que el trader lo entiende y lo acepta. (De hecho, ¿qué vendedor puede tomarse la libertad de abrir una orden que cueste tanto dinero en el primer contacto, con el riesgo de movimientos del mercado grandes e inesperados?)
Por este motivo, los expertos en trading que especulan con millones, son una prueba de un gran error del trader y no tiene nada que ver con la vida real.
Este razonamiento sugirió al programador ganar los 100 000 "pavos" iniciales y luego encontrar "la peor oficina". El programador se queda callado y piensa "todo está controlado".
No olvidemos que los vendedores son gente normal con su cultura y su educación, y que tienen sus negocios funcionando de una u otra forma. La misma tecnología, que no es beneficiosa para los vendedores, se puede detectar inmediatamente cuando el trabajo del analista es eficiente, y los vendedores que trabajan con mitades, que no tienen mucha experiencia, o que no poseen el software necesario, no pueden detectarla fácilmente. Pero en la mayoría de los casos, los vendedores son antiguos "grialers", tienen experiencia en trading y generalmente se agarran muy bien a todos los detalles del trading en el mercado monetario, por lo que saben qué es la progresión geométrica, la preocupación económica, las reinversiones agresivas, y precios de pedidos pequeños y grandes. Generalmente, cada trader tiene que actuar sabiendo que las cualificaciones del vendedor son más altas que las suyas, y que la posición del vendedor en prácticamente cualquier tema está justificada.
Juzguen ustedes mismos: ¿Cuáles pueden ser los resultados (bajo las condiciones técnicas y económicas explicadas arriba) del trabajo de un experto que abre más de 20 000 pedidos en un año?
El cerebro del programador está dando vueltas con todos estos ticks, barras, puntos, extensiones, vendedores y bancos. Decide que no quiere entrar detalles o "preguntas sencillas". Está satisfecho con lo que entiende por "los resultados de la prueba no coinciden con el trading real". Y decide que construirá la tecnología adecuada basada en pedidos pendientes. "¡No me pillarán!", piensa.
2. El segundo "Grial"
2.1 Estrategia
La idea de construir un experto de pedidos abiertos llega a la mente del programador después de que haya estudiado el comportamiento de los tipos de cambio cruzado EURGBP y EURCHF en gráficos de 1-minuto.
img. 8. Historial de tipos de cambio cruzado en regiones con importantes desvíos en los precios (picos)
Por muy fácil que parezca, cuando la sesión europea ya ha terminado, y la asiática aún no ha empezado, algunos símbolos de los gráficos tienen barras con precios inesperados que son totalmente diferentes del flujo "normal" de precios. Desde la lógica formal, basta con colocar las órdenes pendientes en el tipo Límite un tanto arriba y un tanto abajo de la corriente principal, y parte de ellos se abrirán con unas posibilidades de éxito bastante altas. Para que las órdenes pendientes reaccionen de forma adecuada a los cambios de la corriente principal, deben "arrastrarse" por alguna línea mediana y soportar constantemente cierta distancia de la línea MP (Movimiento Promedio). El programador ha escrito un experto para comprender la idea:
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // Graal_2.mq4 (Grail 2). // Used as an example in the article My First "Grail". // Sergey Kovalyov, Dnepropetrovsk (Ukraine),sk@mail.dnepr.net,ICQ 64015987, http://autograf.dp.ua/ //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж extern int TakeProfit=5; // TakeProfit orders extern int StopLoss= 29; // StopLoss orders extern int Distan = 2; // Distance from the МА line extern int Cls = 2; // Close at ** points of profit extern int period_MA=16; // MA period //extern int Time_1 = 0; // Starting time //extern int Time_2 = 0; // Finishing time extern int Prots = 0; // Percentage of free assets //-------------------------------------------------------------------------------------------- int Nom_bl, // BuyLimit order number Nom_sl, // SellLimit total, // Count of lots bl = 0, // 1 = BuyLimit order availability sl = 0, // 1 = SellLimit order availability b = 0, // 1 = Buy order availability s = 0; // 1 = Sell order availability //-------------------------------------------------------------------------------------------- double OP, // OpenPrice (absolute points) SL, // StopLoss orders (relative points) TP, // TakeProfit orders (relative points) dist, // Distance from МА (relative points) Level, // Min.allowed distance of a pending order OP_bl, // OpenPrice BuyLimit (absolute points) OP_sl, // OpenPrice SellLimit(absolute points) cls, // Close at ** profit (absolute points) MA, // MA value (rate) spred, // Spread (absolute points) Lot; // Count of lots //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int init() { Level=MarketInfo(Symbol(),MODE_STOPLEVEL); // Check what the server shows us Level=(Level+1)*Point; // ?:) SL=StopLoss*Point; // StopLoss orders (relative points) TP=TakeProfit*Point; // TakeProfit orders (relative points) dist=Distan*Point; // Distance from the MA line(relative points) cls=Cls*Point; // Close at ** profit (absolute points) spred=Ask-Bid; // Spread (absolute points) return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int start() { //============================================================================================ total=OrdersTotal(); // Count of lots bl=0; // Zeroize at the start of the pass sl=0; // Zeroize at the start of the pass b=0; // Zeroize at the start of the pass s=0; // Zeroize at the start of the pass //-------------------------------------------------------------------------------------------- for (int i=total; i>=0; i--) // For all orders { if (OrderSelect(i,SELECT_BY_POS)==true && // Select an order OrderSymbol()==Symbol()) { //-------------------------------------------------------------------------------------------- if (OrderType()==OP_BUY) // Buy order { b =1; // The order found Close_B(OrderTicket(),OrderLots()); // Close the order (the function decides // whether it is necessary) } //-------------------------------------------------------------------------------------------- if (OrderType()==OP_SELL) // Sell order { s =1; // The order found Close_S(OrderTicket(),OrderLots()); // Close the order (if necessary) } //-------------------------------------------------------------------------------------------- if (OrderType()==OP_BUYLIMIT) // BuyLimit order { OP_bl=NormalizeDouble(OrderOpenPrice(),Digits);//OpenPrice BuyLimit(absolute points) Nom_bl=OrderTicket(); bl=1; // The order found } //-------------------------------------------------------------------------------------------- if (OrderType()==OP_SELLLIMIT) // SellLimit order { OP_sl=NormalizeDouble(OrderOpenPrice(),Digits);//OpenPrice SellLimit(absolute points) Nom_sl=OrderTicket(); sl=1; // The order found } //-------------------------------------------------------------------------------------------- } } //-------------------------------------------------------------------------------------------- MA = iMA(NULL,0, period_MA, 0,MODE_LWMA, PRICE_TYPICAL, 0);// The MA current value Modify_order(); // Activate modification Open_order() ; // Activate opening //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж void Close_B(int Nomber, double lots) // Close Buy orders { //============================================================================================ if (NormalizeDouble(Bid-OrderOpenPrice(),Digits)>=cls)// If the preset profit is reached { OrderClose( Nomber, lots, Bid, 1, Yellow); // Close b = 0; // No Buy order anymore } //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж void Close_S(int Nomber, double lots) // Close Sell orders { //============================================================================================ if (NormalizeDouble(OrderOpenPrice()-Ask,Digits)>=cls)// If the preset order is reached { OrderClose( Nomber, lots, Ask, 1, Yellow); // Close s = 0; // No Sell order anymore } //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж void Modify_order() // Modification of orders { //============================================================================================ if (bl==1) // If there is BuyLimit { OP=MA-dist; // it must be located here if (MathAbs(OP_bl-OP)>0.5*Point) // if it is not located here { OrderModify(Nom_bl,OP,OP-SL,OP+TP,0,DeepSkyBlue);// The order modification } } //-------------------------------------------------------------------------------------------- if (sl==1) // If there is SeelLimit { OP=MA+spred+dist; // It must be located here if (MathAbs(OP_sl-OP)>0.5*Point) // If it is not located here { OrderModify( Nom_sl, OP, OP+SL, OP-TP, 0, Pink);// The order modification } } //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж void Open_order() // An opening function { // int Tek_Time=TimeHour(CurTime()); // To test by the time // if (Tek_Time>Time_2 && Tek_Time> //============================================================================================ if (b==0 && bl==0) // No Buy orders, open bl { OP=MA-dist; // bl order open rate if(OP>Ask-Level) OP=Ask-Level; // OP precision according to the tolerance OP=NormalizeDouble(OP,Digits); // Normalizing (MA gives the 5th digit) OrderSend(Symbol(),OP_BUYLIMIT, Lots(),OP,3,OP-SL,OP+TP,"",0,0,Blue);// Open bl=1; // Now there is a Buy order b1 } //-------------------------------------------------------------------------------------------- if (s==0 && sl==0) // No Sell orders, open sl { OP=MA+spred+dist; // sl order open rate if(OP<Bid+Level) OP=Bid+Level; // OP precision according to the tolerance OP=NormalizeDouble(OP,Digits); // Normalizing (MA gives the 5th digit) OrderSend(Symbol(),OP_SELLLIMIT,Lots(),OP,3,OP+SL,OP-TP,"",0,0,Red);// Open sl=1; // Now there is a Sell order sl } ///============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж double Lots() // Calculation of lots { //============================================================================================ Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Calculate the amount of lots double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); // Minimum lot values if (Lot == 0 ) Lot = Min_Lot; // For testing on const.min.lots //============================================================================================ return(Lot); } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж /*
StopLoss, TakeProfit, Distan (distancia a la que se mantiene la orden por la corriente principal), CIs (cantidad mínima de los puntos ganados en la orden, que debe cerrarse cuando los puntos alcancen este valor), periodo_MA (el periodo MA; el MA aquí es la línea media de divisas del último historial), y Prots (el porcentaje de activos, el precio de la orden) se han elegido como variables ajustables. Esto es más que suficiente para comprender la idea.
-
En la función especial start(), se analizan las órdenes (los métodos de consideración de órdenes se describen aquí) y se toma simultáneamente la decisión de qué hacer con algunos de ellos. Si hay una orden abierta en la terminal, se llamará inmediatamente a la función Close_*() correspondiente, donde se analizará la necesidad de cerrar la orden y se cerrará.
-
Al final de la función start(), se abren las funciones Modify_order() y Open_order() para modificar y abrir, respectivamente, las órdenes abiertas pendientes de tipo Límite. No se abren otros pedidos.
-
En la función Modify_order(), se calcula la ubicación de la orden (a cierta distancia de la línea media) y, si no está colocada en el lugar correcto, se moverá.
-
En la función Open_order(), se determina también el lugar adecuado para colocar el pedido pendiente. En este momento, se consideran las limitaciones del servidor y, si no hay ningún pedido, se coloca ahí.
img. 9. Los resultados de la prueba en Graal_2.mq4 (Grial 2) en el historial de marzo 2005 a junio de 2006, en el gráfico M1 EURUSD bajo las condiciones de trading de la compañía MIG_Investments
2.2. Progresión geométrica
img.10. Los resultados de la prueba en Graal_2.mq4 (Grial 2) en el historial de marzo 2005 a junio de 2006, en el gráfico M1 EURUSD bajo las condiciones de trading de la compañía MIG_Investments con precios constantes de las órdenes.
Originalmente, el programador quería ganar dinero sólo por la noche, pero luego se sorprendió de que el experto trabajara satisfactoriamente durante todo el día. ¿Vale de algo decir que después de haber visto esto, el programador decide de nuevo: "¡Yo solo!" y empieza a "crear dinero" de nuevo? Pero no pasa nada de eso... Esta vez, el programador tiene que familiarizarse con los "picos".
2.3. Errores
En el ejemplo de experto anterior, hay una gran catidad de defectos y soluciones de programación incorrectas. En la función Modify_order(), la distancia mínima permitida para las órdenes pendientes no se tiene en cuenta, las órdenes abiertas que se tienen en cuenta están organizadas de forma incorrecta; TakeProfit no se modifica por separado para "fomentar" el beneficio de CIs, la parte analítica del experto se "desvanece" por todo el código, etc.
La programación incorrecta y, lo que es más, la programación descuidada, a menudo resulta en errores que no pueden distinguirse y, a veces, en réplicas de errores que se integra con otros expertos.
2.4. Restricciones técnicas (Picos)
Por norma general, todas las restricciones, ya sean téncnias o de organización, se convertirán al final en pérdidas económicas. La pregunta es, a costa de qué se cubrirán estas pérdidas.
Cuando el trader ve un gráfico de velas normal en el monitor, es un resultado medio del desarrollo del mercado en un territorio específico (entre los bancos europeos, por ejemplo). Se puede analizar el comportamiento de la divisa en un periodo de historia con diferentes vendedores. En este momento, es fácil ver que todos los gráficos van a ser diferentes unos de otros, aunque sea ligeramente. Los gráficos de algunos vendedores contendrán lotes de velas largas en varias direcciones, mientras que los gráfios de otros vendedores mostrarán "silencio y tranquilidad".
Un gráfico de tick también es un objeto de venta. Es el resultado del trabajo de algún programa de procesamiento que filtra precios de ticks excesivos e innaturales. Y aparecen (los "ticks innaturales"). Esto ocurre cuando una persona en un banco, por algún motivo personal (puede pasar cualquier cosa, ¿no?) ha comprado o vendido una cantidad a un precio que difiere bastante del precio del mercado. El programa de procesamiento acepta esta información y, si una transacción así sólo ocurre una vez, no lo considera a la hora de crear el gráfico final. En algunas ocasiones, el programa tiene dificultades en comprender qué precios son "normales" y cuáles no. Por este motivo, las velas simples de diferentes longitudes (dependiendo del algoritmo del programa de procesamiento) aparecen a veces en el gráfico. Estos son los picos. Esto aparece de formas diferentes, pero no muestran la situación real del mercado monetario.
No es muy difícil hacer un experto que pille estos picos y las órdenes abiertas cuando los precios son más beneficiosos. Pero hay que entender que, en los contratos determinados entre el vendedor y el banco, normalmente el banco no paga una transacción así al vendedor. Esto quiere decir que la fuente de beneficio del trader es, de nuevo, el bolsillo del vendedor. Y el vendedor no quiere que esto ocurra, claro, así que pelea con los traders para realizar operaciones de trading con precios de mercado "normales".
Como una medida para generar esta oportunidad para el vendedor, el contrato entre el vendedor y el trader suele contener cláusulas sobre los derechos del vendedor, en las que se incluyen la posible recotización, apertura no garantizada de pedidos con precios elevados, apertura de pedidos pendientes en una segunda vuelta, y otras precauciones. En algunos casos, el vendedor puede cancelar una orden que ya se ha abierto si, según su opinión, el pedido se ha abierto en un pico.
Esto es lo que le ocurrió al programador. Por muy bien que aparezca en la cuenta demo, el grial se corrigió de nuevo. Esta vez, el programador no cierra el receptor y escucha atentamente a los vendedores cada vez que explican las razones por las que se ha forzado el cierre de las órdenes. Pero cuando el vendedor deshabilita los expertos, el programador no pudo soportarlo y rompió de nuevo el contrato.
Ahora, el programador cree que el perioodo de tiempo de 1-minuto es el culpable de sus continuos fracasos. Una vez que ha leído los posts en los foros, y ha hablado con otros traders, el programador ve que la mayoría de ellos trabajan en periodos de tiempo más largos con los mismos símbolos. "Esto tiene sentido", piensa. Poco a poco, el programador llega a la conclusión de "Mozart y yo" y se quita el abrigo para desarrollar su tercera creación: ya no la hará en los gráficos M1, ("¡Nunca, nuca más!").
3. El tercer "Grial"
3.1 Estrategia formal
Después de estudiar con detenimiento el gráfico EURUSD H1 y utilizando diferentes indicadores para analizarlo, el programador ha descubierto una regularidad muy atractiva: Si el MP (Movimiento Promedio) de un periodo de tiempo más corto se encuentra con el MP de un periodo más largo, el mercado suele moverse en la misma dirección que el MP del periodo más corto.img. 11. La representación gráfica de la estrategia basada en el intercruzado de MPs con periodos diferentes
El programador también se ha dado cuenta de que esta interrelación aparece en todos los periodos de tiempo, pero ha decidido trabajar sólo con los largos. Sólo le queda traducir el conocimiento adquirido en MQL4 para poder informar al experto de la dirección y las condiciones en las que tiene que abrir las órdenes. Y, cuando el experto esté listo, es necesario mejorar sus parámetros: escoger las duraciones de MP más efectivas y colocar adecuadamente StopLoss y TakeProfit.
Esta vez, ha nacido este experto://жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // Graal_3.mq4 (Grail 3). // Used as an example in the article My First "Grail". // Sergey Kovalyov, Dnepropetrovsk (Ukraine),sk@mail.dnepr.net,ICQ 64015987, http://autograf.dp.ua/ //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // // //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж extern int MA1 = 11; // Period of the first MA extern int MA2 = 23; // Period of the second MA extern double TP = 50; // TakeProfit orders extern double SL = 15; // StopLoss orders extern double Prots= 0; // Percentage of free assets //-------------------------------------------------------------------------------------------- int ret, // Direction of intersection total; // Count of open orders //-------------------------------------------------------------------------------------------- double Lot, // Count of lots Pred, // Preceding value of the 1st MA(red) Tek, // Current value of the 1st MA (red) Golub; // Current value of the 2nd MA (blue) //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int init() { //============================================================================================ SL = SL*Point; // StopLoss in points TP = TP*Point; // TakeProfit in points return; //============================================================================================ } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int start() { //============================================================================================ total=OrdersTotal(); // Total amount of orders if (total==2)return; // Both orders are already open //-------------------------------------------------------------------------------------------- Tek =iMA(NULL,0, MA1, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Current value of the 1st MA Pred =iMA(NULL,0, MA1, 0,MODE_LWMA, PRICE_TYPICAL, 1);// Preceding value of the 2nd MA Golub=iMA(NULL,0, MA2, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Current value of the 2nd MA //-------------------------------------------------------------------------------------------- if (Peresechenie()==1) Open_Buy(); // Movement bottom-up = open Buy if (Peresechenie()==2) Open_Sell(); // Movement top-down = open Sell //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Peresechenie() // Function determining intersection { //============================================================================================ if ((Pred<=Golub && Tek> Golub) || (Pred< Golub && Tek>=Golub) ) ret=1; // Intersection bottom-up //-------------------------------------------------------------------------------------------- if ((Pred>=Golub && Tek< Golub) || (Pred> Golub && Tek<=Golub) ) ret=2; // Intersection top-down //============================================================================================ return(ret); // Return the intersection direction } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Open_Buy() // Function opening Buy { //============================================================================================ if (total==1) // If there is only one order... { // ... it means another can be opened OrderSelect(0, SELECT_BY_POS); // Select the order if (OrderType()==0)return; // If it is Buy, do not open } OrderSend(Symbol(),0, Lots(), Ask, 0, Ask-SL, Ask+TP, "", 0, 0, Blue);// open //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Open_Sell() // Function opening Sell { //============================================================================================ if (total==1) // If there is only one order... { // ... it means another can be opened OrderSelect(0, SELECT_BY_POS); // Select the order if (OrderType()==1)return; // If it is Sell, do not open } OrderSend(Symbol(),1, Lots(), Bid, 0, Bid+SL, Bid-TP, "", 0, 0, Red);// Open //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж double Lots() // Calculation of lots { //============================================================================================ Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Calculate the amount of lots double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); // Minimum lot values if (Lot == 0 ) Lot = Min_Lot; // For testing on const. min. lots //============================================================================================ return(Lot); } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж /*
Este experto, como los anteriores, era más bien simple.
Empieza con el bloque que describe las variables. En la función start() se definen la cantidad total de pedidos, y los valores de MP para los periodos más largos y más cortos. Si se encuentran los MPs, se llama a la función correspondiente para que abra las órdenes: Open_*() Para especificar que los MP se han encontraro, se utiliza la función Peresechenie(), y para averiguar el valor de los lotes, se utiliza la función Lots().
en el gráfico H1 EURUSD bajo las condiciones de trading del servidor demo de la compañía MetaQuotes Software Corp.
¡Tres millones en cinco meses! ¡Maravilloso! Pero hay algo en este gráfico que al programador le recuerda la amargura de las experiencias anteriores. Y decide ir un poco más despacio.
3.2. Progresión
Después de haber probaro el mismo experto con precios de pedidos constantes, mostró un gráfico de balance bastante aceptable:
bajo las condiciones de trading del servidor demo con lotes de precios constantes de la compañía MetaQuotes Software Corp.
Seis mil puntos en cinco meeses; se podría cortar con un cuchillo, ¡Más de mil puntos al mes! Pero el programador duda si configurar o no el experto para el trading real. Después de todo, se ha equivocado ya dos veeces...
3.3. Errores
"¡Qué extraño! ¡Debe pasarle algo al MetaEditor!" fue lo primero que pensó. Pero luego, una vez que analizó el código sucesivamente, volvió a encontrar errores. Vamos a hablar de ellos.
3.3.1 Desviaciones de la estrategia inicial - Errores algorítmicos
Mire a la siguiente función:
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Peresechenie() // Function that detects the intersection { //================================================================================================= if ((Pred<=Golub && Tek> Golub) || (Pred< Golub && Tek>=Golub) ) ret=1; // Bottom-up intersection //------------------------------------------------------------------------------------------------- if ((Pred>=Golub && Tek< Golub) || (Pred> Golub && Tek<=Golub) ) ret=2; // Top-down intersection //================================================================================================= return(ret); // Return the intersection direction } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
Parece que todo está bastante claro, ¿qué podemos encontrar? Pero sigue habiendo un error. Es en ese momento, cuando se usa la variable global ret, cuando el valor se guarda igual al último que se ha calculado, es decir, 1 o 2. Por este motivo, la función Peresechenie(), sin tener en cuenta la situación actual, vuelve al último valor calculado. Por eso se le ordena abrirse constantemente en la función start():
if (Peresechenie()==1) Open_Buy(); // Bottom-up movement = open Buy if (Peresechenie()==2) Open_Sell(); // Top-down movement = open Sell
Para cambiarlo, es suficiente con darle valor cero a la variable ret al principio de la función Peresechenie(). Una vez que ha encontrado el error algorítmico, el programador lo corrije y escribe un fragmento al mismo tiempo, que permite abrir sólo una barra. Ahora el experto tiene este aspecto:
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // Graal_31.mq4 (Grail 31) // Used as an example in the article My First "Grail" // Sergey Kovalyov, Dnepropetrovsk, sk@mail.dnepr.net, ICQ 64015987, http://autograf.dp.ua/. //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // // //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж extern int MA1 = 11; // Period of the 1st MA extern int MA2 = 23; // Period of the 2nd MA extern double TP = 50; // TakeProfit orders extern double SL = 15; // StopLoss orders extern double Prots= 0; // Percentage of free assets //-------------------------------------------------------------------------------------------- int New_Bar, // 0/1 The fact of new bar forming Time_0, // The new bar beginning time ret, // Intersection direction total; // Count of open orders //-------------------------------------------------------------------------------------------- double Lot, // Count of lots Pred, // Previous value of the 1st MA (red) Tek, // Current value of the 1st MA (red) Golub; // Current value of the 2nd MA (blue) //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int init() { //============================================================================================ SL = SL*Point; // SL in points TP = TP*Point; // ТР in points return; //============================================================================================ } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int start() { //============================================================================================ total=OrdersTotal(); // Total count of orders if (total==2)return; // Both orders already opened //----------------------------------------------------------------------------- New bar ------ New_Bar=0; // First zeroize if (Time_0 != Time[0]) // If the bar beginning time changed { New_Bar= 1; // Here we have a new bar Time_0 = Time[0]; // Remember the new bar beginning time } //-------------------------------------------------------------------------------------------- Tek =iMA(NULL,0, MA1, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Current value of the 1st MA Pred =iMA(NULL,0, MA1, 0,MODE_LWMA, PRICE_TYPICAL, 1);// Previous value of the 2nd MA Golub=iMA(NULL,0, MA2, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Current value of the 2nd MA //-------------------------------------------------------------------------------------------- if (Peresechenie()==1 && New_Bar==1) Open_Buy(); // Bottom-up movement = open Buy if (Peresechenie()==2 && New_Bar==1) Open_Sell(); // Top-down movement = open Sell //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Peresechenie() { ret=0; // That's the heart of the matter!:) //============================================================================================ if ((Pred<=Golub && Tek> Golub) || (Pred< Golub && Tek>=Golub) ) ret=1; // Bottom-up intersection //-------------------------------------------------------------------------------------------- if ((Pred>=Golub && Tek< Golub) || (Pred> Golub && Tek<=Golub) ) ret=2; // Top-down intersection //============================================================================================ return(ret); // Return the intersection direction } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Open_Buy() { if (total==1) { OrderSelect(0, SELECT_BY_POS); // Select the order if (OrderType()==0)return; // If it is buy, don't open } OrderSend(Symbol(),0, Lots(), Ask, 0, Ask-SL, Ask+TP, "", 0, 0, Blue);// Open return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Open_Sell() { if (total==1) { OrderSelect(0, SELECT_BY_POS); // Select the order if (OrderType()==1)return; // If it is sell, don't open } OrderSend(Symbol(),1, Lots(), Bid, 0, Bid+SL, Bid-TP, "", 0, 0, Red);// Open return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж double Lots() { Lot = NormalizeDouble( AccountEquity()*Prots/100/1000, 1);// Calculate the amount of lots if (Lot<0.1)Lot = 0.1; // For testing on const. min. lots return(Lot); } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж /*
La prueba de este experto con lotes de precios constantes sólo ha obtenido un éxito limitado:
bajo las condiciones de trading del servidor demo con lotes de precios constantes de la compañía MetaQuotes Software Corp.
El programador está bastante desanimado. Tanto trabajo en vano... Con el tiempo limitado, el programador fue a buscar el "grial". Después de un par de meses, decide volver al experto Graal_3.mq4 (Grial 3). "Sí, había un error, pero dio buenos resultados. ¡Puede que sea cuestión de rutina! "Que el experto abra las órdenes como quiera si sólo mantiene los buenos resultados". Y empieza a prorbar de nuevo.
bajo las condiciones de trading del servidor demo con lotes de precios constantes de la compañía MetaQuotes Software Corp.
3.4. Adaptación de los resultados
El programador se da cuenta que es él quien está creando los problemas. Comprueba que no hay ninguna dificultad para adaptar los mejores parámetros de un experto poco efectivo en un segmento del historial. El mismo experto dará siempre diferentes resultados en diferentes periodos del historial.
Toda la cuestión se reduce a la pregunta de cómo encontrar las mejores entradas para el experto, si es posible, y qué fluctuaciones en la velocidad de precio de pequeño mercado no influiría en el funcionamiento y eficacia del experto. Generalmente, hay que centrarse en una estrategia que sea resistente a cualquier cambio en el mercado; y la optimización de los parámetros debe ayudar a algunos alcances a obtener los mejores resultados posibles.
La búsqueda de los ajustes ideales para el experto Graal_3.mq4 (Grial 3) no ha tenido ningún resultado. La prueba del experto con diferentes valores de las variables externas tampoco ha mostrado pérdidas ni resultados en bastantes ajustes diferentes para diferentes periodos del historial. Por este motivo, el programador no ha tenido éxito buscando la mejor configuración. Por eso ha llegado a la conclusión de que esta estrategia no tiene una configuración universal para todas las ocasiones.
El programador ha vuelto al experto Graal_31.mq4 (Grial 31) y quiere obtener desesperadamente los resultados deseados. Pero los mejores tienen este aspecto:
bajo las condiciones de trading del servidor demo con lotes de precios constantes de la compañía MetaQuotes Software Corp.
Eso que el programador ve arriba no se parece para nada a un "grial". El experto no se puede utilizar para trabajar en una cuenta real por la caída profunda en mitad del gráfico. Pero aún así, es un experto que funciona y que muestra un resultado positivo, aunque muy lejos de ser fantástico.
4. Conclusión
La decepción siempre es dolorosa, especialmente si las ilusiones son tan optimistas. Pero la vida pone a todos y a todo en su sitio tarde o temprano. Los problemas del mundo se llevaron el brillo del programador: Ha estropeado las relaciones con dos centros de operaciones, ha perdido dinero que ganó con su trabajo... Después de haber obtenido experiencias incalculables (para sí) en programación y trading en Forex, el programador casi llegó a la conclusión de "Sólo Mozart...", pero paró a tiempo y decidió que nunca sacaría conclusiones precipitadas.
En su lugar, el programador cogió una hoja de papel en blanco y formuló varias conclusiones basadas en las lecciones aprendidas:
-
Las inversiones progresivas son normales en el trading. Sin embargo, las órdenes no deben tener un precio demasiado alto.
-
Quedarse con la estrategia inicial
Si durante el desarrollo del experto, los cambios significantes en los parámetros ajustables provocan cambios significantes en los resultados, quiere decir que la estrategia iniciar se ha nivelado hacia arriba o hacia abajo. Es posible que la nueva estrategia sea más efectiva. En este caso, hay que mantenerla en suspensión durante un tiempo y llamarla más tarde, después de estudiar bien las razones de tal éxito inesperado. Pero se ha vuelto a la primera idea para investigar su utilidad en alcance máximo admitiendo los cambios en los parámetros dentro de los límites razonables. -
Vigilar de cerca los errores algorítmicos
La presencia de errores algoritmos es un fenómeno bastante natural. A veces es necesario tener mucha experiencia para descubrirlos. Al mismo tiempo, algunos de ellos pueden y deben encontrarse en los resultados finales del trabajo del experto. Normalmente, las órdenes abiertas o abiertas "sin marca" son una clara evidencia de un error algorítmico. -
Interpretar correctamente los resultados de la prueba del experto en el Tester de estrategia
El trabajo del experto en una cuenta real y su modelo en el Tester de estrategia son diferentes. La diferencia es que en el modelo no considera los rechazos como pedidos ejecutados y recotizaciones, que tienen lugar en el trading real. Esto no importa en los expertos en los que se tienen altas expectativas, pero sí en los que se tienen las espectavivas más bajas; los resultados del trabajo pueden ser bastante diferentes que los que se obtengan en la prueba. En varios casos, un experto con pocas expectativas y que muestra fantásticos beneficios en la prueba, puede resultar en pérdidas en el trading reral. -
Sin inversiones agresivas
Todas las estrategias de trading deben considerar la pérdida de operaciones. Si los precios de las órdenes son demasiado altos, incluso una pequeña serie de pérdidas puede causar un daño irreparable en la balanza total y, en algunos casos, incluso la pérdida total del depósito. Al permitir las reinversiones agresivas sin supervisar, se comete un error voluntario, una bancarrota garantizada. - No intentar ganar dinero en fluctuaciones aleatorias
Los picos no reflejan tasas de mercado normales y naturales. Si los traders ganan tantos picos, la fuente de beneficio es el dinero del vendedor. El vendedor descubrirá esto tarde o temprano, con todo lo que implica: cancelación de transacciones, deshabilitar expertos, bloqueo de la cuenta. - Comprobar los resultados en diferentes periodos del historial
Cada experto mostrará resultados diferentes en diferentes periodos de tiempo. Se puede encontrar la configuración ideal para cada intervalo, en la que los resultados serán los mejores. Hay que prestar mucha atención a la prueba, no hay que buscar los errores (adaptar los parámetros del experto), sino comprobar los resultados obtenidos en la mayor cantidad de intervalos del historial como sea posible.
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/1413
- 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