Prop trading - è una truffa o è buono? - pagina 9

 
prostotrader:

A proposito, come propone di giustificare questi 175 rubli?

Se è su esattamente 3 mesi in anticipo e fuori alla scadenza, allora 350 rubli dovrebbero essere dedotti.

Perché i costi di deposito sono presi in considerazione solo se c'è un movimento delle azioni (acquisto/vendita).

E se per qualche motivo hai lasciato nello stesso mese (o sei entrato nel mese di scadenza), allora devi dedurre solo 175 rubli.

Come farà l'EA a capire quanto dedurre?

Aggiunto

E poi, per una coppia (Azioni Futures) può essere una quantità enorme, e per 1000 coppie - mizzero.

Tutto dipende dalla frequenza delle situazioni di trading. Sono d'accordo che per un grande depo 175p non avrà un grande ruolo. Ma non tutti hanno un grande depo.

È solo che ora anche questa commissione deve essere presa in considerazione.

 
Alexey Kozitsyn:

Tutto dipende dalla frequenza con cui si presentano le situazioni di trading. Sono d'accordo che 175p non farà molta differenza su un grande deposito. Ma non tutti hanno un grande depo.

Ora dobbiamo solo prendere in considerazione questa commissione.

È chiaro che bisogna tenerne conto, ma come?

 
prostotrader:

È comprensibile tenerne conto, ma come tenerne conto?

Forse 175p una volta al momento dell'ingresso. Implica che il denaro non sarà inattivo per molto tempo e per il mese di uscita si dovrà entrare di nuovo.

 
Alexey Kozitsyn:

Forse 175p una volta al momento dell'ingresso. Implicando che il denaro non sarà inattivo per molto tempo e dovrà entrare di nuovo per il mese di uscita.

Ha senso, ma allora come si spiega il beneficio?

Cioè abbiamo bisogno di sapere quanti giorni mancano alla scadenza e quanti contratti saranno acquistati,

cioè la voce % è calcolata per 1 coppia

Aggiunto

Per ora ho deciso di fare quanto segue:

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



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

Ha senso, ma allora come si spiega il beneficio?

Cioè devi sapere quanti giorni mancano alla scadenza e quanti contratti saranno acquistati,

perché la voce % è calcolata per 1 coppia

Aggiunto

Per ora ho deciso di farlo:

C'è un'altra variante. Basta rendere la commissione del depositante un parametro di input. Se ci saranno diverse posizioni allo stesso tempo, per calcolare la redditività della prima posizione con la commissione, e la seconda e le posizioni successive in questo mese - senza prendere in considerazione la commissione.

 
prostotrader:

Ha senso, ma allora come si fa a contabilizzare i benefici?

Cioè devi sapere quanti giorni mancano alla scadenza e quanti contratti saranno acquistati,

perché la voce % è calcolata su 1 coppia.

Sì, è necessario conoscere il numero di contratti e 175 equamente diviso per quel valore. Sempre nel caso in cui la commissione non sia stata presa in considerazione all'inizio del mese.

 

Va più o meno così

//+------------------------------------------------------------------+
//|                                                    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:

Va più o meno così

Penso che, per uno studio completo ed esaustivo dell'argomento arbitraggio, abbiamo bisogno di fare la visualizzazione in due viste: come hai + aggiungere una differenza di millisecondi tra gli aggiornamenti di informazioni, così come in vista candlestick, per valutare il quadro complessivo della redditività.

All'incirca così (calendario per l'olio):


 
Alexey Kozitsyn:

Credo che per uno studio completo ed esaustivo dell'arbitraggio, abbiamo bisogno di visualizzare due viste: come la tua + aggiungere una differenza di millisecondi tra gli aggiornamenti delle informazioni, così come una vista candlestick per valutare il quadro complessivo della redditività.

Due bicchieri lavorano molto velocemente, anche su futures illiquidi Gli SPOT stanno "fluttuando" con grande velocità

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

Aggiunto

Il punto della strategia "Div hunter" è che compriamo senza rischi azioni e vendiamo futures.

Se prendiamo un dividendo, otteniamo il dividendo e la percentuale alla quale siamo entrati.

Il mercato è da tempo assestato, e non si può ottenere il 10-15% al tasso della Banca Centrale del 7,5% annuo.

 
prostotrader:

Due bicchieri lavorano molto velocemente, anche in futures a basso contenuto di liquido gli SPOT "sbattono" ad una velocità incredibile

Abbiamo bisogno di capire per l'ingresso se ci sarà permesso di entrare a buoni prezzi, ecco perché abbiamo bisogno di ms (credo). Inoltre, sarebbe bello vedere la densità della tazza in tempo reale (per i futures a lungo raggio).