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 quotein 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 quotecharacters whose base currency is the same as the account currency (USDCAD when the account currency is USD). In such cases, quotewill 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

quotewill 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

quoteshould 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){`

I wrote it myself, conducted tests, but it doesn’t always work exactly on cross-country tracks. Tell me where the error is.return NormalizeDouble(openPrice*volume*SymbolInfoDouble(symbol,SYMBOL_TRADE_CONTRACT_SIZE)/AccountInfoInteger(ACCOUNT_LEVERAGE),0);

}

};