Сидите перед монитором десятки минут, видите, как по символу приходят сотни тиков. Как думаете, сколько раз за это время изменился спред? Да и вообще, как такая ерунда может заинтересовать, ведь, очевидно, что спред будет меняться!
Однако, после очередных исследований все же возник интерес изучить данную нестандартную тему: как долго неизменным держится спред?
Смотрел только рынок FOREX на некоторых noname-брокерах.
Ниже исходный код и результаты.
Исходник.
#include <fxsaber\ThirdPartyTicks\Array.mqh> // https://www.mql5.com/ru/code/20225 #include <fxsaber\Calendar\String.mqh> // https://www.mql5.com/ru/code/32430 input datetime inFrom = D'2023.01.09'; ArraySortStruct2_Define(Length) // https://www.mql5.com/ru/forum/170952/page222#comment_40289584 struct SPREAD { private: static double GetSpread( const MqlTick &Tick ) { return(::NormalizeDouble(Tick.ask - Tick.bid, 8)); } static string TimeToString( const ulong Time ) { return((string)(datetime)(Time / 1000) + "." + ::IntegerToString(Time % 1000, 3, '0')); } public: ulong Begin; ulong End; int Count; ulong Length; double Spread; STRING16 Name; SPREAD( void ) : Count(0), Spread(0) { } void Init( const MqlTick &Tick ) { this.Begin = Tick.time_msc; this.End = this.Begin; this.Spread = SPREAD::GetSpread(Tick); this.Count = 1; this.Length = 0; return; } bool Add( const MqlTick &Tick ) { const double NewSpread = SPREAD::GetSpread(Tick); const bool Res = (this.Spread == NewSpread) && (Tick.time_msc - this.End < 3600 * 1000); if (Res) { this.End = Tick.time_msc; this.Count++; } else if (Tick.time_msc - this.End < 3600 * 1000) this.End = Tick.time_msc; this.Length = this.End - this.Begin; return(Res); } string ToString( void ) const { return("Length = " + ::StringSubstr(SPREAD::TimeToString(this.Length), ::StringLen("xxxx.xx.xx ")) + ", Ticks = " + ::IntegerToString(this.Count, 4, ' ') + ", " + this.Name[] + "_spread = " + ::IntegerToString((int)(this.Spread / ::SymbolInfoDouble(this.Name[], SYMBOL_POINT) + 0.1), 4, ' ') + ", "+ " " + SPREAD::TimeToString(this.Begin) + " - " + SPREAD::TimeToString(this.End)); } }; bool AddData( SPREAD &Spreads[], const string Symb, const datetime From, const int MinTicks = 100, const int Amount = 1000 ) { MqlTick Ticks[]; const int Size = CopyTicksRange(Symb, Ticks, COPY_TICKS_ALL, From * 1000); SPREAD Spread;; Spread.Name = Symb; for (int i = 0; i < Size; i++) if (!Spread.Add(Ticks[i])) { if ((Spread.Count >= MinTicks) && Spread.Spread) ARRAY::AddElement(Spreads, Spread, 100000); Spread.Init(Ticks[i]); } ArraySortStruct2(Spreads, Length); ArrayReverse(Spreads); ArrayResize(Spreads, MathMin(ArraySize(Spreads), Amount)); return(Size > 0); } void OnStart() { const string ServerName = AccountInfoString(ACCOUNT_SERVER); SPREAD Spreads[]; for (int i = SymbolsTotal(true) - 1; i >= 0; i--) { const string Symb =SymbolName(i, true); if (!SymbolInfoInteger(Symb, SYMBOL_CUSTOM) && SymbolInfoInteger(Symb, SYMBOL_VISIBLE)) { const string Str = (string)i + ": " + Symb + "_" + ServerName + " from " + (string)inFrom + " - ";; Comment(Str + "calculating..."); Alert(Str + (string)AddData(Spreads, Symb, inFrom)); } } Comment(""); Print(ServerName + " from " + (string)inFrom); for (int i = 0; i < 100; i++) Print(IntegerToString(i, 2, '0') + ": " + Spreads[i].ToString()); }
Noname1.
Tickmill-Live from 2023.01.09 00:00:00 00: Length = 01:21:58.610, Ticks = 547, EURSGD_spread = 500, 2023.01.23 00:06:43.957 - 2023.01.23 01:28:42.567 01: Length = 01:15:14.474, Ticks = 208, USDSGD_spread = 200, 2023.01.23 00:51:36.983 - 2023.01.23 02:06:51.457 02: Length = 01:01:27.143, Ticks = 330, EURSGD_spread = 500, 2023.01.16 00:00:30.077 - 2023.01.16 01:01:57.220 03: Length = 00:57:57.114, Ticks = 189, EURSGD_spread = 500, 2023.01.09 00:02:45.148 - 2023.01.09 01:00:42.262 04: Length = 00:55:28.760, Ticks = 174, NZDSGD_spread = 500, 2023.01.09 00:04:34.152 - 2023.01.09 01:00:02.912 05: Length = 00:55:02.365, Ticks = 142, GBPSEK_spread = 10000, 2023.01.20 00:10:00.429 - 2023.01.20 01:05:02.794 06: Length = 00:44:43.227, Ticks = 1139, GBPCHF_spread = 32, 2023.01.10 08:00:25.525 - 2023.01.10 08:45:08.752 07: Length = 00:39:10.978, Ticks = 146, EURSGD_spread = 500, 2023.01.13 00:16:32.769 - 2023.01.13 00:55:43.747 08: Length = 00:35:30.601, Ticks = 109, GBPCAD_spread = 450, 2023.01.13 00:24:29.678 - 2023.01.13 01:00:00.279 09: Length = 00:33:41.767, Ticks = 538, EURCHF_spread = 8, 2023.01.13 20:00:29.187 - 2023.01.13 20:34:10.954 10: Length = 00:33:23.316, Ticks = 291, EURNOK_spread = 4000, 2023.01.16 01:45:14.165 - 2023.01.16 02:18:37.481
В первой строке показано, что 81 минуту спред на EURSGD не менялся, при этом пришло 547 тиков. Сам спред был 500.
Обращает внимание, что значения спредов почти по всем приведенным символам круглые. Например, спред GBPSEK = 10000 пипсов ровно.
Интервалы больших круглых спредов - ролловер. Можно предположить, что у брокера руками выставлены по одной из двух причин:
- Реальный спред гораздо больше. И чтобы не сносило стопы, максимальный спред ограничен заданным числом.
- Высока вероятность раздевания брокера на этом суточном интервале/символе, поэтому держит столь высокий спред.
Однако, выделяется GBPCHF - не ролловер. Сложно объяснить, зачем в течение 44-х минут брокер дал 1139 подряд тиков без изменения спреда. Возможно, технический сбой.
Noname2.
ICMarketsSC-MT5 from 2023.01.09 00:00:00 00: Length = 01:16:43.571, Ticks = 1034, AUDSGD_spread = 22, 2023.01.23 01:18:52.473 - 2023.01.23 02:35:36.044 01: Length = 01:00:05.359, Ticks = 318, CHFSGD_spread = 500, 2023.01.16 00:04:55.096 - 2023.01.16 01:05:00.455 02: Length = 00:57:39.937, Ticks = 395, GBPUSD_spread = 70, 2023.01.16 00:02:20.282 - 2023.01.16 01:00:00.219 03: Length = 00:56:04.979, Ticks = 177, USDSGD_spread = 250, 2023.01.16 00:04:55.046 - 2023.01.16 01:01:00.025 04: Length = 00:55:05.173, Ticks = 322, GBPCHF_spread = 200, 2023.01.16 00:04:55.038 - 2023.01.16 01:00:00.211 05: Length = 00:48:48.990, Ticks = 280, AUDSGD_spread = 200, 2023.01.16 00:12:11.099 - 2023.01.16 01:01:00.089 06: Length = 00:46:59.475, Ticks = 214, GBPCHF_spread = 200, 2023.01.13 00:00:01.874 - 2023.01.13 00:47:01.349 07: Length = 00:46:47.711, Ticks = 464, GBPJPY_spread = 200, 2023.01.13 00:00:01.829 - 2023.01.13 00:46:49.540 08: Length = 00:45:36.329, Ticks = 2326, CHFJPY_spread = 200, 2023.01.17 00:02:33.427 - 2023.01.17 00:48:09.756 09: Length = 00:43:10.653, Ticks = 268, GBPCAD_spread = 200, 2023.01.13 00:00:01.645 - 2023.01.13 00:43:12.298 10: Length = 00:41:54.697, Ticks = 1118, XAUUSD_spread = 9, 2023.01.12 01:04:44.544 - 2023.01.12 01:46:39.241
На этом брокере почти такая же картина с круглыми спредами.
Оставил только CHF-символы.
08: Length = 00:32:48.672, Ticks = 1743, GBPCHF_spread = 26, 2023.01.16 01:00:00.211 - 2023.01.16 01:32:48.883 10: Length = 00:31:35.540, Ticks = 864, GBPCHF_spread = 26, 2023.01.20 01:00:00.243 - 2023.01.20 01:31:35.783 13: Length = 00:30:07.934, Ticks = 1140, CADCHF_spread = 15, 2023.01.16 01:00:00.218 - 2023.01.16 01:30:08.152 16: Length = 00:27:21.244, Ticks = 387, GBPCHF_spread = 26, 2023.01.11 01:00:00.230 - 2023.01.11 01:27:21.474 20: Length = 00:23:45.795, Ticks = 569, AUDCHF_spread = 13, 2023.01.18 01:00:00.235 - 2023.01.18 01:23:46.030 24: Length = 00:22:18.612, Ticks = 778, GBPCHF_spread = 26, 2023.01.27 01:00:00.190 - 2023.01.27 01:22:18.802 25: Length = 00:21:41.541, Ticks = 945, AUDCHF_spread = 13, 2023.01.16 01:00:00.220 - 2023.01.16 01:21:41.761 28: Length = 00:20:27.507, Ticks = 1102, GBPCHF_spread = 26, 2023.01.12 01:00:04.286 - 2023.01.12 01:20:31.793 29: Length = 00:19:52.241, Ticks = 453, AUDCHF_spread = 13, 2023.01.20 01:00:00.243 - 2023.01.20 01:19:52.484 31: Length = 00:17:55.349, Ticks = 296, CADCHF_spread = 15, 2023.01.20 01:04:58.239 - 2023.01.20 01:22:53.588 33: Length = 00:17:06.185, Ticks = 897, GBPCHF_spread = 26, 2023.01.25 01:00:00.222 - 2023.01.25 01:17:06.407 34: Length = 00:17:05.645, Ticks = 383, GBPCHF_spread = 26, 2023.01.23 01:00:00.266 - 2023.01.23 01:17:05.911 35: Length = 00:17:04.727, Ticks = 344, CADCHF_spread = 15, 2023.01.18 01:00:00.232 - 2023.01.18 01:17:04.959 36: Length = 00:16:53.920, Ticks = 807, AUDCHF_spread = 13, 2023.01.12 01:00:00.207 - 2023.01.12 01:16:54.127 37: Length = 00:16:48.420, Ticks = 481, AUDCHF_spread = 13, 2023.01.23 01:00:00.265 - 2023.01.23 01:16:48.685 38: Length = 00:16:38.373, Ticks = 515, GBPCHF_spread = 26, 2023.01.18 01:00:00.236 - 2023.01.18 01:16:38.609 39: Length = 00:16:19.085, Ticks = 299, AUDCHF_spread = 13, 2023.01.25 01:00:00.222 - 2023.01.25 01:16:19.307 41: Length = 00:15:36.084, Ticks = 318, CADCHF_spread = 15, 2023.01.23 01:00:31.181 - 2023.01.23 01:16:07.265 42: Length = 00:15:01.875, Ticks = 352, CADCHF_spread = 15, 2023.01.13 01:00:00.218 - 2023.01.13 01:15:02.093 43: Length = 00:15:00.227, Ticks = 701, CADCHF_spread = 15, 2023.01.27 01:00:00.185 - 2023.01.27 01:15:00.412 44: Length = 00:15:00.118, Ticks = 331, AUDCHF_spread = 13, 2023.01.27 01:00:00.189 - 2023.01.27 01:15:00.307 45: Length = 00:14:05.477, Ticks = 128, CADCHF_spread = 15, 2023.01.11 01:01:01.543 - 2023.01.11 01:15:07.020 46: Length = 00:13:36.015, Ticks = 531, GBPCHF_spread = 26, 2023.01.19 01:00:00.077 - 2023.01.19 01:13:36.092 47: Length = 00:12:45.220, Ticks = 432, GBPCHF_spread = 26, 2023.01.13 01:03:22.394 - 2023.01.13 01:16:07.614 48: Length = 00:12:36.700, Ticks = 408, CADCHF_spread = 15, 2023.01.12 01:05:33.438 - 2023.01.12 01:18:10.138 49: Length = 00:11:57.105, Ticks = 496, CADCHF_spread = 15, 2023.01.25 01:00:00.214 - 2023.01.25 01:11:57.319 50: Length = 00:11:50.949, Ticks = 186, AUDCHF_spread = 13, 2023.01.26 01:00:00.124 - 2023.01.26 01:11:51.073 51: Length = 00:11:50.872, Ticks = 323, CADCHF_spread = 15, 2023.01.26 01:00:00.203 - 2023.01.26 01:11:51.075 52: Length = 00:11:38.345, Ticks = 189, CADCHF_spread = 15, 2023.01.24 01:00:00.151 - 2023.01.24 01:11:38.496 53: Length = 00:11:36.444, Ticks = 152, GBPCHF_spread = 26, 2023.01.26 01:00:00.219 - 2023.01.26 01:11:36.663
Обращает внимание, что спреды некрупные и сразу после часа ночи. Зачем это нужно брокеру? Это не совпадение, т.к. спреды повторяются.
Две гипотезы.
- Просто держат спред шире рынка, чтобы уменьшить мат. ожидание клиентов. Но при этом сильно не наглеть.
- Заманивание на крупное отрицательное проскальзывание: как торговый приказ пошел на исполнение, вбрасывается (автоматически) шпилька.
Итог.
Как видите, никакой полезной информации. Вы зря потратили свое время. Не пишите такие скрипты, как приложенный ниже.