Prop trading - est-ce une arnaque ou est-ce une bonne chose ? - page 9

 
prostotrader:

Au fait, comment comptez-vous rendre compte de ces 175 roubles ?

S'il est monté exactement 3 mois à l'avance et sorti à l'échéance, alors il faut déduire 350 roubles.

Parce que les frais de dépôt ne sont pris en compte que s'il y a un mouvement dans les actions (achat/vente).

Et si, pour une raison quelconque, vous êtes parti le même mois (ou êtes entré dans le mois d'expiration), vous ne devez déduire que 175 roubles.

Comment l'EE comprendra-t-elle le montant à déduire ?

Ajouté

Et puis, pour une paire (actions à terme), cela peut être un montant énorme, et pour 1000 paires - mizzero.

Tout dépend de la fréquence des situations d'échange. Je suis d'accord que pour un grand dépôt, 175p ne jouera pas un grand rôle. Mais tout le monde ne dispose pas d'un grand dépôt.

C'est juste que maintenant cette commission doit être prise en compte également.

 
Alexey Kozitsyn:

Tout dépend de la fréquence des situations de négociation. Je suis d'accord que 175p ne fera pas une grande différence sur un grand dépôt. Mais tout le monde ne dispose pas d'un grand dépôt.

Il ne nous reste plus qu'à prendre en compte cette commission.

Il est clair qu'il faut en tenir compte, mais comment ?

 
prostotrader:

Il est compréhensible d'en tenir compte, mais comment en tenir compte ?

Peut-être 175p une fois au moment de l'entrée. Ce qui implique que l'argent ne restera pas longtemps inactif et que pour le mois de sortie, il faudra à nouveau entrer.

 
Alexey Kozitsyn:

Peut-être 175p une fois au moment de l'entrée. Ce qui implique que l'argent ne restera pas longtemps inactif et devra entrer à nouveau pour le mois de sortie.

C'est logique, mais comment comptabiliser le bénéfice ?

C'est-à-dire que nous devons savoir combien de jours nous séparent de l'expiration et combien de contrats seront achetés,

c'est-à-dire que le % d'entrée est calculé pour 1 paire

Ajouté

Pour l'instant, j'ai décidé de faire ce qui suit :

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



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

C'est logique, mais comment comptabiliser les avantages ?

C'est-à-dire que vous devez savoir combien de jours avant l'expiration et combien de contrats seront achetés,

parce que le % d'entrée est calculé pour 1 paire

Ajouté

Pour l'instant, j'ai décidé de le faire :

Il existe une autre variante. Il suffit de faire de la commission du déposant un paramètre d'entrée. S'il y aura plusieurs positions en même temps, pour calculer la rentabilité de la première position avec la commission, et la deuxième et les positions suivantes dans ce mois - sans tenir compte de la commission.

 
prostotrader:

C'est logique, mais comment comptabiliser le bénéfice ?

C'est-à-dire que vous devez savoir combien de jours avant l'expiration et combien de contrats seront achetés,

parce que le % d'entrée est calculé sur 1 paire.

Oui, vous devez connaître le nombre de contrats et 175 divisé également par cette valeur. Encore une fois au cas où la commission n'aurait pas été prise en compte plus tôt dans le mois.

 

Cela donne quelque chose comme ça

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

Cela donne quelque chose comme ça

Je pense que, pour une étude complète et exhaustive du thème de l'arbitrage, nous devons faire l'affichage en deux vues : comme vous avez + ajouter une différence de millisecondes entre les mises à jour de l'information, ainsi que dans la vue chandelier, pour évaluer l'image globale de la rentabilité.

Approximativement comme ceci (calendrier pour l'huile) :


 
Alexey Kozitsyn:

Je crois que pour une étude complète et exhaustive de l'arbitrage, il faut afficher deux vues : comme la vôtre + ajouter une différence de quelques millisecondes entre les mises à jour de l'information, ainsi qu'une vue en chandelier pour évaluer l'image globale de la rentabilité.

Deux verres travaillent très rapidement, même sur des contrats à terme illiquides Les SPOTs "s'agitent" à grande vitesse

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

Ajouté

L'intérêt de la stratégie du "chasseur de Div" est que nous achetons sans risque des actions et vendons des contrats à terme.

Si nous attrapons un dividende, nous obtenons le dividende et le pourcentage auquel nous sommes entrés.

Le marché a été réglé depuis longtemps, et vous ne pouvez pas obtenir 10-15% au taux de la Banque centrale de 7,5% par an.

 
prostotrader:

Deux verres fonctionnent très rapidement, même dans les contrats à terme peu liquides Les SPOTs "s'agitent" à une vitesse énorme

Nous devons comprendre pour l'entrée si nous serons autorisés à entrer à de bons prix, c'est pourquoi nous avons besoin de ms (je crois). De même, il serait bon de voir la densité de la coupe en temps réel (pour les contrats à terme à long terme).