Biblioteca de classes genéricas - bugs, descrição, perguntas, recursos de uso e sugestões - página 16

 
fxsaber:

Interessante. E aqui vai uma pergunta. Eu não gostei da implementação actual e ajustei-a. Está torto, é claro. Como é que recebo a bíblia original?

Aqui - a partir de 1702

Arquivos anexados:
Generic.zip  44 kb
 
Artyom Trishkin:

Aqui - a partir de 1702

Obrigado! Vou levar a pergunta aos desenvolvedores. Como eu sou um pouco endireitador...

 

Exemplo 2: Negociação de múltiplos EAs em uma conta líquida

O posicionamento em rede é uma dor de cabeça, para aqueles que negociam mais de um Expert Advisor no mesmo símbolo ao mesmo tempo. Para lidar com situações em que ambos EAs estão em uma cobertura, mas precisam entender que a ausência de uma posição líquida não indica realmente que eles não estão no mercado, gera um código complexo. Uma solução é calcular a contribuição de cada especialista para a posição total. Para isso, precisamos de analisar todo o histórico e calcular o número de contratos que pertencem a cada Medgie único. Se o número for 0,0, o especialista está fora do mercado, se for negativo, o especialista é curto, se for positivo, é longo. Na verdade é muito simples, se usarmos CHashMap e simplesmente decompusermos todos os negócios por ordens mágicas adicionando os seus volumes. Eu esbocei um código muito simples (protótipo) abaixo:

//+------------------------------------------------------------------+
//|                                                 NettoByMagic.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#include <Generic\HashMapGen.mqh>

CHashMap<ulong, double> PositionsByMagic;
int prev_deals = 0;
//+------------------------------------------------------------------+
//| Добавляет новый объем и его меджик                               |
//+------------------------------------------------------------------+
void AddVolume(ulong magic, double volume)
{
   double cur_volume = 0.0;
   if(PositionsByMagic.TryGetValue(magic, cur_volume))
      PositionsByMagic.TrySetValue(magic, cur_volume+volume);
   else
      PositionsByMagic.Add(magic, volume);
}
//+------------------------------------------------------------------+
//| Добавляет новые сделки в словарь                                 |
//+------------------------------------------------------------------+
void ParseDeals()
{
   HistorySelect(0, TimeCurrent());
   for(int i = prev_deals; i < HistoryDealsTotal(); i++)
   {
      ulong ticket = HistoryDealGetTicket(i);
      if(HistoryDealGetString(ticket, DEAL_SYMBOL)!= Symbol())
         continue;
      ENUM_DEAL_TYPE deal_type = (ENUM_DEAL_TYPE)HistoryDealGetInteger(ticket, DEAL_TYPE);
      double volume = 0.0;
      if(deal_type == DEAL_TYPE_BUY)
         volume = HistoryDealGetDouble(ticket, DEAL_VOLUME);
      else if(deal_type == DEAL_TYPE_SELL)
         volume = HistoryDealGetDouble(ticket, DEAL_VOLUME)*(-1);
      else
         continue;
      ulong magic = HistoryDealGetInteger(ticket, DEAL_MAGIC);
      AddVolume(magic, volume);
   }
   prev_deals = HistoryDealsTotal();
}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnTick()
{
   ParseDeals();
   for(int i = 0, k = 0; i < PositionsByMagic.Count(); i++)
   {
      ulong magic = PositionsByMagic.GetKeyAt(i);
      double valume = PositionsByMagic.GetValueAt(i);
      if(k == 10)
         break;
   }
}
//+------------------------------------------------------------------+

Atenção! Para simplificar, o código só calcula o volume líquido para o símbolo atual. Também o CHashMap na implementação atual não contém iteradores de enumeração, então eu fiz esses iteradores apressadamente. O CHashMap modificado é mostrado no anexo.

Arquivos anexados:
HashMapGen.mqh  25 kb
 
fxsaber:

A velocidade do testador é importante para a negociação? Se assim for, o HashMap também afeta a negociação, pois aumenta a velocidade de desenvolvimento e execução do TS.

Testador, otimização e negociação são coisas diferentes.

Uma mesma idéia é negociada e otimizada, mas a implementação pode diferir drasticamente, o que também é indiscutível. Mas um exemplo concreto de uma tarefa onde é necessário usar esses algoritmos eficientes para armazenamento e extração de dados, pelo menos para otimizador, já que para negociação, qualquer um pode dar um exemplo ?

 
Alexey Oreshkin:

Se eu quisesse negociar com sistemas comerciais automatizados, não poderia dar nenhum exemplo de tarefas onde esses eficientes algoritmos de armazenamento e recuperação de dados seriam necessários, pelo menos para o otimizador, já que não existem tais algoritmos para negociação.

Fórum sobre negociação, sistemas de negociação automatizados e testes estratégicos

Biblioteca de classes genéricas - bugs, descrição, problemas, casos de uso e sugestões

fxsaber, 2017.12.08 22:46

Para um caso de teste mais realista (2000 negócios e 1.000.000 acessos únicos ao histórico) o resultado é o seguinte

2017.12.05 00:00:00   Time[Print(SumProfit(Deals,GetDealProfitFull))] = 122969
2017.12.05 00:00:00   Time[SetHashMap()] = 816
2017.12.05 00:00:00   4829800340.792288
2017.12.05 00:00:00   Time[Print(SumProfit(Deals,GetDealProfitHashClear))] = 23852
2017.12.05 00:00:00   Time[HistorySelect(0,INT_MAX)] = 1
2017.12.05 00:00:00   4829800340.792288
2017.12.05 00:00:00   Time[Print(SumProfit(Deals,GetDealProfitClear))] = 114427

Quase 100ms de poupança por passe! Se, digamos, fizermos Optimizar por 10.000 passes completos, a variante Hash vai acabar 15 minutos mais rápido.

 
Vasiliy Sokolov:

Exemplo 2: Negociação de múltiplos EAs em uma conta líquida

Esqueci-me
prev_deals = HistoryDealsTotal();


Um bom exemplo! Realmente conveniente.

 
fxsaber:
Esqueci-me

Um bom exemplo! Conveniente mesmo.

Corrigido.

 

Há motos que são mais fáceis de construir do que de resolver as nuances de usar as de outra pessoa e dependendo delas.

Genérico não é esse tipo de bicicleta. Não se pode escrevê-lo rápida e correctamente. Seria apenas uma questão de o completar.

 
fxsaber:

Grande exemplo teórico! Na prática, alguém já operou milhares de negócios?

p.s. Não estou a tentar provar que é uma porcaria e ninguém precisa dela. Estou a tentar compreender o valor de uma negociação a sério. Eu não sou um teórico, mas um puro praticante.

 
Alexey Oreshkin:

Na prática, alguém já fez milhares de negócios?

Em Forts todos os primeiros.