Cómo obtener el "Porcentaje de margen" mediante programación - página 7

 
K-2SO:

Las pruebas muestran que cuando el porcentaje de margen es igual a 1, ¡el apalancamiento no se tiene en cuenta! Pero cuando es de 100 y más, ya se tiene en cuenta. Me gustaría encontrar un corredor con un porcentaje de margen entre 2 y 99 inclusive.

Algo está mal. El apalancamiento se utiliza cuando se calcula este porcentaje a partir del margen sobre 1 lote estándar, y ahí se tiene en cuenta el apalancamiento.

Compile este script y si hay órdenes abiertas ejecútelo en cualquier par.

void OnStart()
{
 double size = 0, percentage = 0, orderMargin = 0, accountMargin = 0;
 long leverage = 0;
 for(int i = 0; i < OrdersTotal(); i++)
  {
   int tupe = -1;
   if(OrderSelect(i, SELECT_BY_POS) && (tupe=OrderType()) < OP_BUYLIMIT)
    {
     string symbol = OrderSymbol();
     string symbolCurencyMargin = SymbolInfoString(symbol, SYMBOL_CURRENCY_MARGIN);
     double orderOpenPrice = OrderOpenPrice();
     double margin = MarketInfo(symbol, MODE_MARGINREQUIRED);
     double ask = MarketInfo(symbol, MODE_ASK);
     double bid = MarketInfo(symbol, MODE_BID);
     double price = symbolCurencyMargin == "USD" ? 1 : tupe == OP_BUY ? bid : ask;
      size = SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE);
      leverage = AccountInfoInteger(ACCOUNT_LEVERAGE);
      percentage = NormalizeDouble(margin/(size*price/100)*leverage, 0);
      orderMargin = (size*orderOpenPrice*percentage/100)/leverage;
      accountMargin += orderMargin;
      Print(symbolCurencyMargin, " ******** Маржа ", symbol, " = ", orderMargin);
    }
  }
 Print(AccountInfoString(ACCOUNT_CURRENCY), " ******** AccountMargin = ", DoubleToString(accountMargin, 2));
}/********************************************************************/
Sólo tengo 2 pedidos abiertos, se muestra correctamente para ellos.
 
Alexey Viktorov:

Algo está mal. El apalancamiento se utiliza cuando se cuenta ese porcentaje del margen sobre 1 lote estándar, y ahí se tiene en cuenta el apalancamiento.

Compile este script y si hay órdenes abiertas ejecútelo en cualquier par.

Sólo tengo 2 órdenes abiertas, se muestra correctamente.

Lo he hecho. En estos momentos el mercado está cerrado en modo demo y sólo están abiertas las órdenes sobre el oro. Mis palabras son confirmadas por insta (porcentaje de margen:1) su escritura muestra algún tipo de espacio...

No sé qué hacer con él, pero tengo que calcular correctamente el porcentaje de margen en las metacotizaciones y las del robot con 100 y 200.

 
Renat Akhtyamov:
Abra una cuenta de demostración con 5 libras y un apalancamiento de 100 y vea cuál será el porcentaje de margen, por ejemplo, el mismo para el oro o, aún más divertido, el rublo...
No domino el cálculo del margen porcentual, la lógica de los cálculos parece haber sido entendida, pero aún no he escrito el código. Si tienes la tuya, vamos a comprobar lo que dices )
 
K-2SO:

Hecho. Ahora en mis demos mientras el mercado está cerrado sólo en las órdenes de oro están abiertas. Mis palabras son confirmadas por insta (porcentaje de margen:1) su escritura muestra algún tipo de espacio... tambiénSYMBOL_CURRENCY_MARGIN

MetaQuotes y RoboQuotes donde el porcentaje de margen es 100 y 200, todo es correcto.

No entiendo lo que muestra mal. Abrí 2 órdenes más para el petróleo donde el porcentaje de margen = 1 y el tamaño del contrato es sólo 1000 y no 100.000 como para las divisas.

Esto es lo que se imprime

2017.06.05 08:40:04.978 test EURUSD.e,H1: USD ******** AccountMargin = 2207.23
2017.06.05 08:40:03.360 test EURUSD.e,H1: US_ ******** Маржа BRENT = 508.0
2017.06.05 08:39:34.326 test EURUSD.e,H1: US_ ******** Маржа WTI = 484.9
2017.06.05 08:39:25.185 test EURUSD.e,H1: XAU ******** Маржа XAUUSD.e = 840.4333333333334
2017.06.05 08:39:19.651 test EURUSD.e,H1: EUR ******** Маржа EURUSD.e = 373.8933333333333

Aquí hay una captura de pantalla


Por alguna razón, lo muestra al centavo más cercano.

Así que, aparte de las palabras, ponga imágenes...

 
Alexey Viktorov:

Así que, además de las palabras, ponga fotos...


Algo así (lote 0,05, apalancamiento 300):

2017.06.05 12:06:11.968 Script gold_test_vik XAUUSD,H1: removed
2017.06.05 12:06:11.953 gold_test_vik XAUUSD,H1: uninit reason 0
2017.06.05 12:06:11.953 gold_test_vik XAUUSD,H1: USD ******** AccountMargin = 8193395.74
2017.06.05 12:06:11.953 gold_test_vik XAUUSD,H1: USD ******** Маржа XAUUSD = 8193395.736
2017.06.05 12:06:11.953 gold_test_vik XAUUSD,H1: initialized
2017.06.05 12:06:11.937 Script gold_test_vik XAUUSD,H1: loaded successfully

 
K-2SO:


Algo así (lote 0,05, apalancamiento 300):

Ya veo. Preste atención a la moneda del margen. El mío es XAU y el tuyo es USD y entonces tienes que hacer algo con esta línea

double price = symbolCurencyMargin == "USD" ? 1 : tupe == OP_BUY ? bid : ask;

para que la cotización se incluya en el cálculo. Quizás añadir una ruta al símbolo.

Y para la doble comprobación cambiar esta línea así

double price = tupe == OP_BUY ? bid : ask;

Pero en este caso no funcionará correctamente para las monedas.

En general, debemos considerar todas las variantes de camino al símbolo y todas las variantes de monedas de margen para la universalidad.

 
Alexey Viktorov:

Ya veo. Preste atención a la moneda del margen. El mío es XAU y el tuyo es USD y entonces tienes que hacer algo con esta línea

para que la cotización se incluya en el cálculo. Tal vez deberías añadir una ruta al símbolo.

Para comprobarlo de nuevo, cambie esta línea así


De todos modos, no es correcto, el orden es el mismo, el resultado es el mismo:

2017.06.05 12:47:50.984 gold_test_vik XAUUSD,H1: USD ******** AccountMargin = 6392.70
2017.06.05 12:47:50.984 gold_test_vik XAUUSD,H1: USD ******** Маржа XAUUSD = 6392.7
Alexey Viktorov:

Por lo general, todas las variantes de la ruta hacia el símbolo y la moneda del margen deben tenerse en cuenta en aras de la universalidad.

La divisa del margen está clara, pero ¿de qué variantes del camino hacia el símbolo estamos hablando?


p.d. La fórmula sin palanca cuenta todo con precisión:

margin=(OrderLots()*contract*OrderOpenPrice())/100*Percentage; // инста - процент маржи 1% 
 
K-2SO:

Sigue estando mal, el mismo orden, el mismo resultado:

La moneda de los márgenes está clara, pero ¿de qué caminos hacia el instrumento estamos hablando?


p.d. Según la fórmula sin apalancamiento todo está calculado con precisión:

Sí, me he equivocado un poco... El tamaño del lote no se tiene en cuenta en absoluto. Se muestra correctamente porque mis pedidos son de 1 lote estándar... Debería añadir esta línea

orderMargin = (OrderLots()* size*orderOpenPrice*percentage/100)/leverage;

La ruta de acceso al símbolo se define de la siguiente manera

SymbolInfoString(symbol, SYMBOL_PATH);

pero, por desgracia, no hay una denominación inequívoca, por lo que no es tan fácil establecer la condición.

Robo, la demo de ecn tiene ese camino,


y en un céntimo.

Otros pueden ser similares, pero no inequívocos. Por supuesto, podemos comparar con la subcadena, pero para estar seguros de la universalidad deberíamos comprobar muchas empresas de corretaje.

Aunque... podría intentar comprobar la forma en que se calculan las garantías.

Lo comprobaré ahora.

 
Alexey Viktorov:

Sí, me he equivocado un poco... El tamaño del lote no se tiene en cuenta en absoluto. Lo estoy entendiendo bien porque los pedidos son de 1 lote estándar cada uno... Debería añadir esta línea.

Lo hice, pero el resultado sigue siendo erróneo)

Alexey Viktorov:

La ruta de acceso al símbolo se define de la siguiente manera

Es decir, ¿cómo, dónde y por qué necesito utilizar esta vía?
 

Qué dolor de cabeza... Comprueba cómo cuenta para ti.

void OnStart()
{
 double contractSize = 0, orderMargin = 0, accountMargin = 0; double percentage = 0;
 long leverage = 0;
 for(int i = 0; i < OrdersTotal(); i++)
  {
   int type = -1;
   if(OrderSelect(i, SELECT_BY_POS))
    {
      type = OrderType();
     string symbol = OrderSymbol();
     string symbolCurencyMargin = SymbolInfoString(symbol, SYMBOL_CURRENCY_MARGIN);
     double orderLots = OrderLots();
      leverage = AccountInfoInteger(ACCOUNT_LEVERAGE);
     double margin = MarketInfo(symbol, MODE_MARGINREQUIRED);
     double ask = MarketInfo(symbol, MODE_ASK);
     double bid = MarketInfo(symbol, MODE_BID);
     int calcMode = int(SymbolInfoInteger(symbol, SYMBOL_TRADE_CALC_MODE));
     int stringFind = StringFind(symbol, "USD");
     double price = stringFind == 0 ? 1 : type%2 == OP_BUY ? bid : ask;
     double orderOpenPrice = stringFind == 0 ? 1 : OrderOpenPrice();
      contractSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE);
      percentage = NormalizeDouble(margin/(contractSize*price/100)*(calcMode == 0 ? leverage : 1), 0);
      orderMargin = (orderLots*contractSize*orderOpenPrice*percentage/100)/(calcMode == 0 ? leverage : 1);
       Print("******** Процент маржи ", int(percentage), " Маржа ордера ", symbol, " ", orderLots, " = ", orderMargin);
      if(type < OP_BUYLIMIT)
       accountMargin += orderMargin;
    }
  }
 Print("******** AccountMargin = ", DoubleToString(accountMargin, 2)," ", AccountInfoString(ACCOUNT_CURRENCY));
}/********************************************************************/
Hice este para contar los pedidos pendientes también, pero no incluye el margen total.
Razón de la queja: