两个期货之间的价差 - 页 3

 
Dmi3:

良好的结果,祝贺你。

你知道如何在10.00.00进入套利交易吗?

可惜没有,否则结果会更大。

在图表上,你可以看到它离10-00很远,每1对的利润是141点。


 
prostotrader:

可惜没有,否则结果会大很多倍。

在图表上,你可以看到它离10-00很远,而利润变成了每1对141点。


个人交易并不有趣。股票在这里是有意义的,但在我的编码水平上很难根据日历来追踪股票。可能不适合你,你能给我看看至少今年的黄金日历上的股权吗?我试图在GOLD上交易日历,并从这个话题中走了出来。太突然的BA运动,虽然也许我正好碰到了从1500点到2000点的无障碍上升期,但到目前为止我已经放弃了冲动:(

 
Dmi3:

单独的交易并不有趣....

是吗?让我们来算一算...

141点*62对*7,558卢布(每点)=66072.036卢布。(脏,不包括佣金)

交易日历并不容易,你真的可以把事情搞砸。

为了防止这种情况,你需要一个良好和准确的历史,当然还有实时数据。

当然,你还必须密切关注新闻,特别是政治新闻。

 
prostotrader:

是吗?让我们来算一算...

141点*62对*7.558卢布(每点)=66072.036卢布。(脏,不包括佣金)

那么你在日历上也没有股权?也许你有自己的方法,与我的方法明显不同。在我的方法中,你根本不需要关注新闻。:)

我会考虑的,谢谢!

我只在到期前2周交易日历,在到期前1天停止。

 
iiivasyaiii :

简单的交易者,非常感谢您的建议!解决方案很有趣,现在我会尝试,然后我会取消订阅。

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

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

但是我的电脑有问题

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

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

我的 电脑有一个问题

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

Prostotrader,非常感谢你的代码!我也有一个开瓶器。

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:

是吗?让我们来算一算...

141点*62对*7.558卢布(每点)=66072.036卢布。(脏,不包括佣金)

交易日历并不容易,你真的可以把事情搞砸。

为了防止这种情况,你需要一个良好和准确的历史,当然还有实时数据。

当然,人们必须密切关注新闻,特别是政治新闻。

62对?你怎么能找到这么多?我连最大胆的猜测都没有,因为62种变化))。

 
iiivasyaiii:

六十二对?你怎么能找到这么多?我对62种变化连最大胆的估计都没有))。

:)62*2合同金

 
iiivasyaiii:

Prostotrader,非常感谢你的代码!我也有一个开瓶器。

需要对其进行调整以消除错误...

现在没有时间,稍后再做。

顺便说一下,在GetStartTime函数中

你必须替换掉这条线

a_month = a_month - 1;

a_month = a_month - next_month;

 
prostotrader:

:)62*2合同金

如果我问的问题过于 "亲密",我当然要表示歉意,但我已经习惯于深入了解细节。

你在9月17日到底在讽刺什么,我不清楚。

如果GOLD-12.20-GOLD-9.20,那么GOLD-9.20从17/09的12.30开始,价格不会发生变化,因为合约的结算价格已经由规范决定,所以你没有套利,而是简单而不复杂的反趋势GOLD-12.20。



如果GOLD-3.21-GOLD-12.20,尽管根据交易所的数据,17.09日GOLD-3.21的总交易量只有306份合同,你到底是如何得到62份合同进入+62份合同退出=124份合同的?


结果变体二是不可能的,变体一是可能的。但这根本就不是套利,你明白吗?