Блог им. kurd

Беспроигрышная стратегия для фьючерсов. Чудеса и их разоблачение

О чудесах календарного спреда фьючерсов уже доложено в статье некого 3Qu. smart-lab.ru/blog/586202.php

Поэтому сразу приступим к разоблачению. Какая проделана работа.
В Qukk'е на QLua написан монитор, который с 2020.01.17 по 2020.02.06 каждые 200 мсек записывал в текстовый файл офера и биды RIH0 и RIM0. Эти данные представлены как стандартный файл котировок Метастока, где Open = Bid(H0), High = Ask(H0), Low = Bid(M0), Close = Ask(M0).
Программа WealthLab показывает график этого файла, не понимая его значения. Но мой скрипт на C# по этим данным строит другие графики:

Диаграмма из WealthLab
Две точечные линии, зелёные и красные ступеньки, в середине центральной панели:
1) SpreadLong = Ask(H0) — Bid(M0).
2) SpreadShrt = Bid(H0) — Ask(M0).
По цене SpreadShrt приходится продавать спред фьючерсов, когда он дорог а по цене SpreadLong — покупать спред, когда он подешевл.
Чтобы определить, дорог спред или дёшев, строим скользящие средние  с горизонтом 10 мин (серые линии)
3) SmaLong.
4) SmaShrt.
Для наглядности проводим сверху и снизу две синие линии, сдвинутые на 30 руб, сконвертированные в пункты фьючерса.
5) UprLong.
6) LwrLong.
Если SpreadLong выше UprLong (на зелёном фоне), считаем фьючерс дорогим и пригодным к продаже.
Если SpreadShrt ниже LwrShrt (на розовом фоне), это случай для покупки.
Коды программ прилагаются.

Так вот, если вкратце, то чудесам мешают три обстоятельства.
Во-первых, средний за день спред котировок RIM0 составляет от 70 до 130 пунктов, т.е. от 0.05% до 0.09%. И это уже перекрывает сколь-нибудь доступный выигрыш от колебаний спреда.
Во-вторых, если кто захочет купить-продать выгоднее, чем в биды-офера, рискует промахнуться и остаться с одним фьючерсом, стоящим против рынка.
И в-третьих. Если спред фьючерсов пойдёт против открытой позиции, ожидание исправления рынка может оказаться слишком долгим и безнадёжным.
Колебания спреда фьючерсов вокруг теоретического равновесного уровня значительны и продолжительны. За 3 отмониторенных недели спред сходил от значения 1636 к 1516 и затем обратно к 1651. Так что говорить о «беспроигрышности» стратегии можно с большой натяжкой.

Значительный выигрыш во многие проценты за день возможен, если совершать сделки посередине между бидами и оферами. Но это доступно только волшебникам. У остальных такая удача будет столь редка, что не оправдает всей затеи.
А если играть по бидам и оферам, то каждый день интрадея будет убыток в несколько десятых процента.
Если кто захочет проверить работу скрипта WealthLab'а, могу почтой послать отмониторенные биды-офера. Они представлены как 1-минутные, чтобы WealthLab мог их сгруппировать от 10- до 60-минуток.
Скрипт-монитор QLua испоьзует также мои библиотечные скрипты SetPaths64.lu, QuikUtil(qu).lua, QuikConst(qc).lua и LuaUtil(lu).lu. Достаточно дееспособный программист сможет заменить их своим кодом.
Вот скрипт C# для WealthLab:
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms; // DialogResult
using WealthLab;
using WealthLab.Indicators;
//using mw  = MyWealth;
//using mwu = MyWealth.Utils;

namespace WealthLab.Strategies
{
public struct Arg {
public static double MinMoney = 30;   // Минимальный выигрыш в рублях
public static double ProfitFactor = 1;// Доля MinMoney для выхода из позиции
public static int PeriodMins = 10;    // Период SMA, минуты
public static TimeSpan TimeIni = new TimeSpan (10, 10, 0); // Начало игры
public static TimeSpan TimeBan = new TimeSpan (18, 00, 0); // Запрет входа
public static TimeSpan TimeFin = new TimeSpan (18, 40, 0); // Конец игры
}
public struct Data {
public static double SecPriceStep;// Шаг цены в пунктах фьючерса
public static double DealFee = 4; // Комиссия за сделку в рублях
public static double MinProfit;   // Минимальный выигрыш в пунктах
public static int PeriodBars;     // Период SMA, бары
}
   
public class CalendarSpreadTwo : WealthScript
{ 
  DataSeries SpreadLong, SpreadShrt, UprLong, LwrShrt;
  DataSeries SpreadMid, UprMid, LwrMid;
    
  protected override void Execute() {
    ClearDebug();
    if (! Bars.IsIntraday || ! Bars.Scale.Equals (BarScale.Minute)) {
      PrintDebug ("Bar.Scale Minute only!");
      return;
    }
    double stepPrice // Рублёвая цена для Data.SecPriceStep
     ,moneyMargin    // Среднее ГО контракта, руб
     ,moneyFct;      // Единица контракта, руб
    Prepare (out stepPrice, out moneyMargin, out moneyFct);
    //***
    Pos pos = new Pos();
    double win = 0; double ttlWin = 0;
    double minWin = Double.MaxValue; double maxWin = Double.MinValue;
    int bar = Data.PeriodBars; TimeSpan curTime = new TimeSpan (0);
    for ( ; ; ++bar) {
      curTime = new TimeSpan(Date[bar].Hour, Date[bar].Minute, 0);
      if (curTime < Arg.TimeIni)
        goto Next;
      //if (pos.Type == 1  && SpreadShrt[bar] >= UprShrt[bar] ||
      //    pos.Type == -1 && SpreadLong[bar] <= LwrLong[bar])
      if (ExitPos (
        bar, false, pos, ref win, ref minWin, ref maxWin, ref ttlWin))
        goto Next;
      if (curTime >= Arg.TimeBan || pos.Type != 0)
        goto Next;
      if (SpreadShrt[bar] < LwrShrt[bar]) {        // Покупаем
      //if (SpreadMid[bar] < LwrMid[bar]) {        // Покупаем
        EnterPos (1, bar, pos);
      } else if (SpreadLong[bar] > UprLong[bar]) { // Продаём
      //} else if (SpreadMid[bar] > UprMid[bar]) { // Продаём
        EnterPos (-1, bar, pos);
      }
      Next:          
        if (curTime >= Arg.TimeFin)
          break;
    } // for ( ; ; ++ bar
    ExitPos (bar, true, pos, ref win, ref minWin, ref maxWin, ref ttlWin);
    //***
    if (pos.PosNo > 0) {
      double margin = 2 * moneyMargin / moneyFct;
      double fee = Data.DealFee / moneyFct * pos.PosNo;
      double pct = (ttlWin - fee) / margin * 100;
      PrintDebug (String.Format("{0,-7};{1,-6};{2,-5};{3,-7};{4,-6};{5,-5}"
        ,"min", "max", "avr", "ttl", "fee", "pct"));
      PrintDebug (String.Format (
        "{0,7:F2};{1,6:F2};{2,5:F2};{3,7:F2};{4,6:F2};{5,5:F2}"
        ,minWin, maxWin, ttlWin / pos.PosNo,  ttlWin, fee, pct));
    }
  } // Execute()

  bool EnterPos (int type, int bar, Pos pos) {
    pos.Type = type;
    pos.EntryBar = bar;
    pos.EntryPrice = SpreadPrice (type, bar);
    pos.PosNo = pos.PosNo + 1;
    return true;
  } // EnterPos()

  double SpreadPrice (int buySell, int bar) {
    if (buySell == 1) {
      return SpreadLong[bar];
      //double ask1 = High[bar]; double bid2 = Low[bar];
      //return ask1 - bid2; // Для покупки спред дорог
    } else {
      return SpreadShrt[bar];
      //double bid1 = Open[bar]; double ask2 = Close[bar];
      //return bid1 - ask2; // Для продажи спред дёшев
    }
  }
    
  bool ExitPos (int bar, bool atOnce, Pos pos, ref double win
  ,ref double minWin, ref double maxWin, ref double ttlWin) {
    if (pos.Type == 0)
      return false;
    int newType = pos.Type == 1 ? -1 : 1;
    double exitPrice = SpreadPrice (newType, bar);
    bool mustExit = pos.Type == 1
      ? exitPrice >= pos.EntryPrice + Data.MinProfit * Arg.ProfitFactor
      : exitPrice + Data.MinProfit * Arg.ProfitFactor <= pos.EntryPrice;
    if (! mustExit && ! atOnce) return false;   
    pos.ExitBar = bar;
    pos.ExitPrice = exitPrice;
    win = 0;
    if (pos.Type == 1) // Продаём лонг
      win = pos.ExitPrice - pos.EntryPrice;
    else               // Откупаем шорт
      win = pos.EntryPrice - pos.ExitPrice;
    minWin = Math.Min (minWin, win);
    maxWin = Math.Max (maxWin, win);
    ttlWin += win;
    if (pos.PosNo == 1)     
      PrintDebug (
        String.Format ("{0,-4};{1,1}:{2,-6};{3,-6};{4,-7};{5,-7};{6,-7}"
        ,"nn","*", "nBar", "xBar", "nPrc", "xPrc", "win"));
    PrintDebug (String.Format (
      "{0,4};{1,1};{2,6};{3,6};{4,7:F2};{5,7:F2};{6,7:F2}"
      ,pos.PosNo, pos.Type == -1 ? "-" : "+", pos.EntryBar, pos.ExitBar
      ,pos.EntryPrice, pos.ExitPrice, win));
    pos.Type = 0;
     return true;
  } // ExitPos()
    
  void Prepare (out double stepPrice, out double moneyMargin
      ,out double moneyFct) {
    PrintDebug (StrategyName + " " + Bars.Symbol);
    Data.SecPriceStep = stepPrice = moneyMargin = moneyFct = 0;
    if (Bars.Symbol.Contains ("_OneOfBR")) {
      Data.SecPriceStep = 0.01;
      stepPrice   = 6.14629;
      moneyMargin    = 4700;
    } else if (Bars.Symbol.Contains ("_OneOfGD")) {
      Data.SecPriceStep = 0.1;
      stepPrice   = 6.29685;
      moneyMargin    = (7756.08+790879)/2;
    } else if (Bars.Symbol.Contains ("_OneOfRI")) {
      Data.SecPriceStep = 10;
      stepPrice   = 12.29258;
      moneyMargin    = 24000;
    } else if (Bars.Symbol.Contains ("_OneOfSi") ||
     Bars.Symbol.Contains ("_OneOfGZ")) {
      Data.SecPriceStep = 1;
      stepPrice   = 1;
      moneyMargin    = 4500;
      Data.DealFee = 3;
    } else if (Bars.Symbol.Contains ("_OneOfSR")) {
      Data.SecPriceStep = 1;
      stepPrice   = 1;
      moneyMargin    = 4500;
      Data.DealFee = 2.50;
    } else
      return;
    moneyFct = stepPrice / Data.SecPriceStep;
    Data.MinProfit = Arg.MinMoney / moneyFct;      
    SetPeriodBars();
    SpreadLong = High - Low;
    SpreadShrt = Open - Close;
    SpreadLong.Description = "SpeadLong";
    SpreadShrt.Description = "SpeadShrt";
    int m = Bars.Count-1;
    PrintDebug ("Spreads  " + SpreadLong[m] + " " + SpreadShrt[m]);
    PrintDebug ("HighLows " + High[m] + " " + Low[m]);
    DataSeries smaLong = SMA.Series (SpreadLong, Data.PeriodBars);
    smaLong.Description = "SmaLong";
    DataSeries smaShrt = SMA.Series (SpreadShrt, Data.PeriodBars);
    smaShrt.Description = "SmaShrt";
    UprLong = smaLong + Data.MinProfit;
    UprLong.Description = "UprLong";
    LwrShrt = smaShrt - Data.MinProfit;
    LwrShrt.Description = "LwrShrt";
    double avrLong = 0; double avrShrt = 0; double ofrbid = 0;
    for (int i = 0; i < Bars.Count; ++i) {
      avrLong += SpreadLong[i]; avrShrt += SpreadShrt[i];
      ofrbid += Close[i] - Low[i];
    }
    avrLong /= Bars.Count; avrShrt /= Bars.Count;
    ofrbid /= Bars.Count;
    int k = -23;
    PrintDebug (String.Format ("{0,"+k+"}{1,7:F2} ({2:F0} руб)"
      ,"Мин.выигрыш", Data.MinProfit, Arg.MinMoney));
    PrintDebug (String.Format ("{0,"+k+"}{1,7:F2}"
      ,"Профит-фактор", Arg.ProfitFactor));
    PrintDebug (String.Format ("{0,"+k+"}{1,7:F2}, пункты"
      ,"Шаг цены фьючерса", Data.SecPriceStep));
    PrintDebug (String.Format ("{0,"+(k+3)+"}{1,7}"
      ,"Период в минутах", Arg.PeriodMins));
    PrintDebug (String.Format ("{0,"+(k+3)+"}{1,7}"
      ,"Период в барах", Data.PeriodBars));
    PrintDebug (String.Format ("{0,"+k+"}{1,7:F2}"
      ,"Максимум лонг-спреда", SpreadLong.MaxValue));
    PrintDebug (String.Format ("{0,"+k+"}{1,7:F2}"
      ,"Минимум лонг-спреда", SpreadLong.MinValue));
    PrintDebug (String.Format ("{0,"+k+"}{1,7:F2}"
      ,"Максимум шорт-спреда", SpreadShrt.MaxValue));
    PrintDebug (String.Format ("{0,"+k+"}{1,7:F2}"
      ,"Минимум шорт-спреда", SpreadShrt.MinValue));
    PrintDebug (String.Format ("{0,"+k+"}{1,7:F2}"
      ,"Коридор лонг-спреда", SpreadLong.MaxValue - SpreadLong.MinValue));
    PrintDebug (String.Format ("{0,"+k+"}{1,7:F2}"
      ,"Коридор шорт-спреда", SpreadShrt.MaxValue - SpreadShrt.MinValue));
    PrintDebug (String.Format ("{0,"+k+"}{1,7:F2}"
      ,"Средний лонг-спред", avrLong));
    PrintDebug (String.Format ("{0,"+k+"}{1,7:F2}"
      ,"Средний шорт-спред", avrShrt));
    PrintDebug (String.Format ("{0,"+k+"}{1,7:F2}"
      ,"Средний офер-бид", ofrbid));
    ChartPane cpSpread = CreatePane (50, true, true);
    DrawLabel (cpSpread, "Spread");
    PlotSeries (cpSpread, smaLong, Color.Black, LineStyle.Solid, 1);
    PlotSeries (cpSpread, smaShrt, Color.Black, LineStyle.Solid, 1);
    if (Bars.BarInterval > 1) {
      DataSeries diff = smaLong - smaShrt;
      ChartPane cpDiff = CreatePane (25, true, true);
      PlotSeries (cpDiff, diff, Color.Gray, LineStyle.Histogram, 3);
      return;
    }
    PlotSeries (cpSpread, SpreadLong, Color.Green, LineStyle.Dots, 3);
    PlotSeries (cpSpread, SpreadShrt, Color.Red, LineStyle.Dots, 3);
    PlotSeries (cpSpread, UprLong, Color.Green, LineStyle.Solid, 1);
    PlotSeries (cpSpread, LwrShrt, Color.Red, LineStyle.Solid, 1);
    for (int i = 0; i < Data.PeriodBars-1; ++i) {
      UprLong[i] = UprLong[Data.PeriodBars-1];
      LwrShrt[i] = LwrShrt[Data.PeriodBars-1];
      SetSeriesBarColor (i, UprLong, Color.Empty);
      SetSeriesBarColor (i, LwrShrt, Color.Empty);
    }
    int upr = 0; int lwr = 0; int uprlwr = 0;
    for (int i = Data.PeriodBars-1; i < Bars.Count; ++i) {
      if (SpreadLong[i] >= UprLong[i] && SpreadShrt[i] > LwrShrt[i]) {
        SetPaneBackgroundColor (cpSpread, i, Color.LightGreen);
        ++upr;
      } else if (SpreadShrt[i] <= LwrShrt[i] && SpreadLong[i] < UprLong[i]) {
        SetPaneBackgroundColor (cpSpread, i, Color.Pink);
        ++lwr;
      } else if (SpreadLong[i] >= UprLong[i] && SpreadShrt[i]<= LwrShrt[i]) {
        SetPaneBackgroundColor (cpSpread, i, Color.LightYellow);
        ++uprlwr;
      }
    }
    int j = Bars.Count-10;
    AnnotateChart(cpSpread, SpreadLong[j].ToString()
      ,j, SpreadLong[j]+17, Color.Black);
    AnnotateChart(cpSpread, SpreadShrt[j].ToString()
      ,j, SpreadShrt[j]-7, Color.Red);
    k = -20;
    PrintDebug (String.Format ("{0,"+k+"}{1,7} ({2,5:F2}%)"
      ,"Пробоев вверх", upr
      ,100.0 * upr / (Bars.Count - Data.PeriodBars)));
    PrintDebug (String.Format ("{0,"+k+"}{1,7} ({2,5:F2}%)"
      ,"Пробоев вниз", lwr
      ,100.0 * lwr / (Bars.Count - Data.PeriodBars)));
    PrintDebug (String.Format ("{0,"+k+"}{1,7} ({2,5:F2}%)"
      ,"Пробоев вверх и вниз", uprlwr
      ,100.0 * uprlwr / (Bars.Count - Data.PeriodBars)));  

    SpreadMid = ((High + Open) - (Close + Low)) / 2;
    SpreadMid.Description = "SpreadMid";
    DataSeries smaMid = SMA.Series (SpreadMid, Data.PeriodBars);
    smaMid.Description = "SmaMid";
    ChartPane cpMid = CreatePane (25, true, true);
    DrawLabel (cpMid, "Mid");
    PlotSeries (cpMid, SpreadMid, Color.Black, LineStyle.Solid, 1);
    PlotSeries (cpMid, smaMid, Color.Blue, LineStyle.Solid, 1);
    UprMid = smaMid + Data.MinProfit;
    UprMid.Description = "UptMid";
    LwrMid = smaMid - Data.MinProfit;
    LwrMid.Description = "LwrMid";
    PlotSeries (cpMid, UprMid, Color.Green, LineStyle.Solid, 1);
    PlotSeries (cpMid, LwrMid, Color.Red, LineStyle.Solid, 1);
    for (int i = 0; i < Data.PeriodBars-1; ++i) {
      UprMid[i] = UprMid[Data.PeriodBars-1];
      LwrMid[i] = LwrMid[Data.PeriodBars-1];
      SetSeriesBarColor (i, UprMid, Color.Empty);
      SetSeriesBarColor (i, LwrMid, Color.Empty);
    }
    for (int i = Data.PeriodBars-1; i < Bars.Count; ++i) {
      if (SpreadMid[i] > UprMid[i])
        SetPaneBackgroundColor (cpMid, i, Color.LightGreen);
      else if (SpreadMid[i] < LwrMid[i])
        SetPaneBackgroundColor (cpMid, i, Color.Pink);
    }
  } // Prepare()
    
  void SetPeriodBars() {
      if (Bars.BarInterval > 1) { // Arg.PeriodMins) {
      Arg.PeriodMins = Bars.BarInterval;
      Data.PeriodBars = 1;
      return;
    }
    int barsPerMin = 60 * Int32.Parse (
      Bars.Symbol [Bars.Symbol.Length-1].ToString());
    Data.PeriodBars = Arg.PeriodMins * barsPerMin / Bars.BarInterval;
  }
} // class CalendarSpreadTwo
  
class Pos {
  public int Type = 0; // 1 - long, -1 - short
  public int EntryBar, ExitBar;
  public double EntryPrice, ExitPrice;
  public int PosNo = 0;
}  
} // namespace WealthLab.Strategies
Это головной скрипт монитора на QLua для Quik:
-- Мониторим котировки ближнего и дальнего фьючерсов по тикам
Data = { "RIH0", "RIM0" -- дорогой и дешёвый фьючерсы
 ,MsDlt = 200           -- период опроса очереди заявок, мсек
}
  
function OnInit (scriptPath)
dofile ("D:\\BAT\\Lua\\SetPaths64.lua")
Require { qu = "QuikUtil(qu)" } -- lu, qc, tu, wau
ScriptDir, ScriptName = lu.SplitPath (scriptPath)
end -- OnInit()

function OnStop (signal) -- 1 по кнопке Остановить
StopFlag = true          -- 2 при закрытии Quik'а
return 3000 -- Вместо стандартных 5 сек
end -- OnStop()

function main()
dofile (ScriptDir .."OneOf_Lib.lua")
local frame = MakeFrame() -- Неуклюжая идея. Исправить!!!
message (ScriptName ..": Start")
while not StopFlag and frame.HandleTick() do end
message (ScriptName ..": Quit")
end -- main()
А это его вспомогательный dofile:
-- dofile монитора котировок ближнего и дальнего фьючерсов по тикам
-- Константы
local Header =
"<TICKER>;<PER>;<DATE>;<TIME>;<OPEN>;<HIGH>;<LOW>;<CLOSE>;<VOL>"
local per = "1"
local tmBeg, tmEnd = "10000", "184500"
--local tmBeg, tmEnd = "00000", "235000"
-- Параметры: Data.MsDlt
-- Data[1],[2] -- дорогой и дешёвый фьючерсы, "BRG0", "BRH0" и т.п.
local ticker = Data[1] .."-".. Data[2]
-- Общие: Log, ScriptDir С конечным "\", ScriptName Без расширения
local ymd = os.date ("%Y%m%d", os.time())
local sfx = Data.MsDlt == 200 and 5 or
  Data.MsDlt == 500 and 2 or nil
if not sfx then error ("Invalid MsDlt", 2) end
Log = io.open (ScriptDir .."Log\\".. ymd .."_".. ScriptName
 .. sfx ..".csv", "w")
Log:write (Header)

function MakeFrame ()
local ask1, bid1, ask2, bid2, sprd
local frm = Data[1]:sub (1, 2) == "GD" and
     "%s;%s;%s;%s;%.1f;%.1f;%.1f;%.1f;%.2f"
  or Data[1]:sub (1, 2) == "BR" and
     "%s;%s;%s;%s;%.2f;%.2f;%.2f;%.2f;%.3f"
  or "%s;%s;%s;%s;%d;%d;%d;%d;%d" -- GZ, RI, Si, SR
local pre, no = os.time(), 0 -- Ловим начало секунды
local cur = pre
while cur == pre do sleep (1); cur = os.time() end
pre = cur
local m = {}

m.HandleTick = function()
  local tm = os.date ("%H%M%S", cur)
  if tm >= tmEnd then return false end
  if tm >= tmBeg then
    no = no + 1
    ask1 = qu.GetParamNum (qc.SPBFUT, Data[1], qc.OFFER)
    ask2 = qu.GetParamNum (qc.SPBFUT, Data[2], qc.OFFER)
    bid1 = qu.GetParamNum (qc.SPBFUT, Data[1], qc.BID)
    bid2 = qu.GetParamNum (qc.SPBFUT, Data[2], qc.BID)
    sprd = (ask1 + bid1) / 2 - (ask2 + bid2) / 2
    local msg = string.format (frm, ticker, per
      ,os.date ("%Y%m%d", cur), tm
      ,bid1, ask1, bid2, ask2, no)
    Log:write ("\n".. msg)
  end -- if tm >= tmBeg
  sleep (Data.MsDlt)
  cur = os.time()
  if cur > pre then
    Log:flush()
    pre, no = cur, 0
  end
  return true
end -- m.HandleTick()

return m
end -- MakeFrame()
★8
25 комментариев
Оч хорошо проделанная работа. Возможно, неверен сам подход к снаряду.
avatar
3Qu, «Возможно, неверен сам подход к снаряду.»

У Вас есть положительный опыт торговли этого календарника? Или это тоже только в теории на минутках?
avatar
quant_trader, мы же за теорию говорим? В теории это работает. Если у вас не работает — значит неправильная теория.
avatar
3Qu, не, я спрашиваю именно практический результат. Значит тут тоже только теория без практики?
avatar
quant_trader, я не вижу причин, почему теория не должна работать на практике. Если есть торгуемые контракты на ваших уровнях, почему бы некоторым из них не стать вашими.)
В опционах ликвидность похуже, но ведь торгуют и не жалуются.
avatar
Фишка в том, что 200млсек многовато для такого исследования. Чтобы была надежная доказательная база, дату надо прям по прямым протоколам получать
avatar
Андрей К, неправда ваша. Для такого, точнее -подобного, исследования минутных данных вполне достаточно.
avatar
3Qu, если вы говорите про минутки вообще, то теперь и у меня появились сомнения на счет правильности вашего топика.

upd. Хотя прошу прощение. Если ставка по маркету плавает, то между фучами да, ставка тоже поплывет
avatar
Андрей К, сомнения вас, возможно и правильные, но и в топике я далеко не все написал. Только саму идею, но не мануал.) Реализации могут быть оч разными.
avatar
3Qu, нет. В минутках между закрытием одного инструмента и другого может быть несколько секунд и вся теория по одному месту.
avatar
quant_trader, несколько секунд абсолютно ничему не мешают. Вы же HFT хотите.
avatar
3Qu, подожду когда у Вас появится практический опыт
avatar
quant_trader, вы об этом не узнаете.) Я не обсуждаю свои системы.
avatar
Андрей К, Мой брокер присылает в Quik'е сделку через 150-300 мсек после подачи заявки. Кроме того, из графика видно что биды-офера и спред фьючерсов не меняются чаще раза в 1 секунду. Так что ловить микросекунды нет смысла.
avatar
Rostislav Kudryashov, это в квике так видно. Квик может легко не показать, как бид/офер за секунду раз 20-30 может поменяться.
avatar
Андрей К, А у тебя торговый терминал установлен в Москве на сервере ММВБ? Очень интересно узнать подробнее.
Боюсь, мне это недоступно. Я играю через домашний ПК.
Оосновная проблема в том, что внутридневный размах движения спреда фьючерса (и в самые мелкие мксек, и за часы) сопоставим со спредом бидов-оферов дальнего фьючерса.
К тому же, чтобы не застревать надолго в позиции, надо угадывать направление движения спреда фьчерсов, что мне тоже не дано.
Характерная ситуация. В конце дня позиция застряла в убытке. Что делать? Переносить на следующий день и получить углубление убытка или рубить позицию с потерей дневной прибыли?
avatar
Rostislav Kudryashov, 
А у тебя торговый терминал установлен в Москве на сервере ММВБ?
Обычно делают не терминал, а приложение безо всякого графического интерфейса, которое выступает в роли контейнера для стратегий и шлюзов)
avatar
Eugene Logunov, о чем спорят уважаемые господа? Существует или нет в природе календарный арбитраж? Забабахайте сюда, пожалуйста, пару формул. Одной докажите, что существует, иначе даже определения такого не было бы, а другой докажите, что не существует, поскольку британские ученые уже давно выяснили, что мир иллюзорен и объективной реальности не существует… а то дискуссия как-то выдыхается.
avatar
Rostislav Kudryashov, 

привожу график по RTS-3.20 за 1 секунду, за которую было огромное количество возможностей, в том числе и календарного арбитража с RTS-6.20.



По RTS-3.20 за эту секунду проторговано более 5 тысяч лотов. 
По RTS-6.20 за этот же период проторговано 11 (одиннадцать!) лотов.
Где все арбитражеры то?

Дмитрий Овчинников, вообще, арбитражом занимаются немногие, и, в основном, профи. А 11 лотов/с — это оч. не мало. Сколько там в час? А за сессию?
avatar
3Qu, 
это не просто секунда. Это уникальная секунда. Если вы этого не видите на картинке, мне жаль.
Дмитрий Овчинников, не впечатляет. Ну, за 1 с столько же, как за последующие 100. И что это означает? Кому-то захотелось закупиться или запродаться на 5 тыс лотов. Событие вселенского масштаба.))
avatar
На московской бирже го на календарный спред по прежнему такое же как за сумму го двух фьючерсов?
avatar

теги блога Rostislav Kudryashov

....все тэги



UPDONW