Bibliotecas: TradeTransactions - página 2

 
Sergey Chalyshev:

Até o momento, não consigo pensar em um uso para essa biblioteca.

Definitivamente, ela não é necessária no mercado de câmbio e não há necessidade dela na bolsa de valores.

Se você estiver falando de execução parcial, ela funciona a todo vapor no Forex. Em particular, é por isso que a assincronia é muito procurada no Forex e, portanto, essa biblioteca pode ser útil.

Você testou essa biblioteca na bolsa de valores?

Não a testei na bolsa de valores, mas a bolsa de valores e o Forex são tecnicamente iguais para a biblioteca. Você simplesmente obtém dados sobre todas as transações em qualquer lugar que desejar, quando desejar. Isso é tudo o que existe. Portanto, nada depende do tipo de mercado aqui.

Em que casos você acha que ela será útil?

A biblioteca será útil quando a assincronia for útil. Trata-se de qualquer envio em massa (mais de um) de ordens de negociação. Pode haver muitos cenários:

  • Abertura/modificação/fechamento de uma cesta de personagens.
  • Grades.
  • Trabalhar com os resultados de execuções parciais.
  • Fechamento de todas as posições e exclusão de todas as ordens.
  • ...
 
fxsaber:

É necessário fazer experimentos. Acho que a gravação/leitura simultânea de um recurso funciona da mesma forma que com as variáveis globais, porque a gravação em ambos os casos é criação: ResourceCreate e GlobalVariableSet. A única diferença entre um recurso e um global é que, teoricamente, você não pode escrever nada em um recurso ao mesmo tempo. Com as variáveis globais, isso é possível.


De fato, ler um recurso é obter um dado da memória. E se a leitura foi iniciada, a gravação de um recurso não deve afetá-la, porque a gravação está alocando outra parte da memória. Eles dificilmente podem se sobrepor porque o próprio sistema operacional provavelmente os impedirá de fazer isso. É por isso que, do meu ponto de vista, não deve haver conflitos de carregamento/salvamento com os recursos. Mas é claro que é melhor fazer essa pergunta aos desenvolvedores.

Um recurso com o mesmo nome não é o mesmo recurso (e um pedaço de memória, respectivamente)?

É fácil verificar: você deve escrever algo longo com uma marca especial no final e lê-lo em paralelo. Se nem toda a mensagem for lida, isso significa que pode haver um conflito.

 
Andrey Khatimlianskii:

Um recurso com o mesmo nome não é o mesmo recurso (e um pedaço de memória, respectivamente)?

Escrever é criar outro recurso.

É fácil verificar: você deve escrever algo longo com uma marca especial no final e lê-lo em paralelo. Se nem toda a mensagem for lida, pode haver um conflito.

#property script_show_inputs

input bool Save = true; // Salvar/carregar

#include <fxsaber\TradeTransactions\ResourceData.mqh> // https://www.mql5.com/pt/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;
      }
    }        
}


Esse script de teste mostra que não há conflito.

 
fxsaber:

A gravação é a criação de outro recurso.

Esse script de verificação mostra que não há conflitos.

Eu tinha algo parecido com isso em mente:

#property script_show_inputs

input bool Save = true; // Salvar/carregar

#include <fxsaber\TradeTransactions\ResourceData.mqh> // https://www.mql5.com/pt/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 não parece estar perdido.

 
Andrey Khatimlianskii:

Eu quis dizer algo assim:

Ele realmente não parece estar perdido.

Essa variante da verificação não leva em conta as alterações no tamanho do recurso e os dados no final dele.

 
fxsaber:

Essa variante de verificação não leva em conta as alterações no tamanho do recurso e dos dados no final.

Os dados gravados anteriormente podem permanecer na memória? Como limpá-los?

 
Andrey Khatimlianskii:

Os dados registrados anteriormente podem permanecer na memória?

Teoricamente, isso é possível. Portanto, você deve verificar isso também.

Como limpar isso?

Limpando o recurso - exclusão.

 
fxsaber:

Teoricamente, isso pode ser permitido. É por isso que você deve verificar isso também.

Não há erros com duas cadeias de caracteres de comprimentos diferentes:

#property script_show_inputs

input bool Save = true; // Salvar/carregar

#include <fxsaber\TradeTransactions\ResourceData.mqh> // https://www.mql5.com/pt/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:

Também não há erros com duas cadeias de caracteres de comprimentos diferentes:

É isso mesmo. É por isso que eu disse que o código original verificou isso.

 
Você já pensou em usar as convenções de estilo/nomeação padrão do C++? Pessoalmente, acho que seu código é brilhante, mas o motivo pelo qual não uso suas bibliotecas (ou tenho que refatorá-las) é o estilo que está sendo usado. É muito difícil analisar mentalmente alguns de seus códigos simplesmente porque você não está seguindo nenhuma convenção padrão. Isso é particularmente frustrante para aqueles que vêm de outras linguagens. Por exemplo, essa biblioteca nomeia tudo em CamelCase, exceto a declaração de classe (ALLCAPS), o que vai contra todas as convenções de nomeação em quase todas as linguagens de programação. Olhar para o código é frustrante porque em muitas outras linguagens
CamelCase.thing

está acessando um atributo de toda a classe em vez de um atributo de instância.

O mesmo acontece com as declarações de classe, e você gosta tanto de usar macros que nunca sei se suas declarações de classe são macros ou enums. Normalmente, de acordo com as convenções padrão do MQL, você só deve usar ALLCAPS para enums, macros e constantes, e CamelCase é usado para declarações de classe. Além disso, as variáveis são definidas usando snake_case, por convenção MQL.


Não tenho a intenção de ofendê-lo com minha crítica construtiva, e sei que você se esforça muito para tornar essas bibliotecas gratuitas para todos, o que é fantástico e precisamos de mais desenvolvedores como você. Sei que não falo apenas por mim, e se você fizesse apenas pequenos ajustes no estilo aplicado, mais desenvolvedores usariam suas bibliotecas. É isso que você quer, não é?