Warning! This section will be deprecated on February 1st 2025. Please move all your Indicators to the cTrader Store catalogue.
Description
This indicator is to solve the problem cTrader ver 4.4.12 removed to access and edit the icon's comments
For problem details, please see: https://ctrader.com/forum/ctrader-support/39021
Usage:
1. Select Icon, Alt + D to popup a ChartText with the icon's comment;
2. Edit ChartText as needed;
3. Alt + D to save revised comments, hit again to hide popup ChartText;
Interested in the currency strength meter in the chart?
Get the free download link at Telegram Group: cTrader FOREX Club
using System;
using System.IO;
using System.Linq;
using cAlgo.API;
//This indicator is to solve the problem cTrader ver 4.4.12 removed to access and edit the icon's comments
//Problem details see: https://ctrader.com/forum/ctrader-support/39021
//Usage:
//1. Select Icon, Alt + D to popup a ChartText with the icon's comment;
//2. Edit ChartText as needed;
//3. Alt + D to save revised comments, hit again to hide popup ChartText;
//4. Alt + C to make a copy of comments box;
//5. Alt + E to remove copied comments box;
//
//Ver 1.01 Optimise : Short cut key change to only Alt + D, save and hide ChartText;
// 1.02 Optimise : Short cut key change to only Alt + D, unhide, save and hide ChartText;
// : Temporarily fill with 'empty...' if Icon has no comment;
// 1.03 Add Function : Can edit Trendline and Rectangle's comments;
// 1.04 Optimise : MakeSure Textbox is interactive; TextBox can be seen(in the last trading day) if Trendline too old;
// Optimise : Framework .NET 6.0 ready;
// 1.05 Optimise : Use IsInteractive to hide CommentTextBox; Code Structure; CommentTextBox color is not transparent;
// 1.06 Add Function : Alt + X: quick (Un)Lock select trendlines, rectangles, icons, text box;
// 1.07 Optimise : Fixed bug of Alt + D to display textbox immediately;
// Optimise : Put Comments-Box in the mid of chart for TrendLine, Rectangle, HorizentalLine;
// Add Function : Alt + X: can (Un)Lock ChartArrowLines;
// Add Function : Can edit HorizentalLine's Comments;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class EditIconCmmt : Indicator
{
string s_objnme, s_objsve, s_objcmt;//Object Name, Save, Comment
double db_obj_Y; //Object Y-Value
int i_ObjIdx; //Object Bar-Index
Color cl_objCl; //Object Color
private ChartText tx_Cmmt, tx_Copy; //ChartTextBox to display,edit ObjectComment; Copy of ObjectComment;
private ChartStaticText sx_RorS; //Display control process
private ChartObjectType ty_Obj; //Record Select Object ChartObjectType
private readonly static string pfx_CmX = "Cmmt_Tx", pfx_Cms="RorS"; //Prifix : at Name of ObjectCommentTextBox, ControlMessage Text;
private readonly static string sfx_Cpy = "- CmtCpy"; //Sufix : at Name of Copy of ObjectComment;
private readonly static string cnt_Ept = "empty...", nEp=""; //Content: Temperary to fill ObjectCommentTextBox; SymbolEmpty;
private readonly static string act_Sve = " comment saved..."; //Action : ObjectComment saved
private readonly static string act_Hdn = " comment hidden..."; //Action : ObjectComment hidden
private readonly static string act_Cpy = " comment coppied..."; //Action : ObjectComment copy
private readonly static string act_Rmv = " comment removed..."; //Action : ObjectComment remove
private readonly static string act_unL = "Selected objects free now..."; //Action : Objects unlocked
private readonly static string act_Lck = "Selected objects locked..."; //Action : Objects locked
protected override void Initialize()
{ //System.Diagnostics.Debugger.Launch();
Chart.KeyDown += Chart_KeyDown; //HotKeys to SaveChange;
Chart.ObjectsSelectionChanged += Chart_ObjectsSelectionChanged; //Select Icons to popup comments in ChartText;
//Prepare ObjectCommentText and PopupMessageText
sx_RorS = Chart.DrawStaticText(pfx_Cms, string.Format(nEp), VerticalAlignment.Bottom, HorizontalAlignment.Right, Color.Red); sx_RorS.IsHidden=false;
}
public override void Calculate(int index) {}
//Select effective object to prepare CommentTextBox, hidden yet
private void Chart_ObjectsSelectionChanged(ChartObjectsSelectionChangedEventArgs obj)
{
//Exempt object numbers selected (only work for 1 object) - Update Name of SelectObject
if ( Chart.SelectedObjects.Count()==0 ) //Clear Message when select no object
{ PPmsg(nEp,false); }
else if ( Chart.SelectedObjects.Count()==1 ) //Record SelectObject's Name,Type,Comments
{
if ( Chart.SelectedObjects[0].Name!=pfx_CmX ) //Don't do, if tx_Cmmt is selected
{
s_objnme = Chart.SelectedObjects[0].Name; //SelectObjectName
ty_Obj = Chart.SelectedObjects[0].ObjectType; //ChartObjectType
s_objsve = s_objnme; //NameToSave
s_objcmt = Chart.SelectedObjects[0].Comment; //Comment Content
int iStr = Chart.FirstVisibleBarIndex; //Get the first bar-index in Chart
int iEnd = Chart.LastVisibleBarIndex; //Get the last bar-index in Chart
int iMid = (iStr + iEnd) / 2; //Get the mid bar-index in Chart
switch (ty_Obj) //Record ObjectTime, Y-Value
{
case ChartObjectType.Icon : var Ics=Chart.FindAllObjects(ChartObjectType.Icon ).Where(x => x.Name==s_objnme); foreach (ChartIcon ic in Ics) { int iT=Bars.OpenTimes.GetIndexByTime(ic.Time ); i_ObjIdx = iT; db_obj_Y = ic.Y; cl_objCl = ic.Color; } break;
case ChartObjectType.TrendLine : var Trs=Chart.FindAllObjects(ChartObjectType.TrendLine ).Where(x => x.Name==s_objnme); foreach (ChartTrendLine tr in Trs) { int iT=Bars.OpenTimes.GetIndexByTime(tr.Time1); i_ObjIdx = iT<iStr ? iMid : iT; db_obj_Y = tr.Y1; cl_objCl = tr.Color; } break;
case ChartObjectType.Rectangle : var Rts=Chart.FindAllObjects(ChartObjectType.Rectangle ).Where(x => x.Name==s_objnme); foreach (ChartRectangle rt in Rts) { int iT=Bars.OpenTimes.GetIndexByTime(rt.Time1); i_ObjIdx = iT<iStr ? iMid : iT; db_obj_Y = rt.Y1; cl_objCl = rt.Color; } break;
case ChartObjectType.HorizontalLine : var Hls=Chart.FindAllObjects(ChartObjectType.HorizontalLine).Where(x => x.Name==s_objnme); foreach (ChartHorizontalLine hl in Hls) { i_ObjIdx = iMid ; db_obj_Y = hl.Y ; cl_objCl = hl.Color; } break;
default: return;
}
RemvCmTx(); //Remove comments box first to avoid mis-saving
}
}
else if ( Chart.SelectedObjects.Count()>=2 ) //Select multiple object to remove comment box
{ RemvCmTx(); }
}
//Alt+D,C,E: to Popup,Copy,Erase CommentTextBox
private void Chart_KeyDown(ChartKeyboardEventArgs obj)
{
if (obj.AltKey)
{
if (obj.Key.Equals(Key.D)) //Alt + D: to Edit,Save,Hide ObjectComment
{
var Txs= Chart.FindAllObjects(ChartObjectType.Text).Where(x => x.Name==pfx_CmX);
if ( Txs.Count() == 0 ) //First hit to write & display comment;
{
int iStr = Chart.FirstVisibleBarIndex; //Get the first bar-index in Chart
int iEnd = Chart.LastVisibleBarIndex; //Get the last bar-index in Chart
int iMid = (iStr + iEnd) / 2; //Get the mid bar-index in Chart
switch (ty_Obj) //Prepare ObjectCommentText according to ObjectType
{ // ↓↓ Visiable in chart ↓↓ Not transparent
case ChartObjectType.Icon : var Ics=Chart.FindAllObjects(ChartObjectType.Icon ).Where(x => x.Name==s_objnme); foreach (ChartIcon ic in Ics) { int iT=Bars.OpenTimes.GetIndexByTime(ic.Time ); ReadCmTx(ic.Comment, iT, ic.Y, Color.FromArgb(255,ic.Color)); } break;
case ChartObjectType.TrendLine : var Trs=Chart.FindAllObjects(ChartObjectType.TrendLine ).Where(x => x.Name==s_objnme); foreach (ChartTrendLine tr in Trs) { int iT=Bars.OpenTimes.GetIndexByTime(tr.Time1); ReadCmTx(tr.Comment, iT<iStr ? iMid : iT, tr.Y1, Color.FromArgb(255,tr.Color)); } break;
case ChartObjectType.Rectangle : var Rts=Chart.FindAllObjects(ChartObjectType.Rectangle ).Where(x => x.Name==s_objnme); foreach (ChartRectangle rt in Rts) { int iT=Bars.OpenTimes.GetIndexByTime(rt.Time1); ReadCmTx(rt.Comment, iT<iStr ? iMid : iT, rt.Y1, Color.FromArgb(255,rt.Color)); } break;
case ChartObjectType.HorizontalLine : var Hls=Chart.FindAllObjects(ChartObjectType.HorizontalLine).Where(x => x.Name==s_objnme); foreach (ChartHorizontalLine hl in Hls) { ReadCmTx(hl.Comment, iMid , hl.Y , Color.FromArgb(255,hl.Color)); } break;
default: return;
}
}
else //Hit again to save if comment changed;
{
if ( tx_Cmmt.Text != s_objcmt && tx_Cmmt.Text != cnt_Ept)
{
switch (ty_Obj) //Works only at the ObjectSelected
{ // Save comments to Object, Update Comments to compare
case ChartObjectType.Icon : var Ics=Chart.FindAllObjects(ChartObjectType.Icon ).Where(x => x.Name==s_objnme); foreach (ChartIcon ic in Ics) { ic.Comment=tx_Cmmt.Text; s_objcmt=tx_Cmmt.Text; } break;
case ChartObjectType.TrendLine : var Trs=Chart.FindAllObjects(ChartObjectType.TrendLine ).Where(x => x.Name==s_objnme); foreach (ChartTrendLine tr in Trs) { tr.Comment=tx_Cmmt.Text; s_objcmt=tx_Cmmt.Text; } break;
case ChartObjectType.Rectangle : var Rts=Chart.FindAllObjects(ChartObjectType.Rectangle ).Where(x => x.Name==s_objnme); foreach (ChartRectangle rt in Rts) { rt.Comment=tx_Cmmt.Text; s_objcmt=tx_Cmmt.Text; } break;
case ChartObjectType.HorizontalLine : var Hls=Chart.FindAllObjects(ChartObjectType.HorizontalLine).Where(x => x.Name==s_objnme); foreach (ChartHorizontalLine hl in Hls) { hl.Comment=tx_Cmmt.Text; s_objcmt=tx_Cmmt.Text; } break;
default: return;
}
PPmsg(s_objsve+act_Sve, false);
}
else { RemvCmTx(); PPmsg(s_objnme+act_Hdn, true); } //Hit again to Remove comment TextBox;
}
} //Alt + D: to Edit,Save,Hide ObjectComment
else if (obj.Key.Equals(Key.C)) //Alt + C: Leave a Copy Unhiden for ObjectComment
{
tx_Copy = Chart.DrawText(s_objnme+sfx_Cpy, s_objcmt == nEp ? cnt_Ept : s_objcmt, i_ObjIdx, db_obj_Y, Color.FromArgb(255,cl_objCl));
//Put CopyCommentBox at proper position by ObjectType
switch (ty_Obj)
{
case ChartObjectType.Icon : tx_Copy.HorizontalAlignment=HorizontalAlignment.Left; break; //Left beside Icon
case ChartObjectType.TrendLine: tx_Copy.HorizontalAlignment=HorizontalAlignment.Right; break; //LeftBottom Trendline
case ChartObjectType.Rectangle: tx_Copy.HorizontalAlignment=HorizontalAlignment.Right; break; //LeftBotton Rectangle
default: return;
}
tx_Copy.IsHidden=false; tx_Copy.IsInteractive=true; tx_Copy.IsLocked=true; //Display CommentBoxCopy
RemvCmTx(); //Hide CommentsTextBox
PPmsg(s_objsve+act_Cpy, false);
} //Alt + C: Leave a Copy Unhiden for ObjectComment
else if (obj.Key.Equals(Key.E)) //Alt + E: Remove Copied ObjectCommentTextBox, Hide CommentTextBox;
{
var Txs=Chart.FindAllObjects(ChartObjectType.Text).Where(x => x.Name.Contains(s_objnme)); foreach (ChartText Tx in Txs) { Chart.RemoveObject(Tx.Name); }
RemvCmTx(); //Hide CommentsTextBox
PPmsg(s_objsve+act_Rmv, true);
} //Alt + E: Remove Copied ObjectCommentTextBox, Hide CommentTextBox;
else if (obj.Key.Equals(Key.X)) //Alt + X: (Un)Lock select trendlines, rectangles, icons;
{
string s_nm = string.Empty;
//Check all SelectedObjects
for (int i = 0; i < Chart.SelectedObjects.Count; i++ )
{
s_nm = Chart.SelectedObjects[i].Name;
if (Chart.SelectedObjects[i].ObjectType == ChartObjectType.ArrowLine)
{ var ALs = Chart.FindAllObjects(ChartObjectType.ArrowLine).Where( x => x.Name==s_nm ); foreach (ChartArrow al in ALs) { al.IsLocked = !al.IsLocked; PPmsg(al.IsLocked ? act_Lck : act_unL, false);} }
if (Chart.SelectedObjects[i].ObjectType == ChartObjectType.TrendLine)
{ var Trs = Chart.FindAllObjects(ChartObjectType.TrendLine).Where( x => x.Name==s_nm ); foreach (ChartTrendLine tr in Trs) { tr.IsLocked = !tr.IsLocked; PPmsg(tr.IsLocked ? act_Lck : act_unL, false);} }
else if (Chart.SelectedObjects[i].ObjectType == ChartObjectType.Rectangle)
{ var Rts = Chart.FindAllObjects(ChartObjectType.Rectangle).Where( x => x.Name==s_nm ); foreach (ChartRectangle rt in Rts) { rt.IsLocked = !rt.IsLocked; PPmsg(rt.IsLocked ? act_Lck : act_unL, false);} }
else if (Chart.SelectedObjects[i].ObjectType == ChartObjectType.Icon)
{ var Ics = Chart.FindAllObjects(ChartObjectType.Icon) .Where( x => x.Name==s_nm ); foreach (ChartIcon ic in Ics) { ic.IsLocked = !ic.IsLocked; PPmsg(ic.IsLocked ? act_Lck : act_unL, false);} }
else if (Chart.SelectedObjects[i].ObjectType == ChartObjectType.Text)
{ var Txs = Chart.FindAllObjects(ChartObjectType.Text) .Where( x => x.Name==s_nm ); foreach (ChartText tx in Txs) { tx.IsLocked = !tx.IsLocked; PPmsg(tx.IsLocked ? act_Lck : act_unL, false);} }
}
} //Alt + X: (Un)Lock select trendlines, rectangles, icons;
}
}
//Read the SelectObject comment to display;
private void ReadCmTx(string s_CmTx, int i_CmTx, double Y_CmTx, Color cl_CmTx)
{
//Read(Display) Comments content
tx_Cmmt = Chart.DrawText(pfx_CmX, (s_CmTx == nEp) ? cnt_Ept : s_CmTx, i_CmTx, 0, cl_CmTx);
tx_Cmmt.Time = Bars[i_CmTx].OpenTime; tx_Cmmt.Y = Y_CmTx; tx_Cmmt.FontSize = 14;
tx_Cmmt.IsInteractive = true; tx_Cmmt.IsLocked = false;
tx_Cmmt.HorizontalAlignment=HorizontalAlignment.Right;
}
//Set CommentTextBox (Un)Hidden
private void RemvCmTx()
{ if ( Chart.FindAllObjects(ChartObjectType.Text).Where(x => x.Name==pfx_CmX).Count() > 0 ) { Chart.RemoveObject(tx_Cmmt.Name); } }
//Popup Control Message
private void PPmsg(string msg, bool ishidden)
{
if (ishidden) { sx_RorS.Text = nEp; sx_RorS.IsHidden = true ; }
else { sx_RorS.Text = msg; sx_RorS.IsHidden = false; }
}
}
}
Capt.Z-Fort.Builder
Joined on 03.06.2020
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: Edit Icon Comment.algo
- Rating: 5
- Installs: 920
- Modified: 19/07/2023 22:32
Note that publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section, please use the Copyright Infringement Notification form to submit a claim.
Comments
Log in to add a comment.
No comments found.