Librerías: TradeTransactions - página 2

 
Sergey Chalyshev:

Hasta ahora no se me ocurre ningún uso para esta biblioteca.

Definitivamente no es necesaria en forex, y no hay necesidad de ella en la bolsa de valores.

Si hablas de ejecución parcial, funciona a pleno rendimiento en Forex. En particular, es por eso que la asincronía es muy solicitada en Forex, y por lo tanto esta biblioteca puede ser útil.

¿Has probado esta librería en bolsa?

No la he probado en la bolsa, pero la bolsa y el Forex son técnicamente lo mismo para la biblioteca. Simplemente obtienes datos sobre todas las transacciones donde quieras y cuando quieras. Eso es todo. Así que aquí nada depende del tipo de mercado.

¿En qué casos cree que será útil?

La biblioteca será útil cuando lo sea la asincronía. Se trata de cualquier envío masivo (más de uno) de órdenes comerciales. Puede haber muchos escenarios:

  • Apertura/modificación/cierre de una cesta de personajes.
  • Rejillas.
  • Trabajar con los resultados de ejecuciones parciales.
  • Cierre de todas las posiciones y eliminación de todas las órdenes.
  • ...
 
fxsaber:

Hay que experimentar. Creo que la escritura/lectura simultánea de un recurso funciona igual que con las variables globales, porque la escritura en ambos casos es creación: ResourceCreate y GlobalVariableSet. La única diferencia entre un recurso y una global es que ni siquiera teóricamente se puede escribir nada en un recurso al mismo tiempo. Con las variables globales sí es posible.


De hecho, leer un recurso es obtener un dato de la memoria. Y si la lectura ha comenzado, escribir un recurso no debería afectarla, porque escribir es asignar otro trozo de memoria. Difícilmente pueden solaparse porque lo más probable es que el propio SO lo impida. Por eso, desde mi punto de vista, no debería haber conflictos de carga/guardado con los recursos. Pero, por supuesto, es mejor hacer esta pregunta a los desarrolladores.

¿No es un recurso con el mismo nombre el mismo recurso (y un trozo de memoria, respectivamente)?

Es fácil de comprobar - debes escribir algo largo con una marca especial al final y leerlo en paralelo. Si no se lee un mensaje entero, significa que puede haber un conflicto.

 
Andrey Khatimlianskii:

¿Acaso un recurso con el mismo nombre no es el mismo recurso (y trozo de memoria, respectivamente)?

Escribir es crear otro recurso.

Es fácil de comprobar - debes escribir algo largo con una marca especial al final y leerlo en paralelo. Si no se lee un mensaje entero, entonces puede haber un conflicto.

#property script_show_inputs

input bool Save = true; // Guardar/Cargar

#include <fxsaber\TradeTransactions\ResourceData.mqh> // https://www.mql5.com/es/code/22166

#define  MINLENGTH 100000
#define _CS(A) ((!::IsStopped()) && (A))

void OnStart()
{  
  const RESOURCEDATA<int> Resource("::Test");
  int Array[];            

  while (_CS(true))
    if (Save)
      for (int i = 0; _CS(i < MINLENGTH); i++)    
      {
        const int Size = ArrayResize(Array, i + MINLENGTH);
        
        Array[Size - 1] = Size;
        
        Resource = Array;
      }
    else
    {
      ArrayResize(Array, 0);      
      const int Size = Resource.Get(Array);
      
      if (!Size || (Array[Size - 1] != Size))
      {
        Print(Size);
        
        break;
      }
    }        
}


Este script de prueba muestra que no hay conflicto.

 
fxsaber:

La grabación es la creación de otro recurso.

Este script de verificación muestra que no hay conflictos.

Tenía algo así en mente:

#property script_show_inputs

input bool Save = true; // Guardar/Cargar

#include <fxsaber\TradeTransactions\ResourceData.mqh> // https://www.mql5.com/es/code/22166

#define  MINLENGTH 100000

void OnStart()
{  
        const RESOURCEDATA<int> Resource("::Test");
        int Array[];            
        string str = "";
        for ( int i = 0; i < MINLENGTH; i ++ ) str += (i%1000==0?"\n":"a");
        str += "\nCHECK";

        while ( !::IsStopped() )
    if (Save)
    {
        char arr[];
        StringToCharArray( (string)GetTickCount() + "\n" + str, arr );
        ArrayResize(Array, ArraySize(arr));
        ArrayCopy( Array, arr );
        Resource = Array;
    }
    else
    {
      ArrayResize(Array, 0);
      const int Size = Resource.Get(Array);
      char get[]; ArrayResize( get, Size );
      ArrayCopy( get, Array );
      string res = CharArrayToString( get );
      uint start = (uint)StringToInteger( StringSubstr( res, 0, StringFind( res, "\n" ) ) );
      Comment( "Delay = ", (GetTickCount() - start), " ms\n", res );
      if ( StringSubstr( res, StringLen( res )-5, 5 ) != "CHECK" ) { Print( res ); break; }
    }
}

Realmente no parece estar perdido.

 
Andrey Khatimlianskii:

Me refería a algo así:

Realmente no parece que se pierda.

Esta variante de la comprobación no tiene en cuenta los cambios en el tamaño del recurso y los datos al final del mismo.

 
fxsaber:

Esta variante de comprobación no tiene en cuenta los cambios en el tamaño del recurso y los datos al final del mismo.

¿Pueden permanecer en memoria datos escritos anteriormente? ¿Cómo borrarlos?

 
Andrey Khatimlianskii:

¿Pueden permanecer en la memoria datos grabados anteriormente?

En teoría, es posible. Por lo tanto, también deberías comprobarlo.

¿Cómo se borra?

Limpieza del recurso - borrado.

 
fxsaber:

Teóricamente puede estar permitido. Por eso deberías comprobarlo también.

No hay errores con dos cadenas de longitudes diferentes:

#property script_show_inputs

input bool Save = true; // Guardar/Cargar

#include <fxsaber\TradeTransactions\ResourceData.mqh> // https://www.mql5.com/es/code/22166

#define  MINLENGTH 100000

void OnStart()
{  
        const RESOURCEDATA<int> Resource("::Test");
        int Array[];            
        string str[2] = {""};
        for ( int i = 0; i < MINLENGTH  ; i ++ ) str[0] += (i%1000==0?"\n":"a");
        for ( int i = 0; i < MINLENGTH/2; i ++ ) str[1] += (i%1000==0?"\n":"b");
        str[0] += "\nCHECK";
        str[1] += "\nCHECK";

        while ( !::IsStopped() )
    if (Save)
    {
        char arr[];
        static bool var = false;
        var = !var;
        StringToCharArray( (string)GetTickCount() + "\n" + str[var], arr );
        ArrayResize(Array, ArraySize(arr));
        ArrayCopy( Array, arr );
        Resource = Array;
    }
    else
    {
      ArrayResize(Array, 0);
      const int Size = Resource.Get(Array);
      char get[]; ArrayResize( get, Size );
      ArrayCopy( get, Array );
      string res = CharArrayToString( get );
      uint start = (uint)StringToInteger( StringSubstr( res, 0, StringFind( res, "\n" ) ) );
      Comment( "Delay = ", (GetTickCount() - start), " ms\n", res );
      if ( StringSubstr( res, StringLen( res )-5, 5 ) != "CHECK" ) { Print( res ); break; }
    }
}
 
Andrey Khatimlianskii:

Tampoco se producen errores con dos cadenas de longitudes diferentes:

Así es. Por eso dije que el código original lo comprobaba.

 
¿Has considerado alguna vez usar convenciones de estilo/nombre estándar de C++? Personalmente creo que tu código es brillante, pero la razón por la que no uso tus librerías (o tengo que refactorizarlas) es por el estilo utilizado. Es muy difícil analizar mentalmente parte de tu código simplemente porque no sigues ninguna convención estándar. Esto es especialmente frustrante para los que venimos de otros lenguajes. Por ejemplo, esta librería nombra todo en CamelCase excepto la declaración de clase (ALLCAPS), lo que va en contra de cualquier convención de nomenclatura en casi todos los lenguajes de programación. Mirar el código es frustrante porque en muchos otros lenguajes
CamelCase.thing

está accediendo a un atributo de clase en lugar de a un atributo de instancia.

Lo mismo ocurre con las declaraciones de clase, y te gusta usar macros tanto que nunca sé si sus declaraciones de clase son macros o enums. Típicamente, por MQL convenciones estándar, sólo se debe utilizar ALLCAPS para enums, macros y constantes -- y CamelCase se utiliza para las declaraciones de clase. Además, las variables se definen utilizando snake_case, por convención MQL.


No es mi intención ofenderte con mi crítica constructiva, y sé que trabajas muy duro para hacer estas bibliotecas libres para todos, lo cual es impresionante y necesitamos más desarrolladores como tú. Sé que no hablo sólo por mí, y si sólo hicieras unos pequeños ajustes en el estilo que se aplica, entonces más desarrolladores utilizarían tus bibliotecas. Eso es lo que queréis, ¿no?