Good afternoon
Please tell me the formulas for calculating these functions. In particular, we are interested in what happens with crosses – for example, there is an account in USD, and a position is opened on EURGBP.
Also, using the formula OrderCalcProfit (), I would like to calculate Volume and Profit.
Thanks
OrderCalcMargin () and OrderCalcProfit () calculation formulas
Share
teetrinker
Some time has passed, and the formula for calculating OrderCalcProfit() is still not exactly known. Found the code GetOrderProfit (), the result is slightly different:
double GetOrderProfit(ENUM_ORDER_TYPE action, string symbol, double volume, double price_open, double price_close){
double tickValue=SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE);
double profit = NULL;
if ( action == ORDER_TYPE_BUY || action == ORDER_TYPE_BUY_LIMIT || action == ORDER_TYPE_BUY_STOP ) {
profit = (price_close - price_open) * volume * tickValue / _Point;
return profit;
}
else if ( action == ORDER_TYPE_SELL || action == ORDER_TYPE_SELL_LIMIT || action == ORDER_TYPE_SELL_STOP ) {
profit = (price_open - price_close) * volume * tickValue / _Point;
return profit;
}
return profit;
}
Tell me what to add so that the results of OrderCalcProfit() and this function match ?
elugovoy
Let’s say you have a Deposit in USD
Pairs XXXUSD – will be counted correctly by this formula,
but for the other pairs, a transfer to the Deposit currency is required at the current exchange rate, depending on the BUY/SELL direction.
There was a calculation algorithm on MQL4 community, as far as I remember
Guys, maybe it’s time for MQ to request the function of obtaining the margin of the order ? at least open. sometimes it is very necessary.
ya_programmer
the crosses are considered differently:
// USD/CHF point Price = point size * position volume / current rate
/ / EUR / USD point Price = point size * position volume
/ / EUR / CHF point Price = position volume * point size * current quote of the base currency against USD / current exchange rate of the currency pair (cross rate)
desead
here in this formula: return NormalizeDouble(openPrice*volume*SymbolInfoDouble(symbol,SYMBOL_TRADE_CONTRACT_SIZE)/AccountInfoInteger(ACCOUNT_LEVERAGE),0);
here in this place: AccountInfoInteger(ACCOUNT_LEVERAGE)
also, it may not always be true. I myself recently encountered such a situation. Here is a detailed reasoning and explanation:
From the beginning to page 3, all discussion on this issue.
scriptong
Let’s just say that the cross-country will not be something that “not always”, but always wrong.
The calculation formula itself is correct: Margin = quote * volume * contract_size / leverage.
Just instead of quote in different cases, you need to take different quotes. If the base currency of the symbol is quoted through the account currency (for example, EURUSD when the account currency is USD), then as a quote, you really need to take the opening price of the trade: Ask – for Buy and Bid-for Sell. This is the only case for which the calculation method you have given is correct.
A slightly different way is to get the value of quote characters whose base currency is the same as the account currency (USDCAD when the account currency is USD). In such cases, quote will be equal to: 1.0 / Ask for Buy and 1.0 / Bid for Sell.
And quote is calculated quite differently for crosses (symbols that do not contain the account currency). So, if the account currency is USD, the Deposit for the EURJPY trade will be calculated at the current price of EURUSD. Since EURUSD and EURJPY have the same base currency, then quote will be defined as in the case of just EURUSD: Ask (from EURUSD) – for Buy and Bid (from EURUSD) – for Sell.
If the cross is of the CHFJPY type, then quote should be calculated using the USDCHF symbol. Here, the base currencies of the symbol differ. Therefore, we get a quote as in the case of USDCAD: 1.0 / Ask (from USDCHF) – for Buy and 1.0 / Bid (from USDCHF) – for Sell.
I hope I explained it clearly. At one time, I “entered” this scheme for a very long time.
teetrinker
class COrderCalculateMargin{
public: double Result;
public: void COrderCalculateMargin(string symbol,ENUM_ORDER_TYPE orderType,double openPrice,double volume){
Result=0;
string currency=AccountInfoString(ACCOUNT_CURRENCY);
if(StringSubstr(symbol,3,3)==currency)Result=CalcMarginFormula(symbol,openPrice,volume);
else if(StringSubstr(symbol,0,3)==currency)Result=CalcMarginFormula(symbol,1,volume);
else{
string pair=StringSubstr(symbol,0,3)+currency;
if(orderType==ORDER_TYPE_BUY)Result=CalcMarginFormula(pair,Bid(pair),volume);
if(orderType==ORDER_TYPE_SELL)Result=CalcMarginFormula(pair,Ask(pair),volume);
}
return;
}
double CalcMarginFormula(string symbol,double openPrice,double volume){
return NormalizeDouble(openPrice*volume*SymbolInfoDouble(symbol,SYMBOL_TRADE_CONTRACT_SIZE)/AccountInfoInteger(ACCOUNT_LEVERAGE),0);
}
};
I wrote it myself, conducted tests, but it doesn’t always work exactly on cross-country tracks. Tell me where the error is.