Skip to content

Commit a68f7b7

Browse files
authored
1.00
1 parent 140d819 commit a68f7b7

File tree

4 files changed

+1157
-0
lines changed

4 files changed

+1157
-0
lines changed

EquityLine.cs

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
// -------------------------------------------------------------------------------
2+
// Displays projected equity at a draggable price line.
3+
// Takes into account P&L of open trades in the current symbol.
4+
// You can hide/show the line by pressing Shift+E.
5+
//
6+
// Version 1.00
7+
// Copyright 2025, EarnForex.com
8+
// https://www.earnforex.com/indicators/Entry-Line/
9+
// -------------------------------------------------------------------------------
10+
11+
using System;
12+
using System.Linq;
13+
using cAlgo.API;
14+
using cAlgo.API.Internals;
15+
16+
namespace cAlgo
17+
{
18+
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
19+
public class EquityProjectionLine : Indicator
20+
{
21+
[Parameter("Update Frequency (seconds)", DefaultValue = 1, MinValue = 1)]
22+
public int UpdateFrequency { get; set; }
23+
24+
[Parameter("Projection Line Color", DefaultValue = "DodgerBlue")]
25+
public Color LineColor { get; set; }
26+
27+
[Parameter("Projection Line Width", DefaultValue = 2, MinValue = 1)]
28+
public int LineWidth { get; set; }
29+
30+
[Parameter("Projection Line Style", DefaultValue = LineStyle.Solid)]
31+
public LineStyle LineStyleParam { get; set; }
32+
33+
[Parameter("Show Equity Label", DefaultValue = true)]
34+
public bool ShowLabel { get; set; }
35+
36+
[Parameter("Equity Label Prefix", DefaultValue = "EQUITY: ")]
37+
public string EquityLabelPrefix { get; set; }
38+
39+
[Parameter("Label PositiveChange Color", DefaultValue = "Green")]
40+
public Color LabelPositiveChangeColor { get; set; }
41+
42+
[Parameter("Label Negative Change Color", DefaultValue = "Red")]
43+
public Color LabelNegativeChangeColor { get; set; }
44+
45+
[Parameter("Initial Price Offset (pips)", DefaultValue = 50)]
46+
public double InitialPriceOffset { get; set; }
47+
48+
// Global variables:
49+
private const string LineObjectName = "EquityProjectionLine";
50+
private const string EquityLabelObjectName = "EquityProjectionLabel";
51+
private ChartHorizontalLine projectionLine;
52+
private ChartText equityLabel;
53+
private double projectionPrice = 0;
54+
private double projectedEquity = 0;
55+
private bool isVisible = true;
56+
57+
protected override void Initialize()
58+
{
59+
// Check if the line already exists.
60+
projectionLine = Chart.FindObject(LineObjectName) as ChartHorizontalLine;
61+
62+
if (projectionLine == null) // If the line doesn't exist yet.
63+
{
64+
// Initialize projection price near current price.
65+
projectionPrice = Symbol.Bid + (InitialPriceOffset * Symbol.PipSize);
66+
projectionPrice = Math.Round(projectionPrice, Symbol.Digits);
67+
68+
DrawProjectionLine();
69+
}
70+
else
71+
{
72+
projectionPrice = projectionLine.Y;
73+
}
74+
75+
CalculateProjectedEquity();
76+
77+
// Set up timer for updates.
78+
Timer.Start(TimeSpan.FromSeconds(UpdateFrequency));
79+
80+
// Subscribe to chart events.
81+
Chart.ObjectsUpdated += OnChartObjectsUpdated;
82+
Chart.KeyDown += OnChartKeyDown;
83+
Chart.ScrollChanged += OnChartScrollChanged;
84+
Chart.ZoomChanged += OnChartZoomChanged;
85+
}
86+
87+
public override void Calculate(int index)
88+
{
89+
CalculateProjectedEquity();
90+
}
91+
92+
protected override void OnTimer()
93+
{
94+
CalculateProjectedEquity();
95+
}
96+
97+
private void OnChartObjectsUpdated(ChartObjectsUpdatedEventArgs obj)
98+
{
99+
if (obj.Chart.FindObject(LineObjectName) is ChartHorizontalLine line)
100+
{
101+
if (Math.Abs(line.Y - projectionPrice) > Symbol.TickSize)
102+
{
103+
projectionPrice = Math.Round(line.Y, Symbol.Digits);
104+
CalculateProjectedEquity();
105+
UpdateLabel();
106+
}
107+
}
108+
}
109+
110+
private void OnChartKeyDown(ChartKeyboardEventArgs obj)
111+
{
112+
// Toggle visibility with Shift+E.
113+
if (obj.Key == Key.E && (obj.ShiftKey))
114+
{
115+
isVisible = !isVisible;
116+
ToggleVisibility();
117+
}
118+
}
119+
120+
private void OnChartScrollChanged(ChartScrollEventArgs obj)
121+
{
122+
UpdateLabel();
123+
}
124+
125+
private void OnChartZoomChanged(ChartZoomEventArgs obj)
126+
{
127+
UpdateLabel();
128+
}
129+
130+
private void CalculateProjectedEquity()
131+
{
132+
// Get current account information.
133+
double currentEquity = Account.Equity;
134+
135+
// Calculate total P&L change for positions in current symbol.
136+
double totalPLChange = 0;
137+
138+
// Get all positions for current symbol.
139+
var symbolPositions = Positions.Where(p => p.SymbolName == Symbol.Name);
140+
141+
foreach (var position in symbolPositions)
142+
{
143+
double posLots = position.VolumeInUnits;
144+
145+
// Calculate point value for this position.
146+
double pointValue = Symbol.PipValue * position.VolumeInUnits / Symbol.LotSize;
147+
148+
// Calculate projected P&L at projection price.
149+
double projectedPL = 0;
150+
151+
if (position.TradeType == TradeType.Buy)
152+
{
153+
double priceDiff = projectionPrice - Symbol.Bid;
154+
// Convert price difference to pips and calculate P&L.
155+
projectedPL = (priceDiff / Symbol.PipSize) * pointValue;
156+
}
157+
else // Sell position.
158+
{
159+
// For sell positions, we need to account for spread.
160+
double spread = Symbol.Ask - Symbol.Bid;
161+
double projectedAsk = projectionPrice + spread;
162+
double priceDiff = Symbol.Ask - projectedAsk;
163+
// Convert price difference to pips and calculate P&L.
164+
projectedPL = (priceDiff / Symbol.PipSize) * pointValue;
165+
}
166+
167+
totalPLChange += projectedPL;
168+
}
169+
170+
// Calculate projected equity.
171+
projectedEquity = currentEquity + totalPLChange;
172+
173+
// Update display.
174+
UpdateLabel();
175+
}
176+
177+
private void DrawProjectionLine()
178+
{
179+
if (projectionPrice <= 0) return;
180+
181+
// Remove existing line if it exists.
182+
if (projectionLine != null)
183+
{
184+
Chart.RemoveObject(LineObjectName);
185+
}
186+
187+
// Create new horizontal line.
188+
projectionLine = Chart.DrawHorizontalLine(
189+
LineObjectName,
190+
projectionPrice,
191+
LineColor,
192+
LineWidth,
193+
LineStyleParam
194+
);
195+
196+
projectionLine.IsInteractive = true;
197+
projectionLine.Comment = "Drag to change projection price";
198+
199+
// Add or update label.
200+
UpdateLabel();
201+
}
202+
203+
private void UpdateLabel()
204+
{
205+
if (projectionPrice <= 0 || !ShowLabel) return;
206+
207+
// Ensure line exists.
208+
if (projectionLine == null || Chart.FindObject(LineObjectName) == null)
209+
{
210+
DrawProjectionLine();
211+
}
212+
213+
// Remove existing label.
214+
if (equityLabel != null)
215+
{
216+
Chart.RemoveObject(EquityLabelObjectName);
217+
}
218+
219+
// Format equity text with proper decimal places.
220+
string equityText = EquityLabelPrefix + projectedEquity.ToString("F2");
221+
222+
// Calculate color based on equity change.
223+
double currentEquity = Account.Equity;
224+
Color equityColor = LineColor;
225+
if (projectedEquity > currentEquity)
226+
equityColor = LabelPositiveChangeColor;
227+
else if (projectedEquity < currentEquity)
228+
equityColor = LabelNegativeChangeColor;
229+
230+
// Get the leftmost visible bar index.
231+
int firstVisibleBar = Chart.FirstVisibleBarIndex;
232+
233+
// Create label at the left side of the chart.
234+
equityLabel = Chart.DrawText(
235+
EquityLabelObjectName,
236+
equityText,
237+
firstVisibleBar,
238+
projectionPrice,
239+
equityColor
240+
);
241+
242+
equityLabel.FontSize = 12;
243+
equityLabel.HorizontalAlignment = HorizontalAlignment.Right;
244+
equityLabel.VerticalAlignment = VerticalAlignment.Top;
245+
equityLabel.IsInteractive = false;
246+
}
247+
248+
private void ToggleVisibility()
249+
{
250+
if (isVisible)
251+
{
252+
// Hide objects.
253+
if (projectionLine != null)
254+
{
255+
projectionLine.IsHidden = true;
256+
}
257+
if (equityLabel != null)
258+
{
259+
equityLabel.IsHidden = true;
260+
}
261+
}
262+
else
263+
{
264+
// Show objects.
265+
if (projectionLine != null)
266+
{
267+
projectionLine.IsHidden = false;
268+
}
269+
if (equityLabel != null)
270+
{
271+
equityLabel.IsHidden = false;
272+
}
273+
}
274+
}
275+
}
276+
}
277+
//+------------------------------------------------------------------+

0 commit comments

Comments
 (0)