Login Page - Create Account

Support Board


Date/Time: Fri, 06 Sep 2024 09:04:23 +0000



[User Discussion] - ACSIL - how to delete (ACSIL) user drawings when time frame is changed?

View Count: 4941

[2013-07-21 14:47:34]
User11748 - Posts: 14
Hi,

I am coding a study which draws (with ACSIL) many "tools" declared as user drawings.
It works fine, except for the following issue.

When I change the timeframe of the chart (for instance from 10m to 30m), the "old" drawings (10m) stay on the chart, and the "new" drawings (30m) are added to them. So there are 2 sets of drawings on the chart, whereas I would expect "old" drawings to be deleted. When I change again the timeframe (for instance to 60m), a third set of drawings appears. Then, if I come back to the initial timeframe (10m), it does not look the same at the beginning, since all previously drawn drawings appear together.

I have already implemented "if (sc.LastCallToFunction) { ... }" to delete the drawings when the study is removed from the chart, and it works fine. However, it seems that sc.LastCallToFunction is not "called" when the user changes the timeframe.

So how to programmatically delete the "old" (ACSIL) user drawings when the timeframe is changed, before "new" (ACSIL) user drawings are drawn by the study?

Thanks in advance for your help! :)

Nicolas
Date Time Of Last Edit: 2013-07-22 08:11:29
[2013-07-21 16:08:56]
StevieD - Posts: 39
Just thinking out loud here...

Use a PersistVar to store sc.SecondsPerBar.
Do this only when you do the first drawing in a given timeframe.

Add a PersistVar compare to the sc.LastCallToFunction block
if (sc.LastCallToFunction || (sc.PersistVar->i1 > 0 && sc.PersistVar->i1 != sc.SecondsPerBar))
{
// delete "old" drawings
// reset PersistVar to 0
}

Again, just thinking out loud.
Date Time Of Last Edit: 2013-07-21 16:16:56
[2013-07-21 17:06:06]
User11748 - Posts: 14
Hi StevieD,

Thanks a lot for such "thinking out loud"! :)

Unfortunately, I have tested your idea, and I have not managed to obtain a deletion of "old" drawings.
I am not sure, but perhaps the reason is that, when "sc.PersistVar->i1 != sc.SecondsPerBar", the study has already been reloaded.

Thanks again!

Nicolas
Date Time Of Last Edit: 2013-07-21 17:24:07
[2013-07-22 08:10:22]
User11748 - Posts: 14
I have prepared (below) a minimal 40-line code in order to better show the issue I am reporting.
This code draws a marker (ACSIL user drawing) 10 bars before the 1st bar of July 19th, 2013.
When timeframe is changed, new marker appears, but old ones stay on the chart. How to programmatically delete them?
The issue is illustrated on the attached picture, with comments embedded.

#include "sierrachart.h"

SCDLLName("Nicolas Test 2");

SCSFExport scsf_Nicolas_Test_2(SCStudyGraphRef sc) {

  if ( sc.SetDefaults ) {
    sc.GraphName = "Nicolas Test 2";
    sc.AutoLoop = 1;
    sc.FreeDLL = 1;
    sc.GraphRegion = 0;
    return;
  }

  int UniqueLineNumber = 74191;

  if ( sc.LastCallToFunction && sc.PersistVars->i1 > 0 ) {
    sc.DeleteUserDrawnACSDrawing(sc.ChartNumber, UniqueLineNumber + sc.PersistVars->i1);
  }

  bool firstBarOfJuly_19_2003 = sc.BaseDateTimeIn[sc.Index].GetYear() == 2013
    && sc.BaseDateTimeIn[sc.Index].GetMonth() == 7
    && sc.BaseDateTimeIn[sc.Index].GetDay() == 19
    && sc.BaseDateTimeIn[sc.Index-1].GetDay() != 19;

  if ( firstBarOfJuly_19_2003 ) {
    sc.PersistVars->i1 = sc.Index - 10; // index of the bar on top of which the marker shall be drawn
    s_UseTool Tool;
    Tool.Clear();
    Tool.ChartNumber = sc.ChartNumber;
    Tool.DrawingType = DRAWING_MARKER;
    Tool.LineNumber = UniqueLineNumber + sc.PersistVars->i1;
    Tool.BeginIndex = sc.PersistVars->i1;
    Tool.BeginValue = sc.High[sc.PersistVars->i1];
    Tool.Color = RGB(0,200,200);
    Tool.AddMethod = UTAM_ADD_ALWAYS;
    Tool.MarkerType = MARKER_X;
    Tool.MarkerSize = 8;
    Tool.LineWidth = 5;
    Tool.AddAsUserDrawnDrawing = 1; // ***
    sc.UseTool(Tool);
  }
}

Date Time Of Last Edit: 2013-07-22 08:15:01
image2013-07-22_SC.png / V - Attached On 2013-07-22 08:13:56 UTC - Size: 264.14 KB - 728 views
[2013-07-22 23:07:13]
Kiwi - Posts: 375
Have you tried the delete functions

http://www.sierrachart.com/index.php?l=doc/doc_DLLTools.html#scDeleteLineOrText

In such a situation I would store the current timeframe in a persistent variable and if it changed I would issue a command to delete it ...

perhaps you are using DeleteUserDrawnACSDrawing and you should just use scDeleteLineOrText ... thats the command I have used for this purpose in the past. Not sure but try changing it - and if it doesn't work you might add something to be sure its being called (create a unique tool when it is invoked or send a message to the log say).
Date Time Of Last Edit: 2013-07-22 23:08:29
[2013-07-23 07:13:28]
User11748 - Posts: 14
Thanks, Kiwi, for this suggestion. :) But I am afraid that it does not solve the issue.

1. I am not sure that this function applies to ACSIL user drawings. Documentation of the function says that "it is not possible to delete user drawn chart drawings.", but it not clear whether it refers to "real" user drawings or ACSIL user drawings.

2. By the way, I have the feeling that one sentence of the documentation of this function is erroneous: "When a study is removed from the chart, or when it is recalculated, and it has chart drawings added with sc.UseTool(), these chart drawings are automatically deleted from the chart." I think that it does not apply to ACSIL drawings declared as user drawings (Tool.AddAdUserDrawnDrawing = 1).

3. Anyway, I tried to use it.

if ( sc.LastCallToFunction ) {
int res = sc.DeleteLineOrText(sc.ChartNumber, TOOL_DELETE_ALL, 0);
}

This code remains useless this sc.LastCallToFunction is not switched to true when the study is recalculated following a change of time frame.

I tried the following:

if ( sc.Index == 0 ) {
int res = sc.DeleteLineOrText(sc.ChartNumber, TOOL_DELETE_ALL, 0);
SCString buffer; buffer.Format("sc.Index == 0 ; res = %i", res); sc.AddMessageToLog(buffer, 1);
}

When the study is recalculated, the "old" drawings do not disappear (same behaviour that the image previously posted) and the value returned by sc.DeleteLineOrText is 0. I guess that when sc.Index == 0 (beginning of the recalculation), the study has already lost track of the "old" drawings (which, however, stay on the chart).

Thanks again for your help!

Nicolas

PS - Reminder of the question for SC team, in case you notice the thread at this stage. I have a study which creates ACSIL user drawings (Tool.AddAsUserDrawnDrawing = 1). How is it possible to programmatically delete them when the timeframe is changed (sc.LastCallToFunction is useless in this case) before the study is recalculated, in order to avoid having 2 sets of drawings on the chart (the old ones and the new ones). Minimal 40-line code and screenshot above. Thanks! :)
Date Time Of Last Edit: 2013-07-23 07:14:55
[2013-07-23 07:32:29]
Kiwi - Posts: 375
I'll have a look at your code and see if I can spot anything.
[2013-07-23 07:44:49]
Kiwi - Posts: 375
Ok. I'm not sure I resolved your question but I may have solved your problem.

If all you want is that drawing number xxxx+yyy is replaced by a new version when the timeframe is changed then:

Change the tool add method to:
Tool.AddMethod = UTAM_ADD_OR_ADJUST;

Actually I did leave your delete command in so I don't know what it now does. But the only change to your code required to make it replace the old with the new is the line shown above. Hope that helps. Hmmm... Just tested that change ... I must have "fixed something else as well" for mine to work.

Ahhh ... the other problem is that you are adding sc.Index-10 to the LineNumber and that changes .... you need to ensure that the number isn't changing.


Date Time Of Last Edit: 2013-07-23 07:54:41
[2013-07-23 07:58:16]
Kiwi - Posts: 375
Scrap the last post ...

Just took your original code again and set i1 = 0

Thats the problem. Your value of i1 changed each time you changed the seconds per bar. As a result your delete command didn't work.

Working code is:

SCSFExport scsf_Nicolas_Test_2(SCStudyGraphRef sc) {

if ( sc.SetDefaults ) {
sc.GraphName = "Nicolas Test 2";
sc.AutoLoop = 1;
sc.FreeDLL = 1;
sc.GraphRegion = 0;
return;
}

int UniqueLineNumber = 74191;

if ( sc.LastCallToFunction && sc.PersistVars->i1 > 0 ) {
sc.DeleteUserDrawnACSDrawing(sc.ChartNumber, UniqueLineNumber + sc.PersistVars->i1);
}

bool firstBarOfJuly_19_2003 = sc.BaseDateTimeIn[sc.Index].GetYear() == 2013
&& sc.BaseDateTimeIn[sc.Index].GetMonth() == 7
&& sc.BaseDateTimeIn[sc.Index].GetDay() == 19
&& sc.BaseDateTimeIn[sc.Index-1].GetDay() != 19;

if ( firstBarOfJuly_19_2003 ) {
sc.PersistVars->i1 = sc.Index - 10; // index of the bar on top of which the marker shall be drawn
i1 = 0 // set it to a constant for testing
  s_UseTool Tool;
Tool.Clear();
Tool.ChartNumber = sc.ChartNumber;
Tool.DrawingType = DRAWING_MARKER;
Tool.LineNumber = UniqueLineNumber + sc.PersistVars->i1;
Tool.BeginIndex = sc.PersistVars->i1;
Tool.BeginValue = sc.High[sc.PersistVars->i1];
Tool.Color = RGB(0,200,200);
Tool.AddMethod = UTAM_ADD_ALWAYS;
Tool.MarkerType = MARKER_X;
Tool.MarkerSize = 8;
Tool.LineWidth = 5;
Tool.AddAsUserDrawnDrawing = 1; // ***
sc.UseTool(Tool);
}
}

[2013-07-23 09:15:43]
User11748 - Posts: 14
Kiwi,

Thanks a lot for your efforts to help me! :)

Are you sure you attached the "working code"? :)

It does not compile on my computer. I think that the compiler does not understand what i1 means.
Unfortunately, even if I "comment" (//) the "i1" line, the behaviour stays the same ("old" marker stays on the chart when we change time frame). This could be understood since the code does not contain any deletion command (except the one when the study is removed from the chart, with sc.LastCallToFunction).

Nicolas
[2013-07-23 09:31:56]
User11748 - Posts: 14
I think I found a solution.

One of your post made me realize that persistent variables are still persistent when study is fully recalculated, whereas I thought that it was set again to 0 at the beginning of the recalculation.

So I have simply added this piece of code:
// If study is recalculated, let's delete the old marker:
if ( sc.Index == 0 ) {
sc.DeleteUserDrawnACSDrawing(sc.ChartNumber, UniqueLineNumber + sc.PersistVars->i1);
}

I have implemented this change in my bigger projects, and it seems to work. Problem solved.

Full code is below.

Thanks again for your help!

Nicolas

#include "sierrachart.h"

SCDLLName("Nicolas Test 2");

SCSFExport scsf_Nicolas_Test_2(SCStudyGraphRef sc) {

  if ( sc.SetDefaults ) {
    sc.GraphName = "Nicolas Test 2";
    sc.AutoLoop = 1;
    sc.FreeDLL = 1;
    sc.GraphRegion = 0;
    return;
  }

  int UniqueLineNumber = 74191;

  // If study is recalculated, let's delete the old marker:
  if ( sc.Index == 0 ) {
    sc.DeleteUserDrawnACSDrawing(sc.ChartNumber, UniqueLineNumber + sc.PersistVars->i1);
  }

  // If study is removed, let's delete the marker:
  if ( sc.LastCallToFunction && sc.PersistVars->i1 > 0 ) {
    sc.DeleteUserDrawnACSDrawing(sc.ChartNumber, UniqueLineNumber + sc.PersistVars->i1);
  }

  bool firstBarOfJuly_19_2003 = sc.BaseDateTimeIn[sc.Index].GetYear() == 2013
    && sc.BaseDateTimeIn[sc.Index].GetMonth() == 7
    && sc.BaseDateTimeIn[sc.Index].GetDay() == 19
    && sc.BaseDateTimeIn[sc.Index-1].GetDay() != 19;

  if ( firstBarOfJuly_19_2003 ) {
    sc.PersistVars->i1 = sc.Index - 10; // index of the bar on top of which the marker shall be drawn
    s_UseTool Tool;
    Tool.Clear();
    Tool.ChartNumber = sc.ChartNumber;
    Tool.DrawingType = DRAWING_MARKER;
    Tool.LineNumber = UniqueLineNumber + sc.PersistVars->i1;
    Tool.BeginIndex = sc.PersistVars->i1;
    Tool.BeginValue = sc.High[sc.PersistVars->i1];
    Tool.Color = RGB(0,200,200);
    Tool.AddMethod = UTAM_ADD_ALWAYS;
    Tool.MarkerType = MARKER_X;
    Tool.MarkerSize = 8;
    Tool.LineWidth = 5;
    Tool.AddAsUserDrawnDrawing = 1; // ***
    sc.UseTool(Tool);
  }
}



[2013-07-25 12:16:30]
Sierra Chart Engineering - Posts: 104368
Glancing at the image in post #4, the simple solution would be to use:

Tool.AddMethod =UTAM_ADD_OR_ADJUST;

Rather than deleting the drawing. Although you would need to delete when the study is removed.
Sierra Chart Support - Engineering Level

Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy:
https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation

For the most reliable, advanced, and zero cost futures order routing, *change* to the Teton service:
Sierra Chart Teton Futures Order Routing
Date Time Of Last Edit: 2013-07-25 12:54:48
[2013-07-25 12:52:53]
User11748 - Posts: 14
Thanks for your idea. :)

If I make no mistake, the method you propose requires the LineNumber to be the same before and after the reloading.

Nicolas
[2013-07-25 12:55:10]
Sierra Chart Engineering - Posts: 104368
Yes
Sierra Chart Support - Engineering Level

Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy:
https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation

For the most reliable, advanced, and zero cost futures order routing, *change* to the Teton service:
Sierra Chart Teton Futures Order Routing

To post a message in this thread, you need to log in with your Sierra Chart account:

Login

Login Page - Create Account