Support Board
Date/Time: Sun, 22 Dec 2024 07:07:04 +0000
ACSIL - How to run part of code only once per bar
View Count: 4503
[2015-04-20 00:44:31] |
eagle - Posts: 92 |
In an ACSIL custom study, how can I run a partial code block only once per bar, while the rest of the code runs more often? Thanks |
[2015-04-20 04:28:43] |
ejtrader - Posts: 688 |
You can try this.. int &lastIndex = sc.GetPersistentInt(0); if (sc.UpdateStartIndex == 0) { lastIndex = -1; } // Place all code that needs to execute all ticks here {......} if (lastIndex == sc.Index) { return; } lastIndex = sc.Index; // Place all code that needs to execute only once per bar below - this would get executed on first tick of each bar {....} Date Time Of Last Edit: 2018-12-13 03:48:54
|
[2015-04-20 05:29:31] |
eagle - Posts: 92 |
Thanks, ejtrader. BTW, a post of yours from a couple years ago was part of my reference material. Thinking and thinking about persistent variables, I finally took a stab at it (before I saw your post). What would be the difference between using "sc.PersistVars->Integers[0]" or "sc.PersistVars->i1"? Do you (or anyone else) see any errors or inefficiencies in the following code? #include "sierrachart.h" SCDLLName("Bid Ask Ratio Alert") SCSFExport scsf_BidAskRatioAlert(SCStudyInterfaceRef sc) { SCSubgraphRef Buy = sc.Subgraph[0]; SCSubgraphRef Sell = sc.Subgraph[1]; SCInputRef RatioThreshold = sc.Input[0]; SCInputRef ArrowOffsetType = sc.Input[1]; SCInputRef ArrowOffsetValue = sc.Input[2]; SCInputRef FastUpdate = sc.Input[3]; // SECTION 1: *** Configuration Variables and Defaults *** if (sc.SetDefaults) { sc.GraphName = "Bid Ask Ratio Alert"; sc.StudyDescription = "Draw arrows when the ratio exceeds the threshold."; Buy.Name = "Buy Alert Arrow"; Buy.DrawStyle = DRAWSTYLE_ARROWUP; Buy.PrimaryColor = RGB(0, 255, 0); // Green Buy.LineWidth = 4; // Width of arrow Sell.Name = "Sell Alert Arrow"; Sell.DrawStyle = DRAWSTYLE_ARROWDOWN; Sell.PrimaryColor = RGB(255, 0, 0); // Red Sell.LineWidth = 4; // Width of arrow RatioThreshold.Name = "Bid/Ask Size Ratio Threshold"; RatioThreshold.SetFloat(2.5); ArrowOffsetType.Name = "Alert Arrow Offset Specified As"; ArrowOffsetType.SetCustomInputStrings("Tick Offset;Percentage of Chart;Percentage of Price"); ArrowOffsetType.SetCustomInputIndex(1); ArrowOffsetValue.Name = "Alert Arrow Offset"; ArrowOffsetValue.SetFloat(5.2); FastUpdate.Name = "Fast Update for Trade Data"; FastUpdate.SetCustomInputStrings("Disable;Enable"); FastUpdate.SetCustomInputIndex(0); sc.GraphRegion = 0; // Main chart region sc.DrawZeros= 0; // Enforce Fast Update for Trade Data Disable on startup. sc.OnExternalDataImmediateStudyCall = 0; // Looping is not needed. Only the current bar is processed. sc.AutoLoop = 0; sc.FreeDLL = 0; return; } // SECTION 2: *** Study Function Variables *** int Index = sc.Index; // Set Index to the current bar. int &LastIndexProcessed = sc.PersistVars->i1; float &ArrowOffset = sc.PersistVars->f1; // Don't process on startups nor recalculations. if (Index == 0) { LastIndexProcessed = -1; return; } // Process this block only once per bar. if (Index > LastIndexProcessed) { sc.OnExternalDataImmediateStudyCall = FastUpdate.GetIndex(); // Calculate alert arrow offset. int ArrowOffsetTypeIndex = ArrowOffsetType.GetIndex(); float OffsetValue = ArrowOffsetValue.GetFloat(); float ChartHigh, ChartLow; sc.GetMainGraphVisibleHighAndLow(ChartHigh, ChartLow); if (ArrowOffsetTypeIndex == 0) { ArrowOffset = OffsetValue * sc.TickSize; } else if (ArrowOffsetTypeIndex == 1) { ArrowOffset = OffsetValue * (ChartHigh - ChartLow) * 0.005f; } else { ArrowOffset = OffsetValue * sc.Open[Index] * 0.00005f; } // Remove all arrows from the previous bar. Buy[Index -1] = 0; Sell[Index -1] = 0; LastIndexProcessed = Index; } // SECTION 3: *** Data Processing *** if (sc.ServerConnectionState == 3) { // Connected to data feed. int AskSize = sc.AskSize; int BidSize = sc.BidSize; if ((AskSize > 0) && (BidSize > 0)) { // Prevent divide by zero. if (BidSize > AskSize) { if (((float) BidSize / (float) AskSize) > RatioThreshold.GetFloat()) { // Remove any down arrow from the current bar. Sell[Index] = 0; // Place an up arrow below the low of the current bar. Buy[Index] = sc.Low[Index] - ArrowOffset; } else { // Remove all arrows from the current bar. Buy[Index] = 0; Sell[Index] = 0; } } else if (AskSize > BidSize) { if (((float) AskSize / (float) BidSize) > RatioThreshold.GetFloat()) { // Remove any up arrow from the current bar. Buy[Index] = 0; // Place a down arrow above the high of the current bar. Sell[Index] = sc.High[Index] + ArrowOffset; } else { // Remove all arrows from the current bar. Buy[Index] = 0; Sell[Index] = 0; } } else { // Remove all arrows from the current bar. Buy[Index] = 0; Sell[Index] = 0; } } } } |
[2015-04-20 05:52:19] |
eagle - Posts: 92 |
1. In the code of Post #3, is the value of "sc.OnExternalDataImmediateStudyCall", that's set in SECTION 2, persistent across calls to the function?
|
[2015-04-20 06:36:11] |
eagle - Posts: 92 |
I moved the assignment setting of "sc.OnExternalDataImmediateStudyCall" to run only on startup: if (Index == 0) { // Startups and recalculations.
// Set the value of Fast Update for Trade Data. sc.OnExternalDataImmediateStudyCall = FastUpdate.GetIndex(); // Initialize the LastIndexProcessed persistent variable. LastIndexProcessed = -1; // Don't process further on startups nor recalculations. return; } 2. Will this setting of "sc.OnExternalDataImmediateStudyCall" be persistent across calls to the study function? |
[2015-04-20 13:31:31] |
ejtrader - Posts: 688 |
What would be the difference between using "sc.PersistVars->Integers[0]" or "sc.PersistVars->i1"?
There is no difference between using either of them (or the way I have mentioned above in the code). Related to other question - OnExternalDataImmediateStudyCall - refer to the document here and code according to your need :) http://www.sierrachart.com/index.php?page=doc/doc_ACSIL_Members_Variables_And_Arrays.html#scOnExternalDataImmediateStudyCall |
To post a message in this thread, you need to log in with your Sierra Chart account: