Diferencia entre dos futuros - página 3

 
Dmi3:

Buen resultado, enhorabuena.

¿Sabes cómo entrar en una operación de arbitraje a las 10.00 horas?

Lamentablemente no, de lo contrario el resultado habría sido mucho mayor.

En el gráfico se puede ver que está lejos de 10-00 y el beneficio es de 141 pips por 1 par


 
prostotrader:

Lamentablemente no, de lo contrario el resultado habría sido muchas veces mayor

En el gráfico se puede ver que está lejos de 10-00, y el beneficio resultó 141 puntos por 1 par


Las operaciones individuales no son interesantes. La renta variable es de interés en este caso, pero es difícil rastrear la renta variable según los calendarios a mi nivel de codificación. Probablemente no para usted, ¿puede mostrarme la equidad en un calendario de ORO al menos para este año? Intenté negociar el calendario sobre el ORO y me alejé de ese tema. Movimientos demasiado bruscos de la BA, aunque quizás me tocó el periodo justo de una subida sin freno de los 1500 a los 2000, pero de momento he renunciado a las ganas :(

 
Dmi3:

Un acuerdo separado no es interesante....

¿Sí? Hagamos las cuentas...

141 puntos * 62 pares * 7,558 rublos (por punto) = 66072,036 rublos. (sucio, excluyendo las comisiones)

No es fácil comerciar con el calendario, puedes meter la pata.

para evitarlo se necesita un buen y preciso historial y, por supuesto, datos en tiempo real...

Y, por supuesto, hay que seguir de cerca las noticias, especialmente las políticas.

 
prostotrader:

¿Sí? Hagamos las cuentas...

141 puntos * 62 pares * 7.558 rublos (por punto) = 66072.036 rublos. (sucio, sin incluir las comisiones)

Entonces, ¿tampoco tienes capital en los calendarios? Tal vez usted tenga su propio método, significativamente diferente al mío. En mi método no es necesario seguir las noticias en absoluto. :)

Lo pensaré, ¡gracias!

Sólo opero con calendarios 2 semanas antes del vencimiento y paro 1 día antes del vencimiento.

 
iiivasyaiii :

Comerciante simple, ¡muchas gracias por su consejo! La solución es interesante, ahora la pruebo, luego me doy de baja.

 //+------------------------------------------------------------------+
//|                                                       Spread.mq5 |
//|                                     Copyright 2020, prostotrader |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015-2020, prostotrader"
#property link        "http://www.mql5.com"
#property version    "1.035"
//
#property indicator_separate_window

#property indicator_buffers 2
#property indicator_plots    2

//--- plot Label1
#property indicator_label1    "Hi spread"
#property indicator_type1    DRAW_LINE
#property indicator_color1    clrRed
#property indicator_style1    STYLE_SOLID
#property indicator_width1    1
//--- plot Label2
#property indicator_label2    "Low spread"
#property indicator_type2    DRAW_LINE
#property indicator_color2    clrBlue
#property indicator_style2    STYLE_SOLID
#property indicator_width2    1
//--- Levels
#property indicator_level1 0
#property indicator_level2 0
#property indicator_level3 0
//---
struct DATA_TIME
{
   datetime time;
   double hi_value;
   double low_value;
};
//
string sec_symbol;
//
input string    FutName   = "BR-11.20" ;             //Имя второго фьючерса 
input int       NMonth    = 3 ;                       //Разница между фьючерсами (мес)
input int       BrMonth   = 1 ;                       //Разн. между фьюч.(мес) Brent(RVI, CL)
input bool      AutoDate  = false ;                   //Автоматическое начало расчета 
input datetime StartData = D'2020.07.01 19:05:00' ; //Дата начала расчёта индикатора
input bool      Hyst      = true ;                   //Использовать историю
input bool      UseOtstup = true ;                   //Использовать Мин./Мах индикатора
input double    Otstup    = 30 ;                     //Мин./Мах индикатора

//--- indicator buffers
double HiBuff[], LowBuff[];
double max_value; 
double min_value;
double mid_value;
ulong   mid_cnt;
//---
datetime start_time;
datetime end_time;
//
datetime time_array[];
bool pr_book, sec_book;
MqlTick pr_ticks[], sec_ticks[];
int pr_cnt, sec_cnt;
//
int next_month;
int event_cnt;
DATA_TIME data_time[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
bool CheckOneMonth( const string a_symb)
{
   if (( StringFind (a_symb, "BR-" ) == 0 ) || ( StringFind (a_symb, "CL-" ) == 0 ) ||
     ( StringFind (a_symb, "GLD-" ) == 0 ) || ( StringFind (a_symb, "RVI-" ) == 0 ) ||
     ( StringFind (a_symb, "UINR-" ) == 0 ) || ( StringFind (a_symb, "Al-" ) == 0 ) ||
     ( StringFind (a_symb, "Zn-" ) == 0 ) || ( StringFind (a_symb, "Nl-" ) == 0 ) ||
     ( StringFind (a_symb, "Co-" ) == 0 ) || ( StringFind (a_symb, "NG-" ) == 0 ))
  {
     return ( true );
  }
   return ( false );
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
datetime GetStartTime( const string a_symb)
{
   int str_tire = StringFind (a_symb, "-" );
   int str_tochka = StringFind (a_symb, "." , str_tire);
   int str_size = StringLen (a_symb);
   if ((str_tire > 0 ) && (str_tochka > 0 ) && (str_size > 0 ))
  {
     string str_month = StringSubstr (a_symb, str_tire + 1 , str_tochka - str_tire - 1 );
     string str_year = StringSubstr (a_symb, str_tochka + 1 , str_size - str_tochka - 1 );
     long a_month = StringToInteger (str_month);
     long a_year = StringToInteger (str_year); 
     string pr_symb;
    a_month = a_month - 1 ;
     if (a_month == 0 )
    {
      a_month = 12 ;
      a_year = a_year - 1 ; 
    }
    str_year = IntegerToString (a_year); 
    str_month = IntegerToString (a_month);
    pr_symb = StringSubstr (a_symb, 0 , str_tire + 1 ) + str_month + "." + str_year;
     if ( SymbolSelect (pr_symb, true ) == true )
    {
       Print ( __FUNCTION__ , ": Предыдудищий фьючерс " , pr_symb);
       SymbolSelect (pr_symb, false );
       return ( datetime ( ulong ( SymbolInfoInteger (pr_symb, SYMBOL_EXPIRATION_TIME )) + 60 * 20 ));
    }  
  }
   return ( datetime ( 0 ));
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
{
  mid_value = 0 ;
  mid_cnt = 0 ;
   if ( TerminalInfoInteger ( TERMINAL_BUILD ) < 2560 )
  {
     Print ( "Версия билда терминала должна быть не менее 2560!" );
     return ( INIT_FAILED );
  }
   if ( Period () != PERIOD_M1 )
  {
     Print ( "Период графика должен быть М1!" );
     return ( INIT_FAILED );
  }
  event_cnt = 0 ;
  next_month = NMonth;
  max_value = - DBL_MAX ; 
  min_value = DBL_MAX ;
//---
   if (CheckOneMonth( Symbol ())== true )
  {
    next_month = BrMonth;
  }
   else
  {
    next_month = NMonth; 
  }
  sec_symbol = FutName;
  
if(CheckOneMonth(sec_symbol)== true)
  {
    if(next_month == 3)
    { 
      Alert("Продолжительность фючерсов не совпадает!");
      return(INIT_FAILED);
    }  
  } 
  
   ResetLastError ();
   if (! SymbolInfoInteger (sec_symbol, SYMBOL_SELECT ))
  {
     if ( GetLastError () != ERR_MARKET_UNKNOWN_SYMBOL )
    {
       SymbolSelect (sec_symbol, true );
    }
     else
    {
       Print ( __FUNCTION__ , ": Неизвестный символ - " , sec_symbol);
       return ( INIT_FAILED );
    }    
  }
  end_time = datetime ( SymbolInfoInteger ( Symbol (), SYMBOL_EXPIRATION_TIME ));
   if (AutoDate == true )
  {
    start_time = GetStartTime( Symbol ());
  }
   else
  {
    start_time = StartData;
  }  
//---  
   IndicatorSetInteger ( INDICATOR_DIGITS , 0 );
   IndicatorSetString ( INDICATOR_SHORTNAME , "Spread" );
   SetIndexBuffer ( 0 , HiBuff, INDICATOR_DATA );
   ArraySetAsSeries (HiBuff, true );
   PlotIndexSetDouble ( 0 , PLOT_EMPTY_VALUE , EMPTY_VALUE );
   SetIndexBuffer ( 1 , LowBuff, INDICATOR_DATA );
   ArraySetAsSeries (LowBuff, true );
   PlotIndexSetDouble ( 1 , PLOT_EMPTY_VALUE , EMPTY_VALUE );
   IndicatorSetInteger ( INDICATOR_LEVELCOLOR , 0 , clrRed );
   IndicatorSetInteger ( INDICATOR_LEVELCOLOR , 1 , clrBlue );
   IndicatorSetInteger ( INDICATOR_LEVELCOLOR , 2 , clrYellow ); 
   IndicatorSetInteger ( INDICATOR_LEVELSTYLE , STYLE_DOT );
   IndicatorSetInteger ( INDICATOR_LEVELWIDTH , 1 );
//--- Bars on chart
   if (Hyst == true )
  {
     int cnt = 0 ;
     int result = 0 ;
     int res = 0 ;
     int a_bars = 0 ;
     while ((result <= 0 ) && (cnt < 100 )) 
    {
      result = CopyTime ( Symbol (), PERIOD_M1 , start_time, end_time, time_array);
       if (result == a_bars) break ;
      cnt++;   
    }
     if (result > 0 )
    {
      cnt = 0 ;
      result = 0 ;
       while ((result <= 0 ) && (cnt < 100 )) 
      {
        result = CopyTicksRange ( Symbol (), pr_ticks, COPY_TICKS_INFO , ulong (start_time) * 1000 , ulong (end_time) * 1000 );
        cnt++;
      }
       if (result > 0 )
      {
        pr_cnt = result;
        cnt = 0 ;
        result = 0 ;
         while ((result <= 0 ) && (cnt < 100 )) 
        {
          result = CopyTicksRange (sec_symbol, sec_ticks, COPY_TICKS_INFO , ulong (start_time) * 1000 , ulong (end_time) * 1000 );
          cnt++;
        }
         if (result > 0 )
        {
          sec_cnt = result;
          cnt = 0 ;
           ArrayResize (data_time, a_bars);
           ZeroMemory (data_time);
           for ( int i = 0 ; i < a_bars; i++)
          {
             if ( ulong (time_array[i])>= ulong (start_time))
            {
              data_time[cnt].time = time_array[i]; 
              cnt++;
            }
          }
           if (cnt > 0 )
          {
            a_bars = cnt;
             ArrayResize (data_time, a_bars);
             int pr_pos = 0 ;
             int sec_pos = 0 ;
             bool is_found;
             int pr_mem = 0 ;
             int sec_mem = 0 ;
//---            
             for ( int i = 0 ; i < a_bars; i++)
            {
              data_time[i].hi_value = EMPTY_VALUE ;
              data_time[i].low_value = EMPTY_VALUE ;
              is_found = false ;
               while (pr_pos < pr_cnt) 
              {
                 if (( ulong (data_time[i].time) <= ulong (pr_ticks[pr_pos].time)) &&
                   ( ulong (data_time[i].time) + 60 > ulong (pr_ticks[pr_pos].time)))
                {
                  pr_mem = pr_pos;
                   while (sec_pos < sec_cnt) 
                  {
                     if (( ulong (data_time[i].time) <= ulong (sec_ticks[sec_pos].time)) &&
                       ( ulong (data_time[i].time) + 60 > ulong (sec_ticks[sec_pos].time)))
                    {
                      is_found = true ;
                      sec_mem = sec_pos;
                       if ((sec_ticks[sec_pos].bid > 0.0 ) && (pr_ticks[pr_pos].ask > 0.0 ) &&
                         (sec_ticks[sec_pos].ask > 0.0 ) && (pr_ticks[pr_pos].bid > 0.0 ))
                      {
                        data_time[i].hi_value = sec_ticks[sec_pos].bid - pr_ticks[pr_pos].ask;
                        data_time[i].low_value = sec_ticks[sec_pos].ask - pr_ticks[pr_pos].bid;
                      }
                       break ;
                    }
                    sec_pos++;
                  }
                   break ;
                }
                pr_pos++;
              }
              pr_pos = pr_mem;
              sec_pos = sec_mem;
            }
          }
        }
         else
        {
           Alert ( "Не получены тики по второму символу!" );
           return ( INIT_FAILED );
        }
      }
       else
      {
         Alert ( "Не получены тики по первому символу!" );
         return ( INIT_FAILED );
      }
    }
     else
    {
       Alert ( "Не получены бары по символу!" );
       return ( INIT_FAILED );
    }
  }
//--- Books ---    
  pr_book = MarketBookAdd ( Symbol ());
  sec_book = MarketBookAdd (sec_symbol);
   return ( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+
// Custom indicator DeInit function                                  |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason)
{
   if (pr_book == true ) MarketBookRelease ( Symbol ());
   if (sec_book == true ) MarketBookRelease (sec_symbol);
   if (reason == REASON_INITFAILED )
  {
     Print ( "Индикатор удалён! Причина - ошибка инициализации." );
     ChartIndicatorDelete ( 0 , 1 , "Spread" ); 
  }
}
//+------------------------------------------------------------------+
//| Custom indicator On book event function                          |
//+------------------------------------------------------------------+
void OnBookEvent ( const string &symbol)
{
   if ((symbol == Symbol ()) || (symbol == sec_symbol))
  {
     datetime a_time[];
     double a_open[];
     double a_high[];
     double a_low[];
     double a_close[];
     long a_t_vol[];
     long vol[];
     int a_spread[];
     OnCalculate (event_cnt, event_cnt, a_time, a_open, a_high, a_low, a_close, a_t_vol, vol, a_spread); 
  }
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate ( const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[] )
{
   if (prev_calculated == 0 )
  {
     ArrayInitialize (HiBuff, EMPTY_VALUE );
     ArrayInitialize (LowBuff, EMPTY_VALUE );
     if (Hyst == true )
    {
       ArraySetAsSeries (time, true );
       int pos = 0 ;
       int mem_pos = 0 ;
       bool is_found;
       for ( int i = rates_total - 1 ; i > 0 ; i--)
      {
        is_found = false ;
         while (pos < ArraySize (data_time))
        {
           if (time[i] == data_time[pos].time)
          {
            is_found = true ;
            mem_pos = pos;
             if ((data_time[pos].hi_value != EMPTY_VALUE ) && (data_time[pos].low_value != EMPTY_VALUE ))
            {
              HiBuff[i] = data_time[pos].hi_value/ Point ();
              LowBuff[i] = data_time[pos].low_value/ Point ();
               if (HiBuff[i] > max_value) max_value = HiBuff[i];
               if (LowBuff[i] < min_value) min_value = LowBuff[i];
               mid_value = mid_value * mid_cnt + (min_value + max_value)/ 2 ;
               mid_cnt++; 
               mid_value = mid_value/mid_cnt;
            }
             else
            {
               if (i < rates_total - 1 )
              {
                HiBuff[i] = HiBuff[i+ 1 ];
                LowBuff[i] = LowBuff[i+ 1 ];
              }  
            }
             break ;
          }
          pos++;
        }
         if (is_found == false )
        {
          pos = mem_pos;
        }
      }
    }
  }
   else
  {
     double sec_ask = SymbolInfoDouble (sec_symbol, SYMBOL_ASK );
     double sec_bid = SymbolInfoDouble (sec_symbol, SYMBOL_BID );
     double pr_ask = SymbolInfoDouble ( Symbol (), SYMBOL_ASK );
     double pr_bid = SymbolInfoDouble ( Symbol (), SYMBOL_BID );
     if ((sec_ask> 0 ) && (sec_bid > 0 ) && (pr_ask > 0 ) && (pr_bid > 0 ))
    {
       double hi_val = (sec_bid - pr_ask)/ Point ();
       double low_val = (sec_ask - pr_bid)/ Point ();
       if (hi_val > max_value) max_value = hi_val;
       if (low_val < min_value) min_value = low_val;
      HiBuff[ 0 ] = hi_val;
      LowBuff[ 0 ] = low_val;
      mid_value = mid_value * mid_cnt + (min_value + max_value)/ 2 ;
      mid_cnt++; 
      mid_value = mid_value/mid_cnt;
    }
     else
    {
      HiBuff[ 0 ] = HiBuff[ 1 ];
      LowBuff[ 0 ] = LowBuff[ 1 ];
    }
  }
   IndicatorSetDouble ( INDICATOR_LEVELVALUE , 0 , max_value);
   IndicatorSetDouble ( INDICATOR_LEVELVALUE , 1 , min_value);
   IndicatorSetDouble ( INDICATOR_LEVELVALUE , 2 , mid_value);
   if (UseOtstup == true )
  {
     IndicatorSetDouble ( INDICATOR_MAXIMUM , max_value + Otstup);
     IndicatorSetDouble ( INDICATOR_MINIMUM , min_value - Otstup);
  }  
//--- return value of prev_calculated for next call
   event_cnt = rates_total;
//--- 
   return (rates_total);
}

//+------------------------------------------------------------------+

Pero hay un problema en mi computadora.

https://www.mql5.com/ru/forum/351487

Просьба запустить на реале на BR-11.20
Просьба запустить на реале на BR-11.20
  • 2020.09.18
  • www.mql5.com
Пишу индикатор с использованием функции CopyTicksRange(); Получаю кастрированные данные https://www.mql5...
 
prostotrader:

Pero hay un problema en mi ordenador

https://www.mql5.com/ru/forum/351487

Prostotrader, ¡muchas gracias por el código! Yo también tengo un abridor.

LD      0       12:49:16.265    Proverka-CopyTicksRange (BR-11.20,M1)   Start time = 2020.07.01 19:05:00
FK      0       12:49:16.265    Proverka-CopyTicksRange (BR-11.20,M1)   End time = 2020.11.02 18:45:00
KO      0       12:49:16.265    Proverka-CopyTicksRange (BR-11.20,M1)   Time now = 2020.09.21 08:49:16
EI      0       12:49:16.265    Proverka-CopyTicksRange (BR-11.20,M1)   Bars last time = 2020.09.18 23:49:00
QD      0       12:49:16.265    Proverka-CopyTicksRange (BR-11.20,M1)   Last tick time = 2020.09.18 23:57:33
 
prostotrader:

¿Sí? Hagamos las cuentas...

141 puntos * 62 pares * 7,558 rublos (por punto) = 66072,036 rublos. (sucio, excluyendo las comisiones)

No es fácil comerciar con el calendario, puedes meter la pata.

para evitarlo se necesita un buen y preciso historial y, por supuesto, datos en tiempo real...

Y, por supuesto, hay que seguir de cerca las noticias, especialmente las políticas.

¡¿62 pares?! ¿Cómo se las arregló para encontrar tantos? No tengo ni la más atrevida conjetura de 62 variaciones))

 
iiivasyaiii:

¡¿Sesenta y dos pares?! ¿Cómo se las arregló para encontrar tantos? No tengo ni la más mínima estimación de 62 variaciones))

:) 62*2 CONTRATO oro

 
iiivasyaiii:

Prostotrader, ¡muchas gracias por el código! Yo también tengo un abridor.

Hay que retocarlo para eliminar el error...

No tengo tiempo ahora, lo haré un poco más tarde

Por cierto, en la función GetStartTime

hay que sustituir la línea

a_mes = a_mes - 1;

a

a_mes = a_mes - siguiente_mes;

 
prostotrader:

:) 62*2 CONTRATO oro

Desde luego, pido disculpas si hago preguntas demasiado "íntimas", pero estoy acostumbrado a entrar en detalles.

No me queda claro qué es exactamente lo que sarbaste el 17 de septiembre.

Si ORO-12,20-ORO-9,20, entonces ORO-9,20 a partir de las 12,30 del 17/09 no cambia de precio, ya que el precio de liquidación del contrato ya ha sido determinado por la especificación, por lo que no tiene arbitraje, sino una simple y poco complicada contra-tendencia ORO-12,20.



Si GOLD-3.21-GOLD-12.20, ¿cómo demonios se han conseguido 62 contratos de entrada + 62 contratos de salida = 124 contratos, a pesar de que el volumen total de negociación de GOLD-3.21 el 17.09 fue de sólo 306 contratos según los datos de la bolsa?


Como resultado, la variante dos no es posible, la variante uno sí. Pero esto no es un arbitraje en absoluto, ¿entiendes?

Razón de la queja: