Price Data Components
0
Views
0
Downloads
0
Favorites
Volume Calculation Tool
//+------------------------------------------------------------------+
//| 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 riskPercent = 2.0; // Percentage to risk
input PositionType posType = buy; // Position Type
double virtSL[];
double bid, ask, BidAsk, stopLoss, lotSize;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, virtSL, INDICATOR_DATA);
bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
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[])
{
bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
posType == buy ? BidAsk = ask : BidAsk = bid; // Determine bid/ask based on buy/sell
return(rates_total);
}
//+------------------------------------------------------------------+
//| Chart event processing |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
if (id == CHARTEVENT_CLICK)
{
// Get the total bars available
int all_bars = Bars(_Symbol, _Period);
// Record mouse click location as the virtual stop loss level
for (int x = 10; x >= 0; x--)
{
virtSL[x] = GetMouseY(dparam);
}
for (int x = 11; x < all_bars; x++)
{
virtSL[x] = EMPTY_VALUE;
}
// Calculate stop loss distance in points
stopLoss = MathAbs(BidAsk - GetMouseY(dparam));
// Calculate lot size based on the input risk percentage
lotSize = LotSizeCalc(riskPercent, stopLoss); // stoploss value (not the number of points)
// Display risk calculation
string calculation =
".:: Position Volume Calculator ::."
+ "\n\n"
+ "Risking: " + DoubleToString(riskPercent, 2) + "%"
+ "\n\n"
+ "Lot size to use: " + DoubleToString(lotSize, 2)
+ "\n"
+ "Stop loss points: " + DoubleToString(stopLoss/_Point, 2);
Comment(calculation);
}
}
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;
}
double LotSizeCalc(double riskPct, double SLDistance)
{
if (riskPct < 0 || riskPct > 100) {
Print("Error: Invalid risk percentage");
return -1;
}
double freeMargin = AccountInfoDouble(ACCOUNT_MARGIN_FREE); // Free margin on the account in the deposit currency
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE); // Minimal price change of ticks
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); // Value per tick in the deposit currency
double volumeStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP); // Minimum lot step
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN); // Minimum allowed lot size
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX); // Maximum allowed lot size
double riskVolumeStep = (SLDistance / tickSize) * tickValue * volumeStep;
double risk = (riskPct * freeMargin) / 100;
// calculate lot size by dividing risk by risk per volume step
double lots = MathFloor(risk / riskVolumeStep) * volumeStep;
if (lots < minLot) lots = minLot;
if (lots > maxLot) lots = maxLot;
return lots;
}
//+------------------------------------------------------------------+
//| De-initialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment("");
}
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---