Erros, bugs, perguntas - página 2963

 
fxsaber:

O Indicador1 e o Indicador2 devem então ser sincronizados de alguma forma para que ambos os números possam ser escritos na mesma linha comum.

Esta é uma solução muito complexa.

Porque precisariam eles de ser sincronizados? user32.dll fará isso por eles.
O principal é numerá-los correctamente, para que cada número tenha um número único e este número seja um índice da matriz de dados.
Isto pode, como último recurso, ser feito manualmente. Ou pode fazê-lo automaticamente. A propósito, publiquei recentemente algo semelhante em KB(Indicator Cases).
O que há para não gostar nos recursos? Penso que é óptimo dentro dos limites de um terminal. A variante que sugiro, utilizando o user32.dll (implementei esta variante há cerca de 10 anos atrás, quando era jovem e estava a fazer arbitragem), o tempo de acesso e a análise de dados são de cerca de 50 microssegundos (penso que pode ser acelerada em 1,5-2 vezes). É mais lento com os recursos?

 
Nikolai Semko:

Porque precisariam eles de sincronizar? user32.dll fará isso por eles.

Tente escrevê-lo. Talvez não compreenda totalmente a tarefa.

Porque não gosta de recursos? Penso que é óptimo dentro dos limites de um único terminal. A variante que sugeri utilizando a user32.dll (implementei esta variante há cerca de 10 anos, quando estava a fazer arbitragem quando era jovem) tem um tempo de acesso e análise de cerca de 50 microssegundos (penso que pode ser acelerada 1,5-2 vezes). É mais lento com os recursos?

São necessários 100 microssegundos para ler numa máquina doméstica em condições ideais. Um consultor especializado num único tick pode causar uma centena de leituras. É lento.

Em condições ideais, a GlobalVariableGet será executada em 10 microssegundos. Mas isso não é um indicador, pois em condições de combate novas para mim é um travão horrível.

 
fxsaber:

Isto é HistoryTicks - apanhar todas as carraças para EAs. Portanto, EventChartCustom não é adequado, tem a sua própria fila de espera. O mesmo se passa com o tampão.

Tenho-o a trabalhar no EventChartCustom. 99,8% das carraças são recebidas dentro de 0,15 ms.

Fórum sobre comércio, sistemas de comércio automatizados e testes estratégicos

EventChartCustom => indicador é demasiado lento

Andrey Khatimlianskii, 2019.12.12 09:27

Aqui estão as estatísticas para 9 horas de trabalho com 5 símbolos:

Windows 8.1 (build 9600) x64, IE 11, UAC, Intel Core i5-3570  @ 3.40 GHz, Memory: 6979 / 16346 Mb, Disk: 341 / 499 Gb, GMT+2
[USDCHF]: 22784 of 22833 (99.8 %) ticks were processed (0.14 ms delay in average), 49 (0.2 %) ticks were skipped (103.4 ms delay in average)
[EURUSD]: 22944 of 22974 (99.9 %) ticks were processed (0.16 ms delay in average), 30 (0.1 %) ticks were skipped (115.6 ms delay in average)
[USDCAD]: 15331 of 15347 (99.9 %) ticks were processed (0.13 ms delay in average), 16 (0.1 %) ticks were skipped (104.6 ms delay in average)
[EURCHF]: 22516 of 22571 (99.8 %) ticks were processed (0.13 ms delay in average), 55 (0.2 %) ticks were skipped (127.8 ms delay in average)
[EURAUD]: 66842 of 66924 (99.9 %) ticks were processed (0.13 ms delay in average), 82 (0.1 %) ticks were skipped (117.8 ms delay in average)
[GBPUSD]: 41393 of 41393 (100.0 %) ticks were processed (0.00 ms delay in average)
Total trade requests time: 4.280 sec

O consultor especializado estava no GBPUSD, pelo que a nativa OnTick trabalhou para ele.

Não houve erros de "indicador é demasiado lento".


Em contraste, a percentagem de carraças falhadas e a latência média é muito mais elevada no VPS da MQ (mais tarde publicarei as estatísticas).
E há muitos erros de "indicador é demasiado lento".

Não compreendo a natureza do transbordo de filas, porque o Conselheiro Especialista processa imediatamente os eventos acumulados (ele apenas regressa).
Alguém mais o processa?


 
Andrey Khatimlianskii:

Tenho-o a trabalhar noEventChartCustom. 99,8% das carraças são recebidas dentro de 0,15 ms.

Envio carraças do indicador através disto: sparam contém MqlTick, lparam - número de carraça.

O Conselheiro Especialista em OnChartEvent captura estes carrapatos. E precisa de compreender se o tick actual é o mais real ou não? Isto é, há uma fila de carraças ou está vazia?

Para isso, lê o número (a tarefa é ler este número) do último tick enviado pelo indicador. Se a carraça tiver o mesmo número - a fila está vazia, e é possível começar a trabalhar com carraças.


E durante o funcionamento da OnTick, após o OrderSend é necessário verificar se o indicador enviou mais carraças. Para isso, precisamos novamente de ler o número do indicador. E pode haver mais de uma centena de tais verificações durante um OnTick. É por isso que precisamos de ler rapidamente.

 

Dentro de 1 terminal, o winapi mais rápido será a alocação de memória (global dentro de um processo) e funções interbloqueadas como https://docs.microsoft.com/ru-ru/windows/win32/api/winnt/nf-winnt-interlockedexchange.

Estes são não-bloqueantes, atómicos e essencialmente executados em algumas instruçõessm.

InterlockedExchange function (winnt.h) - Win32 apps
InterlockedExchange function (winnt.h) - Win32 apps
  • 2018.12.05
  • lastnameholiu
  • docs.microsoft.com
Sets a 32-bit variable to the specified value as an atomic operation.
 
traveller00:

Dentro de 1 terminal, o winapi mais rápido será a alocação de memória (global dentro de um processo) e funções interbloqueadas como https://docs.microsoft.com/ru-ru/windows/win32/api/winnt/nf-winnt-interlockedexchange.

Estes são não-bloqueantes, atómicos e essencialmente executados em algumas instruçõessm.

Não sem um exemplo.

 
fxsaber:

Para tal, lê o número (a tarefa é ler este número) do último tick enviado pelo indicador. Se o carrapato recebido tiver o mesmo número - a fila está vazia, e pode começar a trabalhar com um pacote de carrapatos.

E durante o funcionamento da OnTick, após OrderSend é necessário verificar se o indicador enviou mais carraças. Para isso, precisamos novamente de ler o número do indicador. E pode haver mais de uma centena de tais verificações durante um OnTick. Por conseguinte, precisamos de o ler rapidamente.

Inicialização.

1. Na primeira linha (muito provavelmente, a linha de escrita), atribuir memória de qualquer forma para a variável do tamanho requerido.

2. Nos fios necessários (fios de leitura), enviar o endereço desta memória.

Trabalho básico.

3. O fio de escrita inicia InterlockedExchange ou InterlockedExchange64 dependendo do tamanho da variável para escrever para ele.

4. A leitura do fio puxa, por exemplo, InterlockedCompareExchange para ler.

Conclusão.

5. Libertar memória alocada, de preferência no mesmo fio que a alocou.


Se necessário, pode ser repetido para a criação de vários balcões. Do lado negativo, necessitará da ligação WinAPI. Das características do endereço de memória atribuído deve ser alinhado, mas por defeito normalmente é.


O trabalho será dentro de 1 processo, a memória é partilhada para os fios de 1 processo. Se necessário, existem outras funções interligadas como InterlockedDecrement, InterlockedAdd, etc.

As funções são não-bloqueio, não esperar por nada, autómatos, são executadas em algumas instruçõessm.


P.S. Tanto quanto me lembro, as operações regulares de leitura e escrita via móvel em assembler são de qualquer forma atómicas. E se o compilador não fizer confusão (não deveria em teoria), podemos tentar ler e escrever para a variável na memória atribuída e será atómica.

Se se adequar à tarefa, é improvável que seja mais rápido dentro de 1 processo. Para interprocessamento o mais rápido será semelhante, mas com memória partilhada, neste caso não se pode passar sem WinAPI.

 
fxsaber:

Este esquema não parece funcionar. Mostrar um exemplo elementar, por favor.

Por que não ser exequível? Tal como eu vejo as coisas. O princípio "getter setter".
Obter o valor de uma variável oculta através de uma função.
Se passar a estrutura MqlTick, defina a sua estrutura com os campos definidos como MqlTick, e adicione o seu campo contador à estrutura.
E devolver esta estrutura da função de exportação.
Um exemplo elementar para o indicador. Não prestar atenção ao exemplo no guião.

struct myMqlTick 
{ 
   datetime     time;          // Время последнего обновления цен 
   double       bid;           // Текущая цена Bid 
   double       ask;           // Текущая цена Ask 
   double       last;          // Текущая цена последней сделки (Last) 
   ulong        volume;        // Объем для текущей цены Last 
   ulong        count;  //Свой счётчик
   
}myStruct;

//--------------------------------------------------
myMqlTick GetTickStruct() export
{
   
   return(myStruct);
}

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   myStruct.time   = 0.0;
   myStruct.bid    = 0.0;
   myStruct.ask    = 0.0;
   myStruct.last   = 0.0;
   myStruct.volume = 0;
   myStruct.count  = 1;  //свой счётчик  
  
}
//+------------------------------------------------------------------+

No Expert Advisor, ligue para GetTickStruct e obtenha toda a estrutura com o seu contador.

Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура для получения текущих цен
Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура для получения текущих цен
  • www.mql5.com
Структура для получения текущих цен - Структуры данных - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Roman:

No Expert Advisor que chama GetTickStruct, obtém toda a estrutura, com o seu contador.

Por favor escreva uma transferência de número elementar de indicador para EA.

 
fxsaber:

Uma transferência de número elementar de indicador para EA, escreva por favor.

Substituir a estrutura por uma variável ))