Problemas de cierre, por favor, ayuda - página 5

 

Hola Ais
Tu respuesta es muy satisfactoria. Escuchar que me ayudarías a entender la complejidad y luego a reducirla, era más de lo que podía pedir. Me humillo ante tu generosidad. Gracias.
Tengo una pregunta sobre la estructura de los comentarios en sus programas. No es que quiera salirme del tren de pensamiento que ha progresado, pero una cuestión de cómo se ve el formato no me es familiar.

Ejemplo:

// < Estructura 17 elementos en 4 dominios > //< >
// < 1. Datos 8 elementos en 2 dominios /> //< >
// < 2. Código 9 elementos en 2 dominios /> //< >
// <Estructura 17 elementos en 4 dominios > //< >
// //< >
// < 1. Datos 8 = 5 i 3 d - s > //< >
// < 1.1. Entrada 7 = 4 i 3 d - s /> //< >
// < 1.2. Buffer 1 = 1 i - d - s /> //< >
// </1. Datos 8 = 5 i 3 d - s > //< >
// //< >

Los comentarios están estructurados de forma tan precisa. Con títulos y subcomentarios, sería la mejor manera de describir lo que leo. Como si los comentarios fueran desarrollados y formados o estructurados por una máquina de código? Es impresionante. No es que entienda todo lo que se comenta. Tu capacidad de organización me parece refrescante.

Gracias de nuevo. Voy a estudiar el programa y tendré más preguntas en un futuro muy cercano.
Saludos

 

Hola Huckleberry

Me alegra saber de ti.


1. La estructura

La estructura está desarrollada y formateada por mí mismo.

//                                                                //<          >
// < Structure             16 elements  in      4 domains       > //<          >
// < 1. Data                7 elements  in      2 domains      /> //<          >
// < 2. Code                9 elements  in      2 domains      /> //<          >
// </Structure             16 elements  in      4 domains       > //<          >
//                                                                //<          >
     

La primera intención es separar estrictamente los datos globales y el código.
El programa de ordenador para mí es un modelo del mundo real.
Los datos globales son las cosas de este mundo.
El código es el conjunto de acciones.
Al separarlos estoy subrayando que entiendo la diferencia entre ellos.
Contar el número de elementos me ayuda a comprobar y controlar todo dentro del programa.


2. El formato

El formato es un simple HTML.
La siguiente etiqueta abre la parte del programa:

// <                                                            > //<          >
      


La etiqueta siguiente cierra la parte del programa:

// </                                                           > //<          >
      


La siguiente etiqueta se utiliza para las partes del programa en una sola línea:

// <                                                           /> //<          >
      

La parte final de la etiqueta ahora se utiliza para el conteo de páginas.
En el futuro se podrá ampliar el uso de esta parte de las etiquetas.

                                                                  //<          >
      

La estructura de las páginas ayuda a navegar fácilmente por el programa.
Usando <Page Up> y <Page Down> siempre veo los mismos tipos de etiquetas en los mismos lugares.



3. Los elementos

El elemento de datos es una única variable global.
También veo el array como elemento único.
Las variables locales son sólo entidades temporales de los elementos de código.

El elemento de código es una sola función.
También puedo usar la palabra "método".
Yo uso la palabra "interfaz" para un conjunto de funciones.

Para reducir la complejidad, divido los datos y el código en dominios lógicos.
El número de dominios depende de la estructura del programa.
Dominios habituales para los datos: "input", "settings", "control", "buffer" ...
Dominios habituales para el código: "special" para el conjunto de funciones especiales, "interface" para el conjunto de otras funciones.
En el caso de programas grandes puedo crear "objetos" con diferentes "interfaces".

Para controlar la integridad de los elementos de datos y elementos de código se utiliza el conteo.


//                                                                //<          >
// < 1. Data                7 =       4 i       3 d       - s   > //<          >
// < 1.1. Input             7 =       4 i       3 d       - s  /> //<          >
// < 1.2. Buffer            - =       - i       - d       - s  /> //<          >
// </1. Data                7 =       4 i       3 d       - s   > //<          >
//                                                                //<          >
// < 2. Code                9 /       - i      82 l       4 o   > //<          >
// < 2.1. Interface         6 /       - i      71 l       4 o  /> //<          >
// < 2.2. Special           3 /       - i      11 l       - o  /> //<          >
// </2. Code                9 /       - i      82 l       4 o   > //<          >
//                                                                //<          >
     

Las etiquetas de apertura y cierre contienen las mismas sumas.
Normalmente cuento la suma en la etiqueta de apertura.
Entonces simplemente copio e inserto la etiqueta de apertura en lugar de la etiqueta de cierre y luego añado la barra de cierre "/".

Para controlar la integridad de los datos se utiliza la siguiente notación.
El número de elementos de datos de "entero" se anota como "i".
El número de elementos de datos de "doble" se anota como "d".
El número de elementos de datos de "cadena" se anota como "s".
La columna de la izquierda contiene la suma de la línea "i" + "d" + "s".

Para controlar la integridad del código se utiliza la siguiente notación.
El número de entradas de la función, es decir, el número de argumentos de la función, se anota como "i".
El número de líneas de código abiertas se anota como "l".
El número de salidas de la función se anota como "o".
Siempre es "1" para una sola función que devuelve cualquier valor y "-" en todos los demás casos.
La columna de la izquierda contiene el número de funciones en el dominio.


4. Los dominios

Estas son las cabeceras de los dominios.

////////////////////////////////////////////////////////////////////<         2>
// < 1.1. Data : Input >                                          //<          >
//                                                                //<          >
// < 1.1. Input             7 =       4 i       3 d       - s   > //<          >
// <      1. Strategy       4 =       2 i       2 d       - s  /> //<          >
// <      2. Trading        3 =       2 i       1 d       - s  /> //<          >
// </1.1. Input             7 =       4 i       3 d       - s   > //<          >
//                                                                //<          >
     
////////////////////////////////////////////////////////////////////<         3>
// < 1.2. Data : Buffer >                                         //<          >
//                                                                //<          >
// < 1.2. Buffer            - =       - i       - d       - s   > //<          >
// </1.2. Buffer            - =       - i       - d       - s   > //<          >
//                                                                //<          >
     
////////////////////////////////////////////////////////////////////<         4>
// < 2.1. Code : Interface >                                      //<          >
//                                                                //<          >
// < 2.1. Interface         6 /       - i      71 l       4 o   > //<          >
// <      1. iNewBar                  - i       4 l       1 o  /> //<          >
// <      2. iSignalOpen              - i      15 l       1 o  /> //<          >
// <      3. iSignalClose             - i      15 l       1 o  /> //<          >
// <      4. iGetTicket               - i       7 l       1 o  /> //<          >
// <      5. iTryOpen                 - i      15 l       - o  /> //<          >
// <      6. iTryClose                - i      15 l       - o  /> //<          >
// </2.1. Interface         6 /       - i      71 l       4 o   > //<          >
//                                                                //<          >
     
////////////////////////////////////////////////////////////////////<        11>
// < 2.2. Code : Special >                                        //<          >
//                                                                //<          >
// < 2.2. Special           3 /       - i      11 l       - o   > //<          >
// <      1. init                     - i       1 l       - o  /> //<          >
// <      2. deinit                   - i       1 l       - o  /> //<          >
// <      3. start                    - i       9 l       - o  /> //<          >
// </2.2. Special           3 /       - i      11 l       - o   > //<          >
//                                                                //<          >
     


Las reglas y anotaciones para el recuento son las mismas que para la cabecera del programa.
Simplemente copio las etiquetas de apertura de las cabeceras de los dominios en la cabecera del programa.

Cada página del dominio tiene etiquetas de apertura y cierre.
Por ejemplo:

////////////////////////////////////////////////////////////////////<        12>
// < 2.2.1. Code : Special : Init >                               //<          >
..
// </2.2.1. Code : Special : Init >                               //<          >
     

Los números iniciales se utilizan para el recuento y la navegación de las partes de la estructura.
Luego sigue la notación para la parte del programa "Datos" o "Código".
Luego sigue el nombre del dominio.
Luego sigue el nombre del elemento del dominio.


Espero que esto pueda ayudar.

Adiós por ahora y esperando su respuesta

 

Hola Ais
Tu sentido de la organización es ......cómo decirlo ..... práctico y sensato.
La integración del HTML facilita la navegación, aunque en este momento me supera.
Muy bueno.
En este momento, estoy diseccionando el programa que me enviaste, un enunciado a la vez. Los conceptos
que tienes sobre las variables, son comprensibles. Gracias de nuevo.
Estoy seguro que te responderé con preguntas.
Adiós

 

Hola Ais,,,<esto ha sido editado>
El programa aún no ha sido absorbido. Siento que te esté llevando tanto tiempo. Hay un área que debo haber pasado por alto,
porque tengo un error que enfrentar.
Debo ir por ahora, pero volveré mañana.
Adiós por ahora

 

Hola Huckleberry
Algunas características fueron añadidas por ejemplo y pueden ser fácilmente cambiadas o eliminadas.
La mejora del programa es un proceso constante.
Adiós por ahora
:)

 
Ais wrote >>

Hola Huckleberry
Algunas características fueron añadidas por ejemplo y pueden ser fácilmente cambiadas o eliminadas.
La mejora del programa es un proceso permanente.
Adiós por ahora
:)


Hola Ais
Gracias por todo lo que has hecho.
Anoche finalmente encontré mi error mientras copiaba tu programa.
En este momento estoy tratando de entender para qué son algunas de las variables y cómo funcionarían.
El iSignalClose es donde estoy insertando parte de mi otro programa para establecer el OrderClosePrice. Con
su sugerencia:

dDelta = OrderOpenPrice () - OrderClosePrice

el programa tiene más flexibilidad.
Vuelvo con más preguntas. Y comentarios.
Saludos
 

Hola Ais
Las preguntas se han producido. Su programa indica en ..... iTryOpen ()

else if     ( iCommand       == OP_BUY )
   {          
string        sType           = "Buy"   ;   
int           iColor          =  Blue   ;               }
else         
   {          sType           = "Sell"  ;    
              iColor          =  Red    ;           

Por mi curiosidad, ¿debería haber

else if     ( iCommand       == OP_BUY  )
   {          
string        sType           = "Buy"   ;   
int           iColor          =  Blue   ;               }
else if     ( iCommand       == OP_SELL )   // Was this ommitted     
   {          sType           = "Sell"  ;    
              iColor          =  Red    ;               }
Aquí hay otra pregunta para entender mejor
// < 2.1.1. Code : Interface : iNewBar >                          //<          >
int       iNewBar ()         //       - i       4 l       1 o     //<          >
{                                                                 //<          >
static    int       iTime_0 = 0                                 ; //<          >
//                                                                //<          >
if      ( iTime_0 < iTime   ( 0 , 0 , 0 ) )                       //<          >
        { iTime_0 = iTime   ( 0 , 0 , 0 ) ;  return ( TRUE  ) ; } //<          >
else    {                                    return ( EMPTY ) ; } //<          >
//                                                  
Si iNewBar es TRUE, el control se pasa a iSignalOpen. Si iNewBar es TRUE (¿igual a la barra actual?), O iFirstRun ==1, entonces iFirstBar = 0. Esto es confuso sólo porque no entiendo la definición de iNewBar () y/o la definición de iFirstRun. Puedo ver donde iFirstRun es decarado e inicializado, pero que significa.
Siento agobiaros con preguntas tan sencillas. No puedo calcular ni ver cómo funcionan los dos dentro de la función. Cuando tengas tiempo, podrías aclarar esto por favor.
Gracias de nuevo por tu esfuerzo : )
Saludos
 

Hola Huckleberry

Ambas preguntas son importantes!

Respuesta 1.

Ambas condiciones son verdaderas, pero si:
1.1. sabemos que

int       iCommand          = iSignalOpen ()                    ; //<          >
     

1.2. sabemos que "iSignalOpen ()" puede devolver sólo 3 valores posibles: "EMPTY", "OP_BUY" y "OP_SELL";
1.3. el primer valor ya está comprobado

if      ( iCommand         == EMPTY  )                return    ; //<          >
     

1.4. el segundo valor también se comprueba

if      ( iCommand         == OP_BUY )                            //<          >
     

entonces es posible omitir la última comprobación "si" para acelerar ligeramente los cálculos.

else if     ( iCommand       == OP_SELL )                    //<          >
     


Respuesta 2.

2.1. Reconocemos que la barra número 0 se cambia comparando la hora de apertura de la barra número 0 con la última hora de apertura almacenada de la barra número 0.
"iTime ( 0, 0, 0 )" devuelve la hora de apertura de la barra actual incompleta.
El índice de la barra actual es siempre 0, es el tercer valor en "iTime ( 0, 0, 0 )".
Declarar la variable "int iTime_0" como "estática" significa que el valor de esta variable se guarda entre las invocaciones de la función.
Cada vez que se cambia la hora de apertura, nosotros:
2.1.1. asignamos "iTime_0 = iTime ( 0, 0, 0 ) ;" para guardar la hora de apertura de la barra actual;
2.1.2. devolvemos "TRUE" que significa que la barra actual es una nueva barra, la última barra número 0 se convirtió en la barra número 1.


////////////////////////////////////////////////////////////////////<         5>
// < 2.1.1. Code : Interface : iNewBar >                          //<          >
int       iNewBar ()         //       - i       4 l       1 o     //<          >
{                                                                 //<          >
static    int       iTime_0 = 0                                 ; //<          >
//                                                                //<          >
if      ( iTime_0 < iTime   ( 0 , 0 , 0 ) )                       //<          >
        { iTime_0 = iTime   ( 0 , 0 , 0 ) ;  return ( TRUE  ) ; } //<          >
else    {                                    return ( EMPTY ) ; } //<          >
}                                                                 //<          >
// </2.1.1. Code : Interface : iNewBar >                          //<          >
     

2.2. Nuestra barra inicial para los cálculos de "dHigh" y "dLow" en "iSignalOpen ()", y "dATR" en "iSignalClose ()", es "iBaseBar=1".
Mientras el número de barra 1 sea el mismo, estos valores son iguales.
Es una razón para calcular estos valores sólo en barras nuevas.
Esto acelera el programa.
La variable "static int iFirstRun" es un simple disparador.
El valor inicial "1" obliga a calcular "dHigh", "dLow" y "dATR" en la primera ejecución del programa, independientemente de cualquier condición.
Esto mejora la fiabilidad del programa.

<agregado posteriormente>
¡Exactamente, en la primera ejecución del programa "iNewBar ()" en "iSignalOpen ()" devuelve "TRUE", y en "iSignalClose" devuelve "EMPTY"!
Esto se debe a que en la primera invocación de "iNewBar ()", que está dentro de la primera ejecución de "iSignalOpen ()", el valor de "iTime_0 = 0"y en la segunda invocación de "iNewBar ()", es decir, dentro de la primera ejecución de "iSignalClose ()", "iTime_0 = iTime ( 0, 0, 0 )".
Como resultado sin el primer control de ejecución puede ser "dATR = 0".
Tal es la primera ejecución.
</agregado después>

Inmediatamente después asignamos "iFirstRun = 0" y la siguiente condición será verdadera sólo en las nuevas barras:

if    ( ( iNewBar () == TRUE )   ||   ( iFirstRun  == 1 ) )       //<          >
     

¡Pero!
¡Restos de código de "iSignalOpen ()" y "iSignalClose ()" ejecutados en cada tick!
Sólo se saltan los cálculos de los valores no modificados.

////////////////////////////////////////////////////////////////////<         6>
// < 2.1.2. Code : Interface : iSignalOpen >                      //<          >
int       iSignalOpen ()     //       - i      15 l       1 o     //<          >
{                                                                 //<          >
static    int                           iFirstRun   = 1         ; //<          >
if    ( ( iNewBar () == TRUE )   ||   ( iFirstRun  == 1 ) )       //<          >
        {                               iFirstRun   = 0         ; //<          >
          int iIndexH = iHighest      ( 0 , 0    , MODE_HIGH  ,   //<          >
                                        iBaseLag , iBaseBar   ) ; //<          >
          int iIndexL = iLowest       ( 0 , 0    , MODE_LOW   ,   //<          >
                                        iBaseLag , iBaseBar   ) ; //<          >
          static double dHigh ; dHigh = High     [ iIndexH    ] ; //<          >
          static double dLow  ; dLow  = Low      [ iIndexL    ] ; //<          >
        } // if                                                   //<          >
//                                                                //<          >
double    dAsk    = MarketInfo        ( Symbol () , MODE_ASK  ) ; //<          >
if      ( dAsk    > dHigh )             return    ( OP_BUY    ) ; //<          >
//                                                                //<          >
double    dBid    = MarketInfo        ( Symbol () , MODE_BID  ) ; //<          >
if      ( dBid    < dLow  )             return    ( OP_SELL   ) ; //<          >
//                                                                //<          >
                                        return    ( EMPTY     ) ; //<          >
}                                                                 //<          >
// </2.1.2. Code : Interface : iSignalOpen >                      //<          >
     


Espero que esto pueda ayudar.
¡Salud!
:)

P.S. Algunas observaciones añadidas posteriormente.
Y, viendo estas observaciones, es obvio que "iNewBar ()" tiene que ser corregido.
Esto se debe a que esta función se invoca dos veces para comprobar un solo evento.
Ahora, para el mismo evento en la primera invocación "iNewBar ()" devuelve un valor correcto, y en la segunda devuelve un valor incorrecto.
Será corregido.



 

Hola Ais
Gracias por la aclaración. Seguiré con más lecturas. Todavía no tengo un manejo completo del código.
Pero mencionaste que había algo que había que corregir en cuanto a la iNewBar? No estoy seguro de que el iNewBar es el culpable del problema lo que el backtest reveló. Posibles dos problemas??
Esto es lo que vi cuando abrí el gráfico después de un backtest. Sabemos que hay una entrada de compra cuando el Ask está por encima del máximo de las últimas veinte barras. La venta es justo lo contrario. Sin embargo, las entradas no son consistentes. ¿Es esta la zona que viste?
Encontré una cosa más. El Hard Stop se calcula Atr*2. Esto es correcto, sin embargo, no veo donde se calcula esto. Pero el verdadero problema es que el TakeProfit tiene el mismo cálculo Atr*2. Si supiera dónde se calcula el Hard Stop, posiblemente podría corregir el TakeProfit. El TakeProfit en este caso debería ser sólo Atr*1.
Cuídate y vuelvo mañana.
Saludos

 

Hola Huckleberry

La condición TakeProfit fue inventada por mí mismo para fines de prueba.
Ahora se cambia.
En lugar de "Atr*2" y "Atr*1" utilizo "dATR * dFactorTP" y "dATR * dFactorSL".
Los valores iniciales "dFactorTP = 1.0" y "dFactorSL = 2.0" están en la página 2 "Datos : Input".
Esta solución permite optimizar fácilmente estos valores.

He cambiado las funciones "iSignalOpen ()" y "iSignalClose ()".
La comprobación de la nueva barra ahora está implementada en estas funciones.
Las condiciones para "Buy" y "Sell" en "iSignalOpen ()" parecen probablemente correctas.

El programa completo está en el archivo adjunto en la siguiente página.

Saludos