Biblioteca de clases genéricas - errores, descripción, preguntas, características de uso y sugerencias - página 16

 
fxsaber:

Interesante. Y aquí hay una pregunta. No me gustó la implementación actual y la modifiqué. Está torcido, por supuesto. ¿Cómo puedo conseguir la biblia original?

Aquí - desde 1702

Archivos adjuntos:
Generic.zip  44 kb
 
Artyom Trishkin:

Aquí - desde 1702

Gracias. Llevaré la pregunta a los desarrolladores. Como soy un poco de enderezar...

 

Ejemplo 2: Operar con varios EAs en una cuenta de red

El posicionamiento neto es un dolor de cabeza, para aquellos que operan más de un Asesor Experto en el mismo símbolo al mismo tiempo. Para tratar situaciones en las que ambos EAs están en una cobertura, pero necesitan entender que la ausencia de una posición neta no indica realmente que no están en el mercado, genera un código complejo. Una solución es calcular la contribución de cada experto a la posición total. Para ello, tenemos que analizar todo el historial y calcular qué número de contratos pertenece a cada Medgie único. Si el número es 0,0, el experto está fuera del mercado, si es negativo, el experto está corto, si es positivo, está largo. En realidad es muy sencillo, si utilizamos CHashMap y simplemente descomponemos todos los tratos por órdenes mágicas sumando sus volúmenes. A continuación he esbozado un código muy sencillo (prototipo):

//+------------------------------------------------------------------+
//|                                                 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;
   }
}
//+------------------------------------------------------------------+

¡Atención! Para simplificar, el código sólo calcula el volumen neto del símbolo actual. También CHashMap en la implementación actual no contiene iteradores de enumeración, así que apresuradamente hice tales iteradores. El CHashMap modificado se muestra en el archivo adjunto.

Archivos adjuntos:
HashMapGen.mqh  25 kb
 
fxsaber:

¿Es importante la velocidad del probador para el comercio? Si es así, el HashMap también afecta al comercio, porque aumenta la velocidad de desarrollo y ejecución de la ST.

Probador, la optimización y el comercio son cosas diferentes.

Una misma idea se negocia y se optimiza, pero la implementación puede diferir dramáticamente, esto también es indiscutible.Pero un ejemplo concreto de una tarea en la que es necesario utilizar estos algoritmos eficientes para el almacenamiento de datos y la extracción, al menos para el optimizador, ya que para el comercio, ¿alguien puede dar un ejemplo?

 
Alexey Oreshkin:

Si quisiera operar con sistemas de trading automatizados, no podría dar ningún ejemplo de tareas en las que se necesiten estos algoritmos eficientes para el almacenamiento y recuperación de datos, al menos para el optimizador, ya que no existen tales algoritmos para el trading...

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

Biblioteca de clases genéricas - errores, descripción, problemas, casos de uso y sugerencias

fxsaber, 2017.12.08 22:46

Para un caso de prueba más realista (2000 operaciones y 1.000.000 de accesos al historial) el resultado es el siguiente

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

¡Casi 100ms de ahorro por pase! Si, por ejemplo, hacemos Optimizar para 10.000 pases completos, la variante Hash acabará siendo 15 minutos más rápida.

 
Vasiliy Sokolov:

Ejemplo 2: Operar con varios EAs en una cuenta de red

Olvidé
prev_deals = HistoryDealsTotal();


Un buen ejemplo. Realmente conveniente.

 
fxsaber:
Olvidé

Buen ejemplo. Muy conveniente.

Corregido.

 

Hay motos que son más fáciles de construir uno mismo que de resolver los matices de usar la de otro y depender de ella.

La genérica no es ese tipo de moto. No se puede escribir de forma rápida y correcta. Sólo sería cuestión de completarlo.

 
fxsaber:

¡Gran ejemplo teórico! En la práctica, ¿alguien ha operado alguna vez miles de operaciones?

p.d. No estoy tratando de demostrar que es una mierda y que nadie lo necesita. Estoy tratando de entender el valor para el comercio real. No soy para nada un teórico, sino un puro practicante.

 
Alexey Oreshkin:

En la práctica, ¿alguien ha hecho miles de operaciones?

En los fuertes cada primero.