Login Page - Create Account

Support Board


Date/Time: Wed, 04 Nov 2026 00:09:43 +0000



[Programming Help] - Countdown Timer

View Count: 315

[2026-09-17 15:02:09]
NdeFirmian - Posts: 2
Hello,

Please advise, as I lose the countdown timer (that counts down in seconds as each number bar progresses) when I duplicate a chart, or duplicate a chart to the Chartbook. The original chart has the timer, but the duplicate chart does not. How do I re-display the timer in the duplicated chart? The CountDown Timer settings shown at the top of the chart are exactly the same for both the original and duplicated chart (e.g. Countdown Timer (150, 100, No, Yes, No, No, No, No, No, No, Yes).

Thank you!

Shihab
[2026-09-17 16:01:48]
John - SC Support - Posts: 48413
We are not able to reproduce this. When we duplicate a chart with the Countdown Timer on it, the Countdown Timer is on the duplicated study and is displayed in the same location as the original chart.

From what you state, the study itself is still on the duplicated chart, but the timer itself is not being drawn. We do not know why this would occur.

Please get us both the original and the duplicated chart where you are having this issue. Please follow the instructions at the following link to get us these charts. The instructions are for a single chart, but we need both of them. And be sure the chart that does not show the Countdown Timer is not showing it in the one you are going to send to us.
Support Board Posting Information: Providing Chartbook with Only a Single Chart
For the most reliable, advanced, and zero cost futures order routing, use the Teton service:
Sierra Chart Teton Futures Order Routing
[2026-09-19 12:25:51]
user2732 - Posts: 10
This is my countdown timer I created. Should work better and look better than the standard one. Just copy paste in notepad then save and change to .cpp and compile in sierra.

#include "sierrachart.h"

SCDLLName("BarTimer")

SCSFExport scsf_BarTimer(SCStudyInterfaceRef sc)
{
SCSubgraphRef Subgraph_Timer = sc.Subgraph[0];

// Input references
SCInputRef Input_FontSize = sc.Input[0];
SCInputRef Input_FontFace = sc.Input[1];
SCInputRef Input_FontWeight = sc.Input[2];
SCInputRef Input_TextColor = sc.Input[3];
SCInputRef Input_BackgroundColor = sc.Input[4];
SCInputRef Input_EnableFlash = sc.Input[5];
SCInputRef Input_FlashTextColor = sc.Input[6];
SCInputRef Input_FlashBackgroundColor = sc.Input[7];
SCInputRef Input_FlashThresholdMinutes = sc.Input[8];
SCInputRef Input_HorizontalPosition = sc.Input[9];
SCInputRef Input_VerticalPosition = sc.Input[10];
SCInputRef Input_TransparentBackground = sc.Input[11];

// Persistent variables
int& LastSecond = sc.GetPersistentInt(1);
int& FlashState = sc.GetPersistentInt(2);

if (sc.SetDefaults)
{
sc.GraphName = "BarTimer";
sc.GraphRegion = 0;
sc.AutoLoop = 0;
sc.UpdateAlways = 1;

Subgraph_Timer.Name = "Timer";
Subgraph_Timer.DrawStyle = DRAWSTYLE_IGNORE;
Subgraph_Timer.PrimaryColor = RGB(0, 0, 0);
Subgraph_Timer.DisplayNameValueInWindowsFlags = 0;

// Font Size
Input_FontSize.Name = "Font Size (px)";
Input_FontSize.SetInt(8);
Input_FontSize.SetIntLimits(6, 72);

// Font Face
Input_FontFace.Name = "Font Face";
Input_FontFace.SetString("Segoe UI");

// Font Weight (100=Thin, 300=Light, 400=Regular, 700=Bold)
Input_FontWeight.Name = "Font Weight (100-900)";
Input_FontWeight.SetInt(300);
Input_FontWeight.SetIntLimits(100, 900);

// Normal Text Color
Input_TextColor.Name = "Text Color";
Input_TextColor.SetColor(RGB(0, 0, 0));

// Normal Background Color
Input_BackgroundColor.Name = "Background Color";
Input_BackgroundColor.SetColor(RGB(255, 255, 255));

// Enable Flash
Input_EnableFlash.Name = "Enable Flash Warning";
Input_EnableFlash.SetYesNo(0);

// Flash Text Color
Input_FlashTextColor.Name = "Flash Text Color";
Input_FlashTextColor.SetColor(RGB(255, 255, 255));

// Flash Background Color
Input_FlashBackgroundColor.Name = "Flash Background Color";
Input_FlashBackgroundColor.SetColor(RGB(255, 0, 0));

// Flash Threshold
Input_FlashThresholdMinutes.Name = "Flash Threshold (Minutes)";
Input_FlashThresholdMinutes.SetInt(5);
Input_FlashThresholdMinutes.SetIntLimits(1, 1440);

// Horizontal Position (150 = far right)
Input_HorizontalPosition.Name.Format("Horizontal Position From Left (1-%d)",
static_cast<int>(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION));
Input_HorizontalPosition.SetInt(149);
Input_HorizontalPosition.SetIntLimits(1, static_cast<int>(CHART_DRAWING_MAX_HORIZONTAL_AXIS_RELATIVE_POSITION));

// Vertical Position (1 = bottom)
Input_VerticalPosition.Name.Format("Vertical Position From Bottom (1-%d)",
static_cast<int>(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION));
Input_VerticalPosition.SetInt(3);
Input_VerticalPosition.SetIntLimits(1, static_cast<int>(CHART_DRAWING_MAX_VERTICAL_AXIS_RELATIVE_POSITION));

// Transparent Background
Input_TransparentBackground.Name = "Transparent Background";
Input_TransparentBackground.SetYesNo(0);

return;
}

// Handle study removal
static const int TimerLineNumber = 8888888;

if (sc.LastCallToFunction || sc.HideStudy)
{
sc.DeleteACSChartDrawing(sc.ChartNumber, TOOL_DELETE_CHARTDRAWING, TimerLineNumber);
return;
}

if (sc.ArraySize == 0)
return;

int LastBarIndex = sc.ArraySize - 1;

// Use SYSTEM time for real-time countdown
SCDateTime CurrentTime = sc.CurrentSystemDateTime;
SCDateTime BarStartTime = sc.BaseDateTimeIn[LastBarIndex];

// Calculate bar end time
int SecondsPerBar = sc.SecondsPerBar;
SCDateTime BarEndTime = BarStartTime;
BarEndTime.AddSeconds(SecondsPerBar);

// Calculate remaining time
SCDateTime RemainingTime = BarEndTime - CurrentTime;

// Handle edge cases
if (RemainingTime.GetAsDouble() < 0.0)
{
SCDateTime BarDuration = SCDateTime::SECONDS(SecondsPerBar);
if (BarDuration.GetAsDouble() != 0.0)
{
double ElapsedBars = (CurrentTime - BarStartTime).GetAsDouble() / BarDuration.GetAsDouble();
double ElapsedPercentageOfCurrentBar = ElapsedBars - static_cast<int>(ElapsedBars);
RemainingTime = (1.0 - ElapsedPercentageOfCurrentBar) * BarDuration.GetAsDouble();
}
else
{
RemainingTime = 0;
}
}

int TotalSecondsRemaining = RemainingTime.GetTimeInSeconds();

if (TotalSecondsRemaining < 0)
TotalSecondsRemaining = 0;

// Calculate components
int Hour = TotalSecondsRemaining / 3600;
int Minute = (TotalSecondsRemaining % 3600) / 60;
int Second = TotalSecondsRemaining % 60;

// Format as 00:00:00
SCString TimeText;
TimeText.Format("%02d:%02d:%02d", Hour, Minute, Second);

// Determine if we should flash - OPTIMIZED LOGIC
bool ShouldFlash = false;
COLORREF TextColor = Input_TextColor.GetColor();
COLORREF BackColor = Input_BackgroundColor.GetColor();

// Only check flash conditions if flash is enabled
if (Input_EnableFlash.GetYesNo())
{
int FlashThresholdSeconds = Input_FlashThresholdMinutes.GetInt() * 60;

// Smart logic: Only flash if threshold is less than bar duration
// If you have 5 min flash on 1 min chart, it would always flash - so disable it
if (FlashThresholdSeconds < SecondsPerBar)
{
// Check if we're within the flash threshold
if (TotalSecondsRemaining <= FlashThresholdSeconds && TotalSecondsRemaining > 0)
{
ShouldFlash = true;

// Toggle flash state every second for smooth flashing
if (TotalSecondsRemaining != LastSecond)
{
LastSecond = TotalSecondsRemaining;
FlashState = 1 - FlashState; // Toggle between 0 and 1
}

// Apply flash colors when in flash state
if (FlashState == 1)
{
TextColor = Input_FlashTextColor.GetColor();
BackColor = Input_FlashBackgroundColor.GetColor();
}
}
}
}

// Reset flash state when not flashing
if (!ShouldFlash)
{
FlashState = 0;
}

// Draw the timer
s_UseTool Tool;
Tool.Clear();
Tool.ChartNumber = sc.ChartNumber;
Tool.DrawingType = DRAWING_TEXT;
Tool.Region = sc.GraphRegion;
Tool.LineNumber = TimerLineNumber;
Tool.AddMethod = UTAM_ADD_OR_ADJUST;
Tool.AddAsUserDrawnDrawing = 0;
Tool.DrawUnderneathMainGraph = 0;

// Position using relative coordinates
Tool.BeginDateTime = Input_HorizontalPosition.GetInt();
Tool.BeginValue = static_cast<float>(Input_VerticalPosition.GetInt());
Tool.UseRelativeVerticalValues = 1;

// Text properties
Tool.Text = TimeText;
Tool.FontSize = Input_FontSize.GetInt();
Tool.FontFace = Input_FontFace.GetString();
Tool.FontBold = (Input_FontWeight.GetInt() >= 600);
Tool.Color = TextColor;
Tool.FontBackColor = BackColor;

// Background box settings
if (Input_TransparentBackground.GetYesNo())
Tool.TransparentLabelBackground = 1;
else
Tool.TransparentLabelBackground = 0;

Tool.TextAlignment = DT_RIGHT;
Tool.ReverseTextColor = 0;

sc.UseTool(Tool);

// Update subgraph value
for (int i = sc.UpdateStartIndex; i < sc.ArraySize; i++)
{
Subgraph_Timer = 0;
}
Subgraph_Timer[LastBarIndex] = static_cast<float>(TotalSecondsRemaining);
}

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

Login

Login Page - Create Account