Login Page - Create Account

Support Board


Date/Time: Wed, 04 Nov 2026 00:21:07 +0000



Post From: Countdown Timer

[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);
}