The formula I use is here.
Account_Balance*Risk*0.01/Stop__Loss/Pip_Value.
This is pretty close to yours, however we're calculating Pip_Values differently.
The way I think about it is, you have to get the value of the Tick. This is usually the value of a Point. But what you want is the value of a Pip. You cannot simply say Pip_Value = Tick_Value*10; Because this'll be good for 5_digits brokers but fail on 4_digits brokers. If you can determine a 5_digit broker vs a 4_digit broker then simply multiply the Tick_Value by 10 or 1 in-order to get the Pip_Value. If you look around the forum, you'll find different ways of doing it. Some people divide and others multiply. Use a method which is easier for you to remember.
Once you've got the correct lotsize from the above equation, then you'll need to drop-off any floating decimals to ensure it goes into the broker lot_steps perfectly. Example: MathFloor( myRiskLots / Symbol_Lot_Step) * Symbol_Lot_Step;
You get Tick_Values via the MarketInfo(); Example double Tick_Value=MarketInfo(Symbol(),MODE_TICKVALUE);
{Added} MarketInfo for Symbols outside the testing Symbol does not work in mt4 strategy tester.
You DON'T use tickValue alone, only as a ratio
AccountBalance() * Percentage = Risk = (OrderOpenPrice() - OrderStopLoss())*DIR * OrderLotsize() * DeltaPerLot()
Done! Works on 4 and 5 Digit brokers. Your information about TICKVALUE helped me a lot. If you could have a look at the code? Is there anything to improve? The only thing I don't like is to use absolute values for OBJPROP_XDISTANCE. I would rather like to make it relative to the window. Monitors have different sizes and therefore absolute values are not the best solution...
//+------------------------------------------------------------------+ //| Moneymanagement.mq4 | //| Copyright 2013, MR | //| | //+------------------------------------------------------------------+ #property copyright "Copyright 2013, MR" #property link "" #property indicator_chart_window //--- input parameters extern int Risk=5; extern int StopLoss=15; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- indicators //---- return(0); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- for(int iObj = ObjectsTotal() - 1; iObj >= 0; iObj--) { string name = ObjectName(iObj); ObjectDelete(name); } //---- return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { //---- double MoneyRisk = AccountBalance()*Risk*0.01; double PipValue = MoneyRisk/StopLoss; if (Digits==5 || Digits ==3) { PipValue = PipValue/(MarketInfo(Symbol(), MODE_TICKVALUE)*10); } else { PipValue = PipValue/MarketInfo(Symbol(), MODE_TICKVALUE); } if (ObjectFind("Acc") == -1) { ObjectCreate("Acc", OBJ_LABEL, 0, 0, 0); ObjectSet("Acc", OBJPROP_XDISTANCE, 1350); ObjectSet("Acc", OBJPROP_YDISTANCE, 0); ObjectSetText("Acc", "Account: "+ DoubleToStr(AccountBalance(), 2)+" "+AccountCurrency(), 10, "Verdana", White); } if (ObjectFind("RiskP") == -1) { ObjectCreate("RiskP", OBJ_LABEL, 0, 0, 0); ObjectSet("RiskP", OBJPROP_XDISTANCE, 1350); ObjectSet("RiskP", OBJPROP_YDISTANCE, 15); ObjectSetText("RiskP", "Risk in %: "+ Risk, 10, "Verdana", White); } if (ObjectFind("RiskA") == -1) { ObjectCreate("RiskA", OBJ_LABEL, 0, 0, 0); ObjectSet("RiskA", OBJPROP_XDISTANCE, 1350); ObjectSet("RiskA", OBJPROP_YDISTANCE, 30); ObjectSetText("RiskA", "Risk in "+AccountCurrency()+": "+ DoubleToStr(MoneyRisk,2), 10, "Verdana", White); } if (ObjectFind("StopLoss") == -1) { ObjectCreate("StopLoss", OBJ_LABEL, 0, 0, 0); ObjectSet("StopLoss", OBJPROP_XDISTANCE, 1350); ObjectSet("StopLoss", OBJPROP_YDISTANCE, 45); ObjectSetText("StopLoss", "Stop Loss: "+ StopLoss+ " Pips", 10, "Verdana", White); } if (ObjectFind("Lotsize") == -1) { ObjectCreate("Lotsize", OBJ_LABEL, 0, 0, 0); ObjectSet("Lotsize", OBJPROP_XDISTANCE, 1350); ObjectSet("Lotsize", OBJPROP_YDISTANCE, 60); ObjectSetText("Lotsize", "Lots: "+DoubleToStr(PipValue, 2), 10, "Verdana", White); } //---- return(0); } //+------------------------------------------------------------------+
I think Window_Corner would be your best bet. Example: https://www.mql5.com/en/code/10842. I do-not think there's any function which returns the maximum_XDistance, but I could be wrong.
He's talking about this post Here:https://www.mql5.com/en/forum/127584. The poster is saying that sometimes the broker changes the "definition of a tick". Imagine a 4_Digit broker who changed the Tick on EurUsd from 0.0001 to 0.0002. Your current formula expects a Tick_Value of $10 ($10 for a Pip on Standard_Lot of 1). However the Tick_Value you get is $20. This causes you to take a Smaller LotSize for the same Distance.
If you're confused, don't worry, allot of people including me gets tripped-up by these money-management calculations. If you look at my codes, I do use the ratio (just to be safe), however, I leave it out the first time to avoid complexity.
return( MarketInfo(pair, MODE_TICKVALUE) / MarketInfo(pair, MODE_TICKSIZE) ); // Not Point.That is too hard for you? Or is calling the function too hard?
Ok, now there is a little bit of light in the dark. I didn't know that a broker can change the tick value. Therefore I had no idea why this ratio is important.
So I better change the calculation for my pip value.
@William: both ;) but with the knowledge about changing tick values it all makes sense to me.
ubzen, I used your advice with OBJPROP_CORNER. That exactly what I was looking for, works fine! But now there is one question left. I don't know if that is even possible. Maybe you had this problem before and have an idea. I print some labels at the right top corner. Although I use the chart shift there is the problem that the chart reaches into the labels sometimes. Is it somehow possible to locate the chart within the chart-window? For example when the chart is in the upper 50% of the window, I would print the labels at the lower right corner.
Checking the highest high or lowest low of the last 10 bars would not help me because I don't know where they are located in relation to the whole chart window.
Maybe you have an idea?
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi,
I would like to make an indicator which has two extern variables: risk (in %) and stop loss. The indicator should print the correct lotsize in the upper right corner of the chart. But there is one issue I can't solve. For example, my loss is larger when I lose 20 Pips with a EURGBP-trade than with a EURUSD-trade. Therefore the lotsize depends on the stoploss size and the currency-pair I want to trade. This indicator should work by receiving the currency-information from the chart. So when I determine the risk and stoploss size in pips, the indicator must show different lotsizes according to the currency.
And this is my problem. How can I receive the chart's secondary currency? I only know that I get the currency pair by using Symbol(). But how can I only get the secondary currency? Or is the only possibility to check for ALL symbols for example ending with "JPY"? Something like IF(CurrencyPair=="AUDJPY" || CurrencyPair=="CADJPY" || CurrencyPair=="EURJPY" || .....) ?
Or can I just say IF(CurrencyPair ending with "JPY") .... ? But I have no idea for the syntax, if this is generally possible.
This is what I have so far (I make it for a Euro based account, therefore I calculate everything to Euro):