How is Grossprofit and usedmargin realy calculated.

Created at 26 Nov 2019, 22:40
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
SH

Shares4UsDevelopment

Joined 14.10.2018

How is Grossprofit and usedmargin realy calculated.
26 Nov 2019, 22:40


Because there where Orders that were not taken that should have been and orders that where taken that should not have been I dove a little deeper in the Moneymanagement used for deciding when to take a position or when to not do so.
In scalping we talk about very small pricechanges and tiny margins that are critical to success or failure.

I wrote a little debugstuff to see what is the status when a position is openend and let it run in backtest on just the first position (notice the stop)

I took a simple situation opening EURNOK long in a EUR account.
 

        private void OnPositionOpened(PositionOpenedEventArgs args)
        {
  Position pos = args.Position;
            double Comm1Way = 25;
            double Crossprice = 1;
            double StartBalance = 1000;
            double units = pos.VolumeInUnits;
            double entryPrice = pos.EntryPrice;
            double leverage = Account.PreciseLeverage;
            double pointPrice = Symbol.Bid;

            double tickSize = Symbol.TickSize;
            Print("\ttickSize\t", tickSize.ToString("F7"));
            double tickValue = Symbol.TickValue;
            Print("\ttickValue\t", tickValue.ToString("F7"));
            double symbolFactor = tickSize / tickValue;
            Print("\tsymbolFactor\t", symbolFactor.ToString("F7"));

            double spread = (entryPrice - pointPrice);
            Print("\tspread\t", spread.ToString("F7"));
            double spreadcosts = units * spread / symbolFactor;
            Print("\tspreadcosts\t", spreadcosts.ToString("F2"));

            double grossprofit = units * spread / symbolFactor;
            Print("\tgrossprofit\t", grossprofit);

            double commission1w = units * Comm1Way / 1000000;
            Print("\tcommission1w\t", commission1w.ToString("F2"));
            double commission2w = 2 * commission1w;
            Print("\tcommission2w\t", commission2w.ToString("F2"));

            double UnitsPrice = units / leverage * Crossprice;
            Print("\tUnitsPrice\t", UnitsPrice.ToString("F2"));

            Print("\tEquity\t" + (StartBalance - (units * spread / (tickSize / tickValue)) - (2 * units * Comm1Way / 1000000)).ToString("F2"));
            Print("\tGr.Prof\t" + (-units * spread / (tickSize / tickValue)).ToString("F2"));
            Print("\tNet.Prof\t", (-units * spread / (tickSize / tickValue) + (2 * -units * Comm1Way / 1000000)).ToString("F2"));
            Print("\tMarginRequired/Used\t" + (((units / leverage) + (units * (entryPrice - pointPrice) / (tickSize / tickValue))) + (units * Comm1Way / 1000000)).ToString("F2"));
            Print("\tFree Margin\t" + (StartBalance + (-units / leverage) + (-units * (entryPrice - pointPrice) / (tickSize / tickValue)) + (-units * Comm1Way / 1000000)).ToString("F2"));

            Print("\tID\t",
               "AccCurr\t",
               "SymbolName\t",
               "TickSize  \t",
               "TickValue\t",
               "EntryPr.\t",
               "AskPrice\t",
               "BidPrice \t",
               "Volume\t",
               "Comm\t",
               "Balance\t",
               "Equity\t",
               "Lev\t",
               "Gr.Prof\t",
               "Net.Prof\t",
               "FreeMar\t",
               "UsedMar");
            Print("\t",
                pos.Id, "\t",
                Account.Currency, "\t",
                SymbolName.Left(6), "\t",
                Symbol.TickSize.ToString("F6"), "\t",
                Symbol.TickValue.ToString("F6"), "\t",
                pos.EntryPrice, "\t",
                Symbol.Ask, "\t",
                Symbol.Bid, "\t",
                pos.VolumeInUnits, "\t",
                pos.Commissions, "\t",
                Account.Balance, "\t",
                Account.Equity, "\t",
                this.Account.PreciseLeverage, "\t",
                pos.GrossProfit, "\t",
                pos.NetProfit, "\t",
                Account.FreeMargin, "\t",
                (Account.Balance - Account.FreeMargin).ToString("F2"), "\t");

             Stop();
        }

This gave differences on what the calculated figures and reported figures at cTrader are. It is something I can not explain with simple rounding..
The output is:

The differences in red are significant for scalpers.

So the Question is:

What formula's does cTrader really use in calculating GrossProfit and UsedMargin?

Hope someone can shed a light on the differences or the correct formula's

Best rgds,
 


@Shares4UsDevelopment
Replies

PanagiotisCharalampous
27 Nov 2019, 08:48

Hi A.R.

Please provide us with the following

  1. The broker.
  2. The full cBot code you are using.
  3. The exact datetime this position is opened.

We need this information in order to provide you an explanation.

Best Regards,

Panagiotis


@PanagiotisCharalampous

Shares4UsDevelopment
27 Nov 2019, 10:44 ( Updated at: 21 Dec 2023, 09:21 )

RE:

Hi Panagiotis,
Here is the data you need:
Broker FXpig 
Feed EURONOK.mpa  M15

Relevant code: (No need for the complete bot, The difference/problem is the same for every executed order)

 ExecuteMarketOrderAsync(TradeType.Buy, "EURNOK", 39841, "SBstHdg8", null, 65);  


 private void FTMO_OnPositionOpen(PositionOpenedEventArgs args)
        {
            Position pos = args.Position;
            double Comm1Way = 25;
            double Crossprice = 1;
            double StartBalance = 1000;
            double units = pos.VolumeInUnits;
            double entryPrice = pos.EntryPrice;
            double leverage = Account.PreciseLeverage;
            double pointPrice = Symbol.Bid;

            double tickSize = Symbol.TickSize;
            Print("\ttickSize\t", tickSize.ToString("F7"));
            double tickValue = Symbol.TickValue;
            Print("\ttickValue\t", tickValue.ToString("F7"));
            double symbolFactor = tickSize / tickValue;
            Print("\tsymbolFactor\t", symbolFactor.ToString("F7"));

            double spread = (entryPrice - pointPrice);
            Print("\tspread\t", spread.ToString("F7"));
            double spreadcosts = units * spread / symbolFactor;
            Print("\tspreadcosts\t", spreadcosts.ToString("F2"));

            double grossprofit = units * spread / symbolFactor;
            Print("\tgrossprofit\t", grossprofit);

            double commission1w = units * Comm1Way / 1000000;
            Print("\tcommission1w\t", commission1w.ToString("F2"));
            double commission2w = 2 * commission1w;
            Print("\tcommission2w\t", commission2w.ToString("F2"));

            double UnitsPrice = units / leverage * Crossprice;
            Print("\tUnitsPrice\t", UnitsPrice.ToString("F2"));

            Print("\tEquity\t" + (StartBalance - (units * spread / (tickSize / tickValue)) - (2 * units * Comm1Way / 1000000)).ToString("F2"));
            Print("\tGr.Prof\t" + (-units * spread / (tickSize / tickValue)).ToString("F2"));
            Print("\tNet.Prof\t", (-units * spread / (tickSize / tickValue) + (2 * -units * Comm1Way / 1000000)).ToString("F2"));
            Print("\tMarginRequired/Used\t" + ((units / leverage) + (units * (entryPrice - pointPrice) / (tickSize / tickValue))).ToString("F2"));
            Print("\tFree Margin\t" + (StartBalance + (-units / leverage) + (-units * (entryPrice - pointPrice) / (tickSize / tickValue))).ToString("F2"));

            Print("\tID\t",
               "AccCurr\t",
               "SymbolName\t",
               "TickSize  \t",
               "TickValue\t",
               "EntryPr.\t",
               "AskPrice\t",
               "BidPrice \t",
               "Volume\t",
               "Comm\t",
               "Balance\t",
               "Equity\t",
               "Lev\t",
               "Gr.Prof\t",
               "Net.Prof\t",
               "FreeMar\t",
               "UsedMar");
            Print("\t",
                pos.Id, "\t",
                Account.Currency, "\t",
                SymbolName.Left(6), "\t",
                Symbol.TickSize.ToString("F6"), "\t",
                Symbol.TickValue.ToString("F6"), "\t",
                pos.EntryPrice, "\t",
                Symbol.Ask, "\t",
                Symbol.Bid, "\t",
                pos.VolumeInUnits, "\t",
                pos.Commissions, "\t",
                Account.Balance, "\t",
                Account.Equity, "\t",
                this.Account.PreciseLeverage, "\t",
                pos.GrossProfit, "\t",
                pos.NetProfit, "\t",
                Account.FreeMargin, "\t",
                (Account.Balance - Account.FreeMargin).ToString("F2"), "\t");
            Stop();
        }


Output:


Position taken::

Event:

Hope it helps.

 


@Shares4UsDevelopment

PanagiotisCharalampous
27 Nov 2019, 11:18 ( Updated at: 21 Dec 2023, 09:21 )

Hi A.R. 

There is a reason I need exact information to reproduce i.e. a plug and play cBot. For example, I tried this myself and values seem to match

Best Regards,

Panagiotis


@PanagiotisCharalampous

Shares4UsDevelopment
27 Nov 2019, 16:29

RE:

Hi Panagiotis
Well that also matches at my end.
It's the outcome of the formula's I used that does not match!
I'd like to know:

Why those formula's are not OK, what is missing?

And why is there a difference in used margin/free margin when the Equity drops not that amount and the balance stays the same?


Cheers,
A.R.
BTW you used a spa feed not the mpa feed


@Shares4UsDevelopment

PanagiotisCharalampous
27 Nov 2019, 17:08

Hi A.R. 

I am not sure why do you calculate margin this way

Print("\tMarginRequired/Used\t" + ((units / leverage) + (units * (entryPrice - pointPrice) / (tickSize / tickValue))).ToString("F2"));

In principle the formula for calculating the margin is the following

Margin = Units / Leverage * Conversion Rate

Where Conversion Rate is the rate between the balance currency and the quote currency

Best Regards,

Panagiotis


@PanagiotisCharalampous

Shares4UsDevelopment
27 Nov 2019, 19:12

RE:

Hi Panagiotis,

Balance currency is the same as Quote currency in the example. (EUR vs EURNOK)
So the Required Margin should be

  • (RequiredMargin = Units / Leverage * Conversion Rate) = 39841 / 100 * 1 = 398.41
  • (UsedMargin = Balance - FreeMargin) => 1000 - 581.28 = 418.72

So Margin taken by ctrader is 418.72 whilst the required margin is 398.41 
Actualy a 1waycommission should be taken into account when determining the RequiredMargin.So:

  • (RequiredMargin = (Units / Leverage * Conversion Rate) = 1wCommission)= (39841 / 100 * 1) +1  = 399.41

Still a 19 Euro Gap

Shouldn't 418.72 and 399.41 match?


@Shares4UsDevelopment

PanagiotisCharalampous
28 Nov 2019, 08:45 ( Updated at: 21 Dec 2023, 09:21 )

Hi A.R. 

Commissions should not be taken into account for required margin calculation. See below a simple example from Spotware Beta. 

Unfortunately I cannot reproduce your numbers since I do not have enough information, like the complete cBot you are using, your account type and the symbol you are using. Can you please reproduce such a behavior on Spotware Beta and provide me a complete cBot that will allow me to see the same numbers as you? 

Best Regards,

Panagiotis


@PanagiotisCharalampous