Prop trading: ¿es una estafa o es bueno? - página 9

 
prostotrader:

Por cierto, ¿cómo propone contabilizar esos 175 rublos?

Si se trata de un contrato con 3 meses de antelación y que sale a su vencimiento, habrá que deducir 350 rublos.

Porque los gastos de depósito sólo se tienen en cuenta si hay movimiento en las acciones (compra/venta).

Y si por alguna razón te fuiste en el mismo mes (o entraste en el mes de vencimiento), entonces tienes que deducir sólo 175 rublos.

¿Cómo entenderá la EA cuánto debe deducir?

Añadido

Y entonces, para un par (Acciones de Futuros) puede ser una cantidad enorme, y para 1000 pares - mizzero.

Todo depende de la frecuencia de las situaciones comerciales. Estoy de acuerdo en que para un gran depo 175p no jugará un gran papel. Pero no todo el mundo tiene una gran deposición.

Es que ahora también hay que tener en cuenta esta comisión.

 
Alexey Kozitsyn:

Todo depende de la frecuencia con la que se produzcan las situaciones comerciales. Estoy de acuerdo en que 175p no hará mucha diferencia en una gran depo. Pero no todo el mundo tiene una gran deposición.

Ahora sólo hay que tener en cuenta esta comisión.

Está claro que hay que tenerlo en cuenta, pero ¿cómo?

 
prostotrader:

Es comprensible tenerlo en cuenta, pero ¿cómo tenerlo en cuenta?

Tal vez 175p una vez en el momento de la entrada. Lo que implica que el dinero no estará inactivo durante mucho tiempo y tendrá que volver a entrar para el mes de salida.

 
Alexey Kozitsyn:

Tal vez 175p una vez en el momento de la entrada. Lo que implica que el dinero no estará inactivo durante mucho tiempo y tendrá que volver a entrar para el mes de salida.

Tiene sentido, pero entonces ¿cómo se explica el beneficio?

Es decir, necesitamos saber cuántos días faltan para el vencimiento y cuántos contratos se comprarán,

es decir, el % de entrada se calcula para 1 par

Añadido

Por ahora he decidido hacer lo siguiente:

deponalog:= Settings.DepoNalog/(Settings.MaxFut * ExpData.FutData.Lot);
Settings.DepoNalog - 175 руб.



Settings.MaxFut - Предполагаемое кол-во фьючерсов продажи (на скрине 100)
ExpData.FutData.Lot - кол-во акций во фьючерсе
 
prostotrader:

Tiene sentido, pero entonces ¿cómo se contabilizan los beneficios?

Es decir, necesita saber cuántos días faltan para el vencimiento y cuántos contratos se van a comprar,

porque el % de entrada se calcula para 1 par

Añadido

Por ahora he decidido hacerlo:

Hay una variante más. Sólo hay que hacer que la comisión del depositante sea un parámetro de entrada. Si habrá varias posiciones al mismo tiempo, para calcular la rentabilidad de la primera posición con la comisión, y la segunda y siguientes posiciones en este mes - sin tener en cuenta la comisión.

 
prostotrader:

Tiene sentido, pero entonces ¿cómo se contabilizan los beneficios?

Es decir, necesita saber cuántos días faltan para el vencimiento y cuántos contratos se van a comprar,

porque el % de entrada se calcula sobre 1 par.

Sí, hay que saber el número de contratos y 175 divididos igualmente por ese valor. De nuevo, en caso de que la comisión no se haya tenido en cuenta a principios de mes.

 

Es algo así como

//+------------------------------------------------------------------+
//|                                                    SPOTvsFUT.mq5 |
//|                                     Copyright 2019, prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Label1
#property indicator_label1  "Input %"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrLime
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Label2
#property indicator_label2  "Output %"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrAqua
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//---
#define  on_call -111
#define  YEAR    365
//---
input double StCB     = 7.5;    //Ставка ЦБ(%)
input double BBSpot   = 0.025;  //Брокер и Биржа СПОТ(%)
input double BrFut    = 0.24;   //Брокер ФОРТС(руб.)
input double BiFut    = 0.0066; //Биржа ФОРТС(%) 
input double BrExp    = 1.0;    //Брокер за эксп.(руб.) 
input double BiExp    = 2.0;    //Биржа за зксп.(руб.)
input double Div      = 0;      //Дивиденты(руб./акция)
input double NalogDiv = 13;     //Налог на дивиденты(%)
input double NalDepo  = 175;    //Комиссия депозитария (руб./мес.)
input long   NFut     = 100;    //Передп. кол-во фьючерсов к продаже
input int    aBars    = 40;     //Мин. Баров на графике  
//---
struct MARKET_DATA
{
  int exp_day;
  double spot_ask;
  double spot_bid;
  double fut_ask;
  double fut_bid;
  double fut_lot;
  double go_sell;
  double go_buy;
};
//---
string spot_symbol;
int event_cnt;
MARKET_DATA ma_data;
double inBuff[], outBuff[];
bool spot_book, fut_book;

//+------------------------------------------------------------------+
//| Custom indicator Get Spot name function                          |
//+------------------------------------------------------------------+
string GetSpot(const string fut_name)
{
  string Spot = ""; 
  if(fut_name != "")
  {
    int str_tire = StringFind(fut_name, "-");
    if(str_tire > 0)
    {
      Spot = StringSubstr(fut_name, 0, str_tire);
      if(Spot == "GAZR") Spot = "GAZP"; else
      if(Spot == "SBRF") Spot = "SBER"; else
      if(Spot == "SBPR") Spot = "SBERP"; else
      if(Spot == "TRNF") Spot = "TRNFP"; else
      if(Spot == "NOTK") Spot = "NVTK"; else
      if(Spot == "MTSI") Spot = "MTSS"; else
      if(Spot == "GMKR") Spot = "GMKN"; else
      if(Spot == "SNGR") Spot = "SNGS"; else
      if(Spot == "Eu")   Spot = "EURRUB_TOD"; else
      if(Spot == "Si")   Spot = "USDRUB_TOD"; else
      if(Spot == "SNGP") Spot = "SNGSP";
    }
  }  
  return(Spot);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
  int t_bars = Bars(Symbol(), PERIOD_CURRENT);
  if(t_bars < (aBars + 2))
  {
    Alert("Не хватает баров на графике!");
    return(INIT_FAILED);
  }
  event_cnt = 0;
//---
  spot_symbol = GetSpot(Symbol());
  if(spot_symbol == "")
  {
    Alert("Не получено имя СПОТа!");
    return(INIT_FAILED);
  }
  else
  {
    if(SymbolSelect(spot_symbol, true) == false)
    {
      Alert("Нет смвола с именем " + spot_symbol + "!");
      return(INIT_FAILED);
    }
    else
    {
      spot_book = MarketBookAdd(spot_symbol);
      if(spot_book == false)
      {
        Alert("Не добавлен стакан СПОТа!");
        return(INIT_FAILED);
      }
    }
  }
  fut_book = MarketBookAdd(Symbol());
  if(spot_book == false)
  {
    Alert("Не добавлен стакан фьючерса!");
    return(INIT_FAILED);
  }   
  IndicatorSetInteger(INDICATOR_DIGITS, 2);
  IndicatorSetString(INDICATOR_SHORTNAME, "SPOTvsFUT");
//---  
  SetIndexBuffer(0, inBuff, INDICATOR_DATA);
  PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
  ArraySetAsSeries(inBuff, true); 
  
  SetIndexBuffer(1, outBuff, INDICATOR_DATA);
  PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
  ArraySetAsSeries(outBuff, true);
  
    int window=ChartWindowFind(ChartID(),"SPOTvsFUT");
  ObjectCreate(ChartID(),"SPOTvsFUT_1",OBJ_LABEL,window,0,0);
  ObjectSetInteger(ChartID(),"SPOTvsFUT_1",OBJPROP_YDISTANCE,15);
  ObjectSetInteger(ChartID(),"SPOTvsFUT_1",OBJPROP_XDISTANCE,5);
  ObjectSetInteger(ChartID(),"SPOTvsFUT_1",OBJPROP_COLOR,clrLime);
  ObjectSetString(ChartID(),"SPOTvsFUT_1",OBJPROP_TEXT,"Input: 0");  

  ObjectCreate(ChartID(),"SPOTvsFUT_2",OBJ_LABEL,window,0,0);
  ObjectSetInteger(ChartID(),"SPOTvsFUT_2",OBJPROP_YDISTANCE,30);
  ObjectSetInteger(ChartID(),"SPOTvsFUT_2",OBJPROP_XDISTANCE,5);
  ObjectSetInteger(ChartID(),"SPOTvsFUT_2",OBJPROP_COLOR,clrAqua);
  ObjectSetString(ChartID(),"SPOTvsFUT_2",OBJPROP_TEXT,"Output: 0");
//---  
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
// Custom indicator DeInit function                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  ObjectDelete(ChartID(),"SPOTvsFUT_1");
  ObjectDelete(ChartID(),"SPOTvsFUT_2");
  if(fut_book == true) MarketBookRelease(Symbol());
  if(spot_book == true) MarketBookRelease(spot_symbol);
  if(reason == REASON_INITFAILED)
  {
    Print("Индикатор удалён! Причина - ошибка инициализации.");
    string short_name = ChartIndicatorName(ChartID(), 1, 0);
    ChartIndicatorDelete(ChartID(), 1, short_name); 
  }
}
//+------------------------------------------------------------------+
//| Custom indicator Get expiration  function                        |
//+------------------------------------------------------------------+   
int GetExpiration(const string aSymbol)
{
  MqlDateTime ExpData, CurData;
  datetime expir_time = datetime(SymbolInfoInteger(aSymbol, SYMBOL_EXPIRATION_TIME));
  TimeToStruct(expir_time, ExpData);
  TimeTradeServer(CurData);
  if(ExpData.year != CurData.year)
  {
    return(YEAR * (ExpData.year - CurData.year) - CurData.day_of_year + ExpData.day_of_year);
  }
  else
  {
    return(ExpData.day_of_year - CurData.day_of_year);
  }
}
//+------------------------------------------------------------------+
// Custom indicator On book event function                           |
//+------------------------------------------------------------------+
void OnBookEvent(const string& symbol)
{
  if((symbol == Symbol()) || (symbol == spot_symbol))
  {
    ma_data.exp_day  = GetExpiration(Symbol());
    ma_data.fut_ask  = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
    ma_data.fut_bid  = SymbolInfoDouble(Symbol(), SYMBOL_BID);
    ma_data.fut_lot  = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_CONTRACT_SIZE);
    ma_data.go_sell  = SymbolInfoDouble(Symbol(), SYMBOL_MARGIN_INITIAL);
    ma_data.go_buy  = SymbolInfoDouble(Symbol(), SYMBOL_MARGIN_MAINTENANCE);
    ma_data.spot_ask = SymbolInfoDouble(spot_symbol, SYMBOL_ASK);
    ma_data.spot_bid = SymbolInfoDouble(spot_symbol, SYMBOL_BID);
//---    
    double price[]; 
    OnCalculate(event_cnt, event_cnt, on_call, price); 
  }
}
//+------------------------------------------------------------------+
// Custom indicator Calc In Value function                           |
//+------------------------------------------------------------------+
double CalcInValue()
{
  double depocomiss = NalDepo/(NFut * ma_data.fut_lot);
  double comiss = ma_data.spot_ask * ma_data.fut_lot * BBSpot/100 * 2 +
                  BrFut + BiFut * ma_data.fut_bid/100 + BrExp + BiExp;
  double divNalog = Div/100 * 13;
  double divWaite = 0;
  if(Div > 0) divWaite = ((Div - divNalog) * ma_data.fut_lot * 13/100/365 * 20);
  //--- TODO ---
  return(0);
}
//+------------------------------------------------------------------+
// Custom indicator Calc Out Value function                          |
//+------------------------------------------------------------------+
double CalcOutValue()
{
  double comiss = ma_data.spot_bid * ma_data.fut_lot * BBSpot/100 +
                   BrFut + BiFut * ma_data.fut_ask/100;
  //--- TODO ---
  return(0);

}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
  if(prev_calculated == 0)
  {
    ArrayInitialize(inBuff, EMPTY_VALUE);
    ArrayInitialize(outBuff, EMPTY_VALUE);
  }  
//---  
  if(begin == on_call)
  {
    for(int i = aBars - 1; i > 0; i--)
    {
      inBuff[i] = inBuff[i - 1];
      outBuff[i] = outBuff[i - 1];
    }
    inBuff[0] = CalcInValue(); 
    outBuff[0] = CalcOutValue();
  }
  else
  {
    inBuff[0] = inBuff[1];
    outBuff[0] = outBuff[1];
  }
  inBuff[aBars] = EMPTY_VALUE;
  outBuff[aBars] = EMPTY_VALUE;
  ObjectSetString(ChartID(),"SPOTvsFUT_1",OBJPROP_TEXT,"Input: " + DoubleToString(inBuff[0], 2));
  ObjectSetString(ChartID(),"SPOTvsFUT_2",OBJPROP_TEXT,"Output: " + DoubleToString(outBuff[0], 2));
  ChartRedraw(ChartID());
//--- return value of prev_calculated for next call
  event_cnt = rates_total;
  return(rates_total);
}
//+------------------------------------------------------------------+
 
prostotrader:

Es algo así como

Creo que para un estudio completo y exhaustivo del tema del arbitraje, hay que hacer la visualización en dos vistas: como tienes + añadir una diferencia de milisegundos entre las actualizaciones de la información, así como en la vista de velas, para evaluar el panorama general de la rentabilidad.

Aproximadamente así (calendario para el aceite):


 
Alexey Kozitsyn:

Creo que para un estudio completo y exhaustivo del arbitraje, deberíamos mostrar dos vistas: como la suya + añadir una diferencia de milisegundos entre las actualizaciones de la información, así como una vista de velas para evaluar el panorama general de la rentabilidad.

Dos vasos trabajan muy rápido, incluso en futuros sin liquidez Los puntos se "agitan" con gran velocidad

if((symbol == Symbol()) || (symbol == spot_symbol))

Añadido

El objetivo de la estrategia "Div hunter" es que compremos acciones y vendamos futuros sin riesgo.

Si cogemos un dividendo, obtenemos el dividendo y el porcentaje al que entramos.

El mercado hace tiempo que está asentado, y no se puede conseguir un 10-15% al tipo del Banco Central del 7,5% anual.

 
prostotrader:

Dos vasos trabajan muy rápido, incluso en futuros con poco líquido Los puntos se "agitan" a una velocidad tremenda

Necesitamos entender para la entrada si se nos permitirá entrar a buenos precios, por eso necesitamos ms (creo). Además, sería bueno ver la densidad de la copa en tiempo real (para futuros de largo alcance).

Razón de la queja: