Support Board
Date/Time: Thu, 15 Jan 2026 01:42:06 +0000
Post From: Displaying Custom Bars on the Chart
| [2025-12-07 12:10:05] |
| User431178 - Posts: 833 |
|
I used the code on the website to create a Custom Bars study, which compiles fine but when I apply it to a 1-tick chart, it doesnt display anything. here is the code
It's clearly not a verbatim copy of the published code, your AI added some random unnecessary stuff to your code. This is the main problem, custom chart study is always hidden, setting it to display as main graph = blank chart. sc.DisplayAsMainPriceGraph = 1; // This is crucial Code below is working as expected. #include "sierrachart.h" SCDLLName("Working Custom Range Bars") // Forward declarations for our functions SCSFExport BuildCustomRangeBars(SCCustomChartBarInterfaceRef ChartBarInterface); int GetRangeBarDirection(SCCustomChartBarInterfaceRef ChartBarInterface, int BarIndex); // This is the main study function. It only runs once to set up the study. // CORRECTED a typo here: SCStudyFocus -> SCStudyInterfaceRef SCSFExport scsf_WorkingCustomRangeBars(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { // --- Essential Settings for a Custom Price Graph --- sc.GraphName = "Working Custom Range Bars"; sc.StudyDescription = "A working implementation of Sierra Chart's custom range bar example."; sc.UsesCustomChartBarFunction = 1; sc.fp_ACSCustomChartBarFunction = BuildCustomRangeBars; sc.AutoLoop = 0; // The custom bar function handles the looping // --- Input Setting --- sc.Input[0].Name = "Range Per Bar in Ticks"; sc.Input[0].SetInt(10); sc.Input[0].SetIntLimits(1, INT_MAX); return; } int& r_ChartDataReloadedFlag = sc.GetPersistentInt(CUSTOM_CHART_BAR_RELOAD_FLAG_KEY); if (r_ChartDataReloadedFlag == 0) { sc.FlagToReloadChartData = true; r_ChartDataReloadedFlag = 1; } // --- Logic to automatically reload the chart if the range input changes --- const int RangePerBar = sc.Input[0].GetInt(); int& r_PriorRangePerBar = sc.GetPersistentInt(1); if (r_PriorRangePerBar != 0 && r_PriorRangePerBar != RangePerBar) { sc.FlagToReloadChartData = true; } r_PriorRangePerBar = RangePerBar; if (sc.IsFullRecalculation) { sc.GraphName.Format("Custom Range Bar = %d", RangePerBar); } } // This function is called by Sierra Chart for every tick of data to build the bars SCSFExport BuildCustomRangeBars(SCCustomChartBarInterfaceRef ChartBarInterface) { ChartBarInterface.StartNewBarFlag = 0; // Default to not creating a new bar const float NeededRangeAsFloat = ChartBarInterface.GetInput(0).GetInt() * ChartBarInterface.TickSize; // Phase 1: Check if the current tick's price movement completes the current bar if (ChartBarInterface.IsDeterminingIfShouldStartNewBar) { int Direction = GetRangeBarDirection(ChartBarInterface, ChartBarInterface.CurrentBarIndex); float BarHigh = ChartBarInterface.GetChartBarValue(SC_HIGH, ChartBarInterface.CurrentBarIndex); float BarLow = ChartBarInterface.GetChartBarValue(SC_LOW, ChartBarInterface.CurrentBarIndex); if (Direction == 1) // Bar is moving up { BarHigh = max(BarHigh, ChartBarInterface.NewFileRecord.GetHigh()); if ((BarHigh - BarLow) >= NeededRangeAsFloat) ChartBarInterface.StartNewBarFlag = 1; } else // Bar is moving down { BarLow = min(BarLow, ChartBarInterface.NewFileRecord.GetLow()); if ((BarHigh - BarLow) >= NeededRangeAsFloat) ChartBarInterface.StartNewBarFlag = 1; } } // Phase 2: After a new bar has been created, finalize the previous bar else if (ChartBarInterface.IsFinalProcessingAfterNewOrCurrentBar) { if (ChartBarInterface.IsNewChartBar && ChartBarInterface.CurrentBarIndex > 0) { int PreviousBarIndex = ChartBarInterface.CurrentBarIndex - 1; int Direction = GetRangeBarDirection(ChartBarInterface, PreviousBarIndex); if (Direction == 1) // Finalize an up bar { // Set the Close equal to the High ChartBarInterface.GetChartBarValue(SC_LAST, PreviousBarIndex) = ChartBarInterface.GetChartBarValue(SC_HIGH, PreviousBarIndex); } else // Finalize a down bar { // Set the Close equal to the Low ChartBarInterface.GetChartBarValue(SC_LAST, PreviousBarIndex) = ChartBarInterface.GetChartBarValue(SC_LOW, PreviousBarIndex); } } } } // Helper function to determine the direction of the current range bar int GetRangeBarDirection(SCCustomChartBarInterfaceRef ChartBarInterface, int BarIndex) { for (int i = 0; i < 10 && BarIndex - i >= 0; ++i) { int CurrentIndex = BarIndex - i; float& BarOpen = ChartBarInterface.GetChartBarValue(SC_OPEN, CurrentIndex); float& BarLast = ChartBarInterface.GetChartBarValue(SC_LAST, CurrentIndex); if (BarLast < BarOpen) return -1; // Down if (BarLast > BarOpen) return 1; // Up if (CurrentIndex > 0) { float& PriorBarLast = ChartBarInterface.GetChartBarValue(SC_LAST, CurrentIndex - 1); if (BarLast < PriorBarLast) return -1; // Down if (BarLast > PriorBarLast) return 1; // Up } } return 1; // Default to up if undetermined } |
