Support Board
Date/Time: Sun, 15 Jun 2025 06:52:52 +0000
[Programming Help] - ACSIL study
View Count: 209
[2025-06-08 00:49:19] |
User936417 - Posts: 16 |
Are there internal limitations in how Sierra Chart makes those drawings accessible to ACSIL studies—especially for manual DRAWING_LINE tools.I am trying to write a study that projects lines 12, 15, and 22 points beyond a newly drawn Line tool line. I have a successful build with subgraphs and all but the projected lines will not appear.
|
[2025-06-08 09:21:52] |
User431178 - Posts: 711 |
Are there internal limitations in how Sierra Chart makes those drawings accessible to ACSIL studies—especially for manual DRAWING_LINE tools
No, you can access all of those.I am trying to write a study that projects lines 12, 15, and 22 points beyond a newly drawn Line tool line. I have a successful build with subgraphs and all but the projected lines will not appear.
If you want help, you'll need to post the code.
|
[2025-06-08 23:57:51] |
User936417 - Posts: 16 |
Here is the code: #include "sierrachart.h" SCDLLName("Line Tool Projections") #ifndef DRAWING_LINE #define DRAWING_LINE 8 #endif SCSFExport scsf_LineToolProjections(SCStudyInterfaceRef sc) { SCInputRef Level1 = sc.Input[0]; SCInputRef Level2 = sc.Input[1]; SCInputRef Level3 = sc.Input[2]; SCInputRef ShowLevelValues = sc.Input[3]; // Subgraphs for projected level outputs SCSubgraphRef Level1Up = sc.Subgraph[0]; SCSubgraphRef Level2Up = sc.Subgraph[1]; SCSubgraphRef Level3Up = sc.Subgraph[2]; SCSubgraphRef Level1Down = sc.Subgraph[3]; SCSubgraphRef Level2Down = sc.Subgraph[4]; SCSubgraphRef Level3Down = sc.Subgraph[5]; if (sc.SetDefaults) { sc.GraphName = "Line Tool Projections"; sc.AutoLoop = 0; Level1.Name = "Projection Level 1 (points)"; Level1.SetInt(9); Level2.Name = "Projection Level 2 (points)"; Level2.SetInt(13); Level3.Name = "Projection Level 3 (points)"; Level3.SetInt(19); ShowLevelValues.Name = "Show Level Value Labels"; ShowLevelValues.SetYesNo(1); // Subgraph settings Level1Up.Name = "Level 1 Up"; Level1Up.DrawStyle = DRAWSTYLE_LINE; Level1Up.PrimaryColor = RGB(0, 255, 0); Level2Up.Name = "Level 2 Up"; Level2Up.DrawStyle = DRAWSTYLE_LINE; Level2Up.PrimaryColor = RGB(0, 200, 0); Level3Up.Name = "Level 3 Up"; Level3Up.DrawStyle = DRAWSTYLE_LINE; Level3Up.PrimaryColor = RGB(0, 150, 0); Level1Down.Name = "Level 1 Down"; Level1Down.DrawStyle = DRAWSTYLE_LINE; Level1Down.PrimaryColor = RGB(255, 0, 0); Level2Down.Name = "Level 2 Down"; Level2Down.DrawStyle = DRAWSTYLE_LINE; Level2Down.PrimaryColor = RGB(200, 0, 0); Level3Down.Name = "Level 3 Down"; Level3Down.DrawStyle = DRAWSTYLE_LINE; Level3Down.PrimaryColor = RGB(150, 0, 0); return; } if (sc.UpdateStartIndex != sc.ArraySize - 1) return; const int ToolType = static_cast<int>(DRAWING_LINE); const int DrawingCount = sc.GetACSDrawingsCount(sc.ChartNumber, ToolType); if (DrawingCount == 0) { sc.AddMessageToLog("LineToolProjections: No line drawings found.", 0); return; } for (int i = DrawingCount - 1; i >= 0; --i) { s_UseTool Tool; if (!sc.GetACSDrawingByIndex(sc.ChartNumber, i, Tool, ToolType)) continue; if (Tool.DrawingType != static_cast<DrawingTypeEnum>(DRAWING_LINE)) continue; float High = max(Tool.BeginValue, Tool.EndValue); float Low = min(Tool.BeginValue, Tool.EndValue); float Level1Val = static_cast<float>(Level1.GetInt()); float Level2Val = static_cast<float>(Level2.GetInt()); float Level3Val = static_cast<float>(Level3.GetInt()); float Levels[6] = { High + Level1Val, High + Level2Val, High + Level3Val, Low - Level1Val, Low - Level2Val, Low - Level3Val }; // Plot subgraph values Level1Up[sc.Index] = Levels[0]; Level2Up[sc.Index] = Levels[1]; Level3Up[sc.Index] = Levels[2]; Level1Down[sc.Index] = Levels[3]; Level2Down[sc.Index] = Levels[4]; Level3Down[sc.Index] = Levels[5]; // Draw horizontal projected lines for (int j = 0; j < 6; ++j) { s_UseTool LineTool; LineTool.Clear(); LineTool.ChartNumber = sc.ChartNumber; LineTool.DrawingType = static_cast<DrawingTypeEnum>(DRAWING_LINE); LineTool.BeginValue = Levels[j]; LineTool.BeginDateTime = sc.BaseDateTimeIn[sc.ArraySize - 1].GetAsDouble(); LineTool.Color = RGB(0, 255, 0); LineTool.AddMethod = UTAM_ADD_ALWAYS; if (ShowLevelValues.GetYesNo()) { char Label[32]; snprintf(Label, sizeof(Label), "%.2f", Levels[j]); LineTool.Text = Label; } sc.UseTool(LineTool); } break; // Only process most recent line } } |
[2025-06-09 12:33:33] |
User431178 - Posts: 711 |
If you want to interact with user drawn elements, then you need to use the appropriate functions. sc.GetUserDrawnDrawingsCount instead of sc.GetACSDrawingsCount sc.GetUserDrawnChartDrawing instead of sc.GetACSDrawingByIndex Using Drawing Tools From an Advanced Custom Study: sc.GetUserDrawnChartDrawing() |
[2025-06-10 01:03:22] |
User936417 - Posts: 16 |
thank you for your help. I am still not there. Build works but no lines are projected. I made the changes that you suggested above. i am getting the following in the message log: 2025-06-09 21:00:06.631 | Chart: ESM25_FUT_CME [CB][M] 5 Min #7 | Study: Line Tool Projections | LineToolProjections: No line drawings found. Here is the code with changes you suggested. #include "sierrachart.h" SCDLLName("Line Tool Projections") #ifndef DRAWING_LINE #define DRAWING_LINE 8 #endif SCSFExport scsf_LineToolProjections(SCStudyInterfaceRef sc) { SCInputRef Level1 = sc.Input[0]; SCInputRef Level2 = sc.Input[1]; SCInputRef Level3 = sc.Input[2]; SCInputRef ShowLevelValues = sc.Input[3]; // Subgraphs for projected level outputs SCSubgraphRef Level1Up = sc.Subgraph[0]; SCSubgraphRef Level2Up = sc.Subgraph[1]; SCSubgraphRef Level3Up = sc.Subgraph[2]; SCSubgraphRef Level1Down = sc.Subgraph[3]; SCSubgraphRef Level2Down = sc.Subgraph[4]; SCSubgraphRef Level3Down = sc.Subgraph[5]; if (sc.SetDefaults) { sc.GraphName = "Line Tool Projections"; sc.AutoLoop = 0; Level1.Name = "Projection Level 1 (points)"; Level1.SetInt(9); Level2.Name = "Projection Level 2 (points)"; Level2.SetInt(13); Level3.Name = "Projection Level 3 (points)"; Level3.SetInt(19); ShowLevelValues.Name = "Show Level Value Labels"; ShowLevelValues.SetYesNo(1); // Subgraph settings Level1Up.Name = "Level 1 Up"; Level1Up.DrawStyle = DRAWSTYLE_LINE; Level1Up.PrimaryColor = RGB(0, 255, 0); Level2Up.Name = "Level 2 Up"; Level2Up.DrawStyle = DRAWSTYLE_LINE; Level2Up.PrimaryColor = RGB(0, 200, 0); Level3Up.Name = "Level 3 Up"; Level3Up.DrawStyle = DRAWSTYLE_LINE; Level3Up.PrimaryColor = RGB(0, 150, 0); Level1Down.Name = "Level 1 Down"; Level1Down.DrawStyle = DRAWSTYLE_LINE; Level1Down.PrimaryColor = RGB(255, 0, 0); Level2Down.Name = "Level 2 Down"; Level2Down.DrawStyle = DRAWSTYLE_LINE; Level2Down.PrimaryColor = RGB(200, 0, 0); Level3Down.Name = "Level 3 Down"; Level3Down.DrawStyle = DRAWSTYLE_LINE; Level3Down.PrimaryColor = RGB(150, 0, 0); return; } if (sc.UpdateStartIndex != sc.ArraySize - 1) return; const int ToolType = static_cast<int>(DRAWING_LINE); const int DrawingCount = sc.GetUserDrawnDrawingsCount(sc.ChartNumber, ToolType); if (DrawingCount == 0) { sc.AddMessageToLog("LineToolProjections: No line drawings found.", 0); return; } for (int i = DrawingCount - 1; i >= 0; --i) { s_UseTool Tool; if (!sc.GetUserDrawnChartDrawing(sc.ChartNumber, i, Tool, ToolType)) continue; if (Tool.DrawingType != static_cast<DrawingTypeEnum>(DRAWING_LINE)) continue; float High = max(Tool.BeginValue, Tool.EndValue); float Low = min(Tool.BeginValue, Tool.EndValue); float Level1Val = static_cast<float>(Level1.GetInt()); float Level2Val = static_cast<float>(Level2.GetInt()); float Level3Val = static_cast<float>(Level3.GetInt()); float Levels[6] = { High + Level1Val, High + Level2Val, High + Level3Val, Low - Level1Val, Low - Level2Val, Low - Level3Val }; // Plot subgraph values Level1Up[sc.Index] = Levels[0]; Level2Up[sc.Index] = Levels[1]; Level3Up[sc.Index] = Levels[2]; Level1Down[sc.Index] = Levels[3]; Level2Down[sc.Index] = Levels[4]; Level3Down[sc.Index] = Levels[5]; // Draw horizontal projected lines for (int j = 0; j < 6; ++j) { s_UseTool LineTool; LineTool.Clear(); LineTool.ChartNumber = sc.ChartNumber; LineTool.DrawingType = static_cast<DrawingTypeEnum>(DRAWING_LINE); LineTool.BeginValue = Levels[j]; LineTool.BeginDateTime = sc.BaseDateTimeIn[sc.ArraySize - 1].GetAsDouble(); LineTool.Color = RGB(0, 255, 0); LineTool.AddMethod = UTAM_ADD_ALWAYS; if (ShowLevelValues.GetYesNo()) { char Label[32]; snprintf(Label, sizeof(Label), "%.2f", Levels[j]); LineTool.Text = Label; } sc.UseTool(LineTool); } break; // Only process most recent line } } |
[2025-06-10 08:16:59] |
User431178 - Posts: 711 |
thank you for your help. I am still not there. Build works but no lines are projected. I made the changes that you suggested above. i am getting the following in the message log: 2025-06-09 21:00:06.631 | Chart: ESM25_FUT_CME [CB][M] 5 Min #7 | Study: Line Tool Projections | LineToolProjections: No line drawings found. Here is the code with changes you suggested. const int DrawingCount = sc.GetUserDrawnDrawingsCount(sc.ChartNumber, ToolType); should be as below, drawing type is not used here const int DrawingCount = sc.GetUserDrawnDrawingsCount(sc.ChartNumber, 0); if (!sc.GetUserDrawnChartDrawing(sc.ChartNumber, i, Tool, ToolType)) continue; should be as below, you have things in the wrong order if (!sc.GetUserDrawnChartDrawing(sc.ChartNumber, DRAWING_LINE, Tool, i)) continue; If you want the last added / modified drawing you can dispense with the loop and simply enter -1 as the drawing index if (!sc.GetUserDrawnChartDrawing(sc.ChartNumber, DRAWING_LINE, Tool, -1)) return; #ifndef DRAWING_LINE #define DRAWING_LINE 8 #endif What is the purpose of this? DRAWING_LINE is defined by DrawingTypeEnum and has a value of 1, you can simply use the existing enum value as the function argument. When you cast your "DRAWING_LINE" to DrawingTypeEnum it becomes DrawingTypeEnum::DRAWING_RETRACEMENT. // Plot subgraph values Level1Up[sc.Index] = Levels[0]; Level2Up[sc.Index] = Levels[1]; Level3Up[sc.Index] = Levels[2]; Level1Down[sc.Index] = Levels[3]; Level2Down[sc.Index] = Levels[4]; Level3Down[sc.Index] = Levels[5]; You are using sc.AutoLoop = 0, therefore sc.Index would not be used, here you would need sc.ArraySize-1 instead (for example). // Draw horizontal projected lines for (int j = 0; j < 6; ++j) { s_UseTool LineTool; LineTool.Clear(); LineTool.ChartNumber = sc.ChartNumber; LineTool.DrawingType = DRAWING_LINE; // static_cast<DrawingTypeEnum>(DRAWING_LINE); LineTool.BeginValue = Levels[j]; LineTool.BeginDateTime = sc.BaseDateTimeIn[sc.ArraySize - 1].GetAsDouble(); LineTool.Color = RGB(0, 255, 0); LineTool.AddMethod = UTAM_ADD_ALWAYS; You need to set an end date time and price for your line, both anchors are needed for it to be drawn. You can also drop the static cast and just use the enum value when setting the drawing type. if (ShowLevelValues.GetYesNo()) { char Label[32]; snprintf(Label, sizeof(Label), "%.2f", Levels[j]); LineTool.Text = Label; } Here you can use sc.FormatGraphValue instead or even LineTool.Text.Format("%.2f", Levels[j]) It might pay to read some of the docs about drawing tools (and other items). Using Drawing Tools From an Advanced Custom Study One other thing, the way you have it written, every time the function is called (every chart update) it will add more lines to the chart, 6 on each call, on top of the previous ones. You may wish to remember which line you have added lines for and/or remember the lines added and update them instead. Persistent variables can help you with that. ACSIL Interface Members - Functions: Persistent Variable Functions |
[2025-06-10 17:40:52] |
User936417 - Posts: 16 |
Thanks for your help I will continue this as time permits. There is a lot more to it than I imagined!
|
To post a message in this thread, you need to log in with your Sierra Chart account: