//+------------------------------------------------------------------+ //| Position Risk Calculation Tool.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property indicator_chart_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_label1 "Virtual SL" #property indicator_type1 DRAW_LINE #property indicator_style1 STYLE_SOLID #property indicator_color1 clrPurple enum PositionType{ buy, // Buy sell // Sell }; input double lotSize = 1.0; // Trade volume (lot size) input PositionType posType = buy; // Position Type double virtSL[]; double balance; double maxLoss; double bid, ask; double BidAsk; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { SetIndexBuffer(0, virtSL, INDICATOR_DATA); bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); balance = AccountInfoDouble(ACCOUNT_BALANCE); ArraySetAsSeries(virtSL, true); Comment("Click on the chart at the desired stop loss level..."); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { balance = AccountInfoDouble(ACCOUNT_BALANCE); // updated now on every recalculation bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); posType == buy ? BidAsk = ask : bid; return(rates_total); } void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam){ if (id == CHARTEVENT_CLICK){ int all_bars = Bars(_Symbol, _Period); for(int x = 10; x >= 0; x--){ virtSL[x] = GetMouseY(dparam); } for(int x = 11; x < all_bars; x++){ virtSL[x] = EMPTY_VALUE; } double virtualStopLossPoints = MathAbs(BidAsk - GetMouseY(dparam))/_Point; maxLoss = MaxLossCalc(lotSize, virtualStopLossPoints); string calculation = ".:: Position Risk Calculator ::." + "\n\n" + "Lot size: " + DoubleToString(lotSize, 2) + "\n" + "Stop loss points: " + DoubleToString(virtualStopLossPoints, 2) + "\n\n" + "Risking:" + "\n" + DoubleToString(virtualStopLossPoints > 0 ? maxLoss : balance, 2) + " " + AccountInfoString(ACCOUNT_CURRENCY) + " " + "(" + DoubleToString(virtualStopLossPoints > 0 ? (maxLoss/balance) * 100 : 100, 2) + "%" + ")"; Comment(calculation); ChartNavigate(0, CHART_END); } } double GetMouseY(const double &dparam){ long chartHeightInPixels = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS); double priceRange = ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN); double pixelsPerPrice = chartHeightInPixels / priceRange; double mouseYValue = ChartGetDouble(0, CHART_PRICE_MAX) - dparam / pixelsPerPrice; return mouseYValue; } //+------------------------------------------------------------------+ //| Calculating monetary risk based on lot size and stop loss | //| | //+------------------------------------------------------------------+ double MaxLossCalc(double lot, double sl_points) { // Get tick value for the current symbol (value per pip in the account currency per 1 lot) double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); double stopLossValue = sl_points * tickValue; maxLoss = lot * stopLossValue; return maxLoss; // Return the max loss in monetary terms } void OnDeinit(const int reason){ Comment(""); }