Como obter a "Porcentagem de Margem" de forma programática - página 7

 
K-2SO:

Testes mostram que quando a porcentagem da margem é igual a 1, a alavancagem não é levada em conta! Mas a partir de 100 e mais, já é levado em conta. Gostaria de poder encontrar um corretor com uma margem percentual entre 2 e 99 inclusive.

Algo está errado. A alavancagem é usada quando se calcula esta porcentagem a partir da margem em 1 lote padrão, e a alavancagem é levada em conta lá.

Compilar este roteiro e, se houver ordens abertas, executá-lo em qualquer 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));
}/********************************************************************/
Tenho apenas 2 pedidos abertos, mostra-se corretamente para eles.
 
Alexey Viktorov:

Algo está errado. A alavancagem é usada quando se conta essa porcentagem da margem em 1 lote padrão, e a alavancagem é levada em conta lá.

Compilar este roteiro e, se houver ordens abertas, executá-lo em qualquer par.

Tenho apenas 2 pedidos abertos, ele se mostra corretamente.

Já o fiz. No momento, o mercado está fechado em modo de demonstração e somente as encomendas de ouro estão abertas. Minhas palavras são confirmadas por insta (margem percentual:1) seu roteiro mostra algum tipo de espaço...

Não sei o que fazer com isso, mas tenho que calcular corretamente a porcentagem de margem em metaquotas e robôs com 100 e 200.

 
Renat Akhtyamov:
Abra uma conta demo com 5 libras e uma alavancagem de 100 e veja qual será a porcentagem da margem, por exemplo, a mesma para o ouro ou ainda mais engraçado - o rublo...
Não dominei o cálculo da margem percentual, a lógica dos cálculos parece ter sido compreendida, mas ainda não escrevi o código. Se você tem seu próprio, vamos verificar o que você está dizendo )
 
K-2SO:

Feito. Agora em minhas demonstrações, enquanto o mercado está fechado apenas com pedidos de ouro estão abertos. Minhas palavras são confirmadas por insta (margem percentual:1) seu roteiro mostra algum tipo de espaço... assim comoSYMBOL_CURRENCY_MARGIN

MetaQuotes e RoboQuotes onde a porcentagem de margem é 100 e 200, tudo está correto.

Eu não entendo o que mostra errado. Abri mais 2 pedidos de óleo onde o percentual de margem = 1 e o tamanho do contrato é de apenas 1000 e não 100.000 como para as moedas.

Isto é o que é impresso

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

Aqui está uma captura de tela


Por alguma razão, ele mostra o centavo exato.

Então, além das palavras, coloque imagens...

 
Alexey Viktorov:

Então, além das palavras, poste fotos...


Em algum lugar como este (lote 0,05, alavancagem 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:


Em algum lugar como este (lote 0,05, alavancagem 300):

Estou vendo. Preste atenção à moeda da margem. O meu é XAU e o seu é USD e então você tem que fazer algo com esta linha

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

para que a cotação seja incluída no cálculo. Talvez acrescente um caminho ao símbolo.

E para a dupla verificação, mudar esta linha assim

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

Mas neste caso não vai funcionar corretamente para as moedas.

Em geral, devemos considerar todas as variantes do caminho para o símbolo e todas as variantes de moedas de margem para a universalidade.

 
Alexey Viktorov:

Estou vendo. Preste atenção à moeda da margem. O meu é XAU e o seu é USD e então você tem que fazer algo com esta linha

para que a cotação seja incluída no cálculo. Talvez você devesse acrescentar um caminho ao símbolo.

Para verificar novamente, mude esta linha desta forma


Mesmo assim, não é correto, a ordem é a mesma, o resultado é o mesmo:

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:

Geralmente, todas as variantes do caminho para o símbolo e a moeda da margem devem ser levadas em conta para o bem da universalidade.

Eu vejo a moeda da margem, mas de que variantes do caminho para o símbolo estamos falando?


p.s. A fórmula sem alavancagem conta tudo com precisão:

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

Ainda errado, a mesma ordem, o mesmo resultado:

A moeda margem é clara, mas de que caminhos para o instrumento estamos falando?


p.s. De acordo com a fórmula sem alavancagem tudo é calculado com precisão:

Sim, eu estraguei um pouco... O tamanho do lote não é considerado de forma alguma. É mostrado corretamente porque meus pedidos são de 1 lote padrão. Eu deveria acrescentar esta linha

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

O caminho para o símbolo é definido da seguinte forma

SymbolInfoString(symbol, SYMBOL_PATH);

mas, infelizmente, não há nomes inequívocos, portanto, não é tão fácil definir a condição.

Robo, a demonstração da ecn tem esse caminho,


e em um centavo.

Outros podem ser semelhantes, mas não inequívocos. É claro que podemos comparar com o substrato, mas para ter certeza da universalidade, devemos verificar muitas corretoras.

Embora... você poderia tentar verificar a forma como a garantia é calculada.

Vou verificar isso agora.

 
Alexey Viktorov:

Sim, eu estraguei um pouco... O tamanho do lote não é levado em conta de forma alguma. Estou acertando porque os pedidos são de 1 lote padrão cada um. Eu deveria acrescentar esta linha.

Eu fiz, mas o resultado ainda está errado)

Alexey Viktorov:

O caminho para o símbolo é definido da seguinte forma

Quero dizer, como, onde e por que preciso usar este caminho?
 

Que chato... Verifique como isso conta para você.

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));
}/********************************************************************/
Fiz este para contar também as ordens pendentes, mas não inclui a margem total.
Razão: