Skip to content

Commit e3ca0e5

Browse files
authored
1.01
1. Added expected floating profit/loss display. 2. Added number formatting. 3. Fixed calculation formula in cTrader.
1 parent 19c789d commit e3ca0e5

File tree

3 files changed

+115
-14
lines changed

3 files changed

+115
-14
lines changed

EquityLine.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Takes into account P&L of open trades in the current symbol.
44
// You can hide/show the line by pressing Shift+E.
55
//
6-
// Version 1.00
6+
// Version 1.01
77
// Copyright 2025, EarnForex.com
88
// https://www.earnforex.com/indicators/Entry-Line/
99
// -------------------------------------------------------------------------------
@@ -33,9 +33,6 @@ public class EquityProjectionLine : Indicator
3333
[Parameter("Show Equity Label", DefaultValue = true)]
3434
public bool ShowLabel { get; set; }
3535

36-
[Parameter("Equity Label Prefix", DefaultValue = "EQUITY: ")]
37-
public string EquityLabelPrefix { get; set; }
38-
3936
[Parameter("Label PositiveChange Color", DefaultValue = "Green")]
4037
public Color LabelPositiveChangeColor { get; set; }
4138

@@ -52,6 +49,7 @@ public class EquityProjectionLine : Indicator
5249
private ChartText equityLabel;
5350
private double projectionPrice = 0;
5451
private double projectedEquity = 0;
52+
private double totalFloatingProfit = 0;
5553
private bool isVisible = true;
5654

5755
protected override void Initialize()
@@ -134,16 +132,18 @@ private void CalculateProjectedEquity()
134132

135133
// Calculate total P&L change for positions in current symbol.
136134
double totalPLChange = 0;
135+
136+
double floatingProfit = 0;
137137

138138
// Get all positions for current symbol.
139139
var symbolPositions = Positions.Where(p => p.SymbolName == Symbol.Name);
140140

141141
foreach (var position in symbolPositions)
142142
{
143143
double posLots = position.VolumeInUnits;
144-
144+
floatingProfit += position.NetProfit;
145145
// Calculate point value for this position.
146-
double pointValue = Symbol.PipValue * position.VolumeInUnits / Symbol.LotSize;
146+
double pointValue = Symbol.PipValue * position.VolumeInUnits;
147147

148148
// Calculate projected P&L at projection price.
149149
double projectedPL = 0;
@@ -167,6 +167,9 @@ private void CalculateProjectedEquity()
167167
totalPLChange += projectedPL;
168168
}
169169

170+
// For output.
171+
totalFloatingProfit = totalPLChange + floatingProfit;
172+
170173
// Calculate projected equity.
171174
projectedEquity = currentEquity + totalPLChange;
172175

@@ -217,7 +220,7 @@ private void UpdateLabel()
217220
}
218221

219222
// Format equity text with proper decimal places.
220-
string equityText = EquityLabelPrefix + projectedEquity.ToString("F2");
223+
string equityText = $"Equity: {projectedEquity:N2} {Account.Asset.Name} (Floating profit: {totalFloatingProfit:N2} {Account.Asset.Name})";
221224

222225
// Calculate color based on equity change.
223226
double currentEquity = Account.Equity;

EquityLine.mq4

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//+------------------------------------------------------------------+
66
#property copyright "www.EarnForex.com, 2025"
77
#property link "https://www.earnforex.com/indicators/Equity-Line/"
8-
#property version "1.00"
8+
#property version "1.01"
99
#property indicator_chart_window
1010
#property strict
1111

@@ -18,7 +18,6 @@ input color LineColor = clrDodgerBlue; // Projection line color
1818
input int LineWidth = 2; // Projection line width
1919
input ENUM_LINE_STYLE LineStyle = STYLE_SOLID; // Projection line style
2020
input bool ShowLabel = true; // Show equity label
21-
input string EquityLabelPrefix = "EQUITY: "; // Equity label prefix
2221
input color LabelPositiveChangeColor = clrGreen; // Equity label color (positive change)
2322
input color LabelNegativeChangeColor = clrRed; // Equity label color (negative change)
2423
input int InitialPriceOffset = 50; // Initial price offset in points
@@ -28,6 +27,7 @@ string LineObjectName = "EquityProjectionLine";
2827
string EquityLabelObjectName = "EquityProjectionLabel";
2928
double ProjectionPrice = 0;
3029
double ProjectedEquity = 0;
30+
double totalFloatingProfit = 0;
3131

3232
void OnInit()
3333
{
@@ -130,6 +130,8 @@ void CalculateProjectedEquity()
130130
// Calculate total P&L change for positions in current symbol.
131131
double totalPLChange = 0;
132132

133+
double floatingProfit = 0;
134+
133135
// Scan all positions.
134136
int totalOrders = OrdersTotal();
135137
for (int i = 0; i < totalOrders; i++)
@@ -162,13 +164,17 @@ void CalculateProjectedEquity()
162164
if (priceDiff < 0) projectedPL = priceDiff * point_value_reward * posLots;
163165
else projectedPL = priceDiff * point_value_risk * posLots;
164166
}
167+
floatingProfit += OrderProfit() + OrderSwap() + OrderCommission();
165168
totalPLChange += projectedPL;
166169
}
167170
}
168171

169172
// Calculate projected equity.
170173
ProjectedEquity = currentEquity + totalPLChange;
171174

175+
// For output.
176+
totalFloatingProfit = totalPLChange + floatingProfit;
177+
172178
// Update display.
173179
UpdateLabel();
174180
}
@@ -211,7 +217,7 @@ void UpdateLabel()
211217
// Get the leftmost and rightmost visible bars.
212218
int firstVisibleBar = (int)ChartGetInteger(ChartID(), CHART_FIRST_VISIBLE_BAR);
213219

214-
string equityText = EquityLabelPrefix + DoubleToString(ProjectedEquity, 2);
220+
string equityText = "Equity: " + FormatDouble(DoubleToString(ProjectedEquity, 2), 2) + " " + AccCurrency + " (Floating profit: " + FormatDouble(DoubleToString(totalFloatingProfit, 2), 2) + " " + AccCurrency + ")";
215221

216222
// Calculate color based on equity change.
217223
double currentEquity = AccountEquity();
@@ -469,4 +475,35 @@ double GetCurrencyCorrectionCoefficient(MqlTick &tick, const mode_of_operation m
469475
}
470476
return -1;
471477
}
478+
479+
//+---------------------------------------------------------------------------+
480+
//| Formats double with thousands separator for so many digits after the dot. |
481+
//+---------------------------------------------------------------------------+
482+
string FormatDouble(const string number, const int digits = 2)
483+
{
484+
// Find "." position.
485+
int pos = StringFind(number, ".");
486+
string integer = number;
487+
string decimal = "";
488+
if (pos > -1)
489+
{
490+
integer = StringSubstr(number, 0, pos);
491+
decimal = StringSubstr(number, pos, digits + 1);
492+
}
493+
string formatted = "";
494+
string comma = "";
495+
496+
while (StringLen(integer) > 3)
497+
{
498+
int length = StringLen(integer);
499+
string group = StringSubstr(integer, length - 3);
500+
formatted = group + comma + formatted;
501+
comma = ",";
502+
integer = StringSubstr(integer, 0, length - 3);
503+
}
504+
if (integer == "-") comma = "";
505+
if (integer != "") formatted = integer + comma + formatted;
506+
507+
return(formatted + decimal);
508+
}
472509
//+------------------------------------------------------------------+

EquityLine.mq5

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//+------------------------------------------------------------------+
66
#property copyright "www.EarnForex.com, 2025"
77
#property link "https://www.earnforex.com/indicators/Equity-Line/"
8-
#property version "1.00"
8+
#property version "1.01"
99
#property indicator_chart_window
1010
#property indicator_plots 0
1111

@@ -18,7 +18,6 @@ input color LineColor = clrDodgerBlue; // Projection line color
1818
input int LineWidth = 2; // Projection line width
1919
input ENUM_LINE_STYLE LineStyle = STYLE_SOLID; // Projection line style
2020
input bool ShowLabel = true; // Show equity label
21-
input string EquityLabelPrefix = "EQUITY: "; // Equity label prefix
2221
input color LabelPositiveChangeColor = clrGreen; // Equity label color (positive change)
2322
input color LabelNegativeChangeColor = clrRed; // Equity label color (negative change)
2423
input int InitialPriceOffset = 50; // Initial price offset in points
@@ -28,6 +27,7 @@ string LineObjectName = "EquityProjectionLine";
2827
string EquityLabelObjectName = "EquityProjectionLabel";
2928
double ProjectionPrice = 0;
3029
double ProjectedEquity = 0;
30+
double totalFloatingProfit = 0;
3131

3232
void OnInit()
3333
{
@@ -136,6 +136,8 @@ void CalculateProjectedEquity()
136136
// Calculate total P&L change for positions in current symbol.
137137
double totalPLChange = 0;
138138

139+
double floatingProfit = 0;
140+
139141
// Scan all positions.
140142
int totalPositions = PositionsTotal();
141143
for (int i = 0; i < totalPositions; i++)
@@ -167,18 +169,46 @@ void CalculateProjectedEquity()
167169
if (priceDiff < 0) projectedPL = priceDiff * point_value_reward * posLots;
168170
else projectedPL = priceDiff * point_value_risk * posLots;
169171
}
172+
floatingProfit += PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP) + CalculateCommission();
170173
totalPLChange += projectedPL;
171174
}
172175
}
173176
}
174177

175178
// Calculate projected equity.
176179
ProjectedEquity = currentEquity + totalPLChange;
177-
180+
181+
// For output.
182+
totalFloatingProfit = totalPLChange + floatingProfit;
183+
178184
// Update display.
179185
UpdateLabel();
180186
}
181187

188+
double CalculateCommission()
189+
{
190+
double commission_sum = 0;
191+
if (!HistorySelectByPosition(PositionGetInteger(POSITION_IDENTIFIER)))
192+
{
193+
Print("HistorySelectByPosition failed: ", GetLastError());
194+
return 0;
195+
}
196+
int deals_total = HistoryDealsTotal();
197+
for (int i = 0; i < deals_total; i++)
198+
{
199+
ulong deal_ticket = HistoryDealGetTicket(i);
200+
if (deal_ticket == 0)
201+
{
202+
Print("HistoryDealGetTicket failed: ", GetLastError());
203+
continue;
204+
}
205+
if ((HistoryDealGetInteger(deal_ticket, DEAL_TYPE) != DEAL_TYPE_BUY) && (HistoryDealGetInteger(deal_ticket, DEAL_TYPE) != DEAL_TYPE_SELL)) continue; // Wrong kinds of deals.
206+
if (HistoryDealGetInteger(deal_ticket, DEAL_ENTRY) != DEAL_ENTRY_IN) continue; // Only entry deals.
207+
commission_sum += HistoryDealGetDouble(deal_ticket, DEAL_COMMISSION);
208+
}
209+
return commission_sum;
210+
}
211+
182212
// Draw projection line on chart.
183213
void DrawProjectionLine()
184214
{
@@ -216,7 +246,7 @@ void UpdateLabel()
216246
// Get the leftmost and rightmost visible bars.
217247
int firstVisibleBar = (int)ChartGetInteger(ChartID(), CHART_FIRST_VISIBLE_BAR);
218248

219-
string equityText = EquityLabelPrefix + DoubleToString(ProjectedEquity, (int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS));
249+
string equityText = "Equity: " + FormatDouble(DoubleToString(ProjectedEquity, (int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS)), (int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS)) + " " + AccCurrency + " (Floating profit: " + FormatDouble(DoubleToString(totalFloatingProfit, (int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS)), (int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS)) + " " + AccCurrency + ")";
220250

221251
// Calculate color based on equity change.
222252
double currentEquity = AccountInfoDouble(ACCOUNT_EQUITY);
@@ -405,4 +435,35 @@ double GetCurrencyCorrectionCoefficient(MqlTick &tick, const mode_of_operation m
405435
}
406436
return -1;
407437
}
438+
439+
//+---------------------------------------------------------------------------+
440+
//| Formats double with thousands separator for so many digits after the dot. |
441+
//+---------------------------------------------------------------------------+
442+
string FormatDouble(const string number, const int digits = 2)
443+
{
444+
// Find "." position.
445+
int pos = StringFind(number, ".");
446+
string integer = number;
447+
string decimal = "";
448+
if (pos > -1)
449+
{
450+
integer = StringSubstr(number, 0, pos);
451+
decimal = StringSubstr(number, pos, digits + 1);
452+
}
453+
string formatted = "";
454+
string comma = "";
455+
456+
while (StringLen(integer) > 3)
457+
{
458+
int length = StringLen(integer);
459+
string group = StringSubstr(integer, length - 3);
460+
formatted = group + comma + formatted;
461+
comma = ",";
462+
integer = StringSubstr(integer, 0, length - 3);
463+
}
464+
if (integer == "-") comma = "";
465+
if (integer != "") formatted = integer + comma + formatted;
466+
467+
return(formatted + decimal);
468+
}
408469
//+------------------------------------------------------------------+

0 commit comments

Comments
 (0)