Support Board
Date/Time: Fri, 18 Apr 2025 06:47:27 +0000
[Programming Help] - C2447 error when compiling Advanced Custom Studies
View Count: 128
[2025-03-24 04:20:15] |
User595847 - Posts: 5 |
Hello, I’m encountering Error C2447: '(': missing function header (old-style formal list?) when I try to compile my custom strategy script. The error seems to be related to function headers or syntax, but I’m unable to pinpoint the exact cause. I’ve tried reviewing the function definitions and headers, checked for missing function headers or syntax errors in my custom function declarations but to no avail. If you could help pinpoint the problem and suggest how to fix the missing function header or any other related issues, I’d greatly appreciate it. Full script is below. Thank you for your assistance! Best regards, Mark #include "sierrachart.h" SCDLLName("Trade Logic Strategy") // Initialize study settings function void InitializeStudy(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { sc.GraphName = "Trade Logic Strategy"; sc.StudyDescription = "Automated strategy using predefined levels and opening range."; sc.AutoLoop = 1; // Inputs sc.Input[0].Name = "Predefined Level"; sc.Input[0].SetFloat(4000.0); sc.Input[1].Name = "Opening Range Start Time"; sc.Input[1].SetTime(HOURS(9) + MINUTES(30)); sc.Input[2].Name = "Tick Bar Size"; sc.Input[2].SetInt(2000); sc.Input[3].Name = "Stop Loss (Ticks)"; sc.Input[3].SetInt(10); sc.Input[4].Name = "Target Profit (Ticks)"; sc.Input[4].SetInt(20); sc.Input[5].Name = "Order Quantity"; sc.Input[5].SetInt(1); sc.AllowMultipleEntriesInSameDirection = false; sc.MaximumPositionAllowed = 1; sc.SupportReversals = false; sc.SendOrdersToTradeService = false; } } // Calculate Opening Range void CalculateOpeningRange(SCStudyInterfaceRef sc, float &openingRangeHigh, float &openingRangeLow, bool &openingRangeSet) { SCDateTime now = sc.BaseDateTimeIn[sc.Index]; SCDateTime openingRangeStartTime = sc.Input[1].GetTime(); if (!openingRangeSet && now >= openingRangeStartTime && now < openingRangeStartTime + SCDateTime(0, 3600)) { openingRangeHigh = max(openingRangeHigh, sc.High[sc.Index]); openingRangeLow = min(openingRangeLow, sc.Low[sc.Index]); } else if (now > openingRangeStartTime + SCDateTime(0, 3600)) { openingRangeSet = true; } } // Check trade conditions bool CheckTradeConditions(SCStudyInterfaceRef sc, float predefinedLevel, float openingRangeHigh, float openingRangeLow) { bool isAboveConditions = (sc.Close[sc.Index] > predefinedLevel) && (sc.Close[sc.Index] > openingRangeHigh); bool isBelowConditions = (sc.Close[sc.Index] < predefinedLevel) && (sc.Close[sc.Index] < openingRangeLow); return isAboveConditions || isBelowConditions; } // Execute the trade void ExecuteTrade(SCStudyInterfaceRef sc, bool isAboveConditions, bool isBelowConditions, int orderQuantity, int stopLossTicks, int targetProfitTicks) { s_SCNewOrder NewOrder; NewOrder.OrderType = SCT_ORDERTYPE_MARKET; NewOrder.OrderQuantity = orderQuantity; NewOrder.TimeInForce = SCT_TIF_GOOD_TILL_CANCELED; NewOrder.AttachedOrderStopOffset = stopLossTicks * sc.TickSize; NewOrder.AttachedOrderTargetOffset = targetProfitTicks * sc.TickSize; if (isAboveConditions) { int result = sc.BuyEntry(NewOrder); if (result > 0) sc.AddMessageToLog("✅ Long trade executed", 0); } else if (isBelowConditions) { int result = sc.SellEntry(NewOrder); if (result > 0) sc.AddMessageToLog("✅ Short trade executed", 0); } } // Main function: Sierra Chart entry point SCSFExport void scsf_TradeLogicStrategy(SCStudyInterfaceRef sc) { // Initialize study settings InitializeStudy(sc); // Ensure valid index if (sc.Index < 1) return; // Retrieve input values float predefinedLevel = sc.Input[0].GetFloat(); int orderQuantity = sc.Input[5].GetInt(); int stopLossTicks = sc.Input[3].GetInt(); int targetProfitTicks = sc.Input[4].GetInt(); // Variables for opening range static float openingRangeHigh = 0.0; static float openingRangeLow = 0.0; static bool openingRangeSet = false; // Calculate the opening range CalculateOpeningRange(sc, openingRangeHigh, openingRangeLow, openingRangeSet); // Check if trade conditions are met bool tradeConditionsMet = CheckTradeConditions(sc, predefinedLevel, openingRangeHigh, openingRangeLow); // Execute trade if conditions are met if (tradeConditionsMet) { ExecuteTrade(sc, (sc.Close[sc.Index] > predefinedLevel && sc.Close[sc.Index] > openingRangeHigh), (sc.Close[sc.Index] < predefinedLevel && sc.Close[sc.Index] < openingRangeLow), orderQuantity, stopLossTicks, targetProfitTicks); } } |
[2025-03-24 09:30:18] |
User431178 - Posts: 647 |
Post the whole complier error message next time, it may point directly to the error. This is wrong for a start: sc.Input[1].SetTime(HOURS(9) + MINUTES(30)); See this example in the docs: ACSIL Interface Members - sc.Input Array: sc.Input[].SetTime() Also you can construct an SCDateTime object and call the GetTime() member function: SCDateTime(int Hour, int Minute, int Second, int Millisecond) SCDateTime(9, 30, 0, 0).GetTime() |
[2025-03-24 15:04:38] |
cmet - Posts: 689 |
Incorrect study initialization. Not using valid ACSIL members. This is one of the main issues when using GPT to help with ACSIL (along with green check emojis in notes ✅ 😶). Make sure when you use it, you're forcing valid syntax. This is not checked for functionality but it compiles and might get you thinking about the solutions you need: #include "sierrachart.h"
SCDLLName("Trade Logic Strategy"); SCSFExport scsf_TradeLogicStrategy(SCStudyInterfaceRef sc) { //inputs SCInputRef Input_Level = sc.Input[0]; SCInputRef Input_StartTime = sc.Input[1]; SCInputRef Input_Stop = sc.Input[3]; SCInputRef Input_Target = sc.Input[4]; SCInputRef Input_Quantity = sc.Input[5]; if (sc.SetDefaults) { sc.GraphName = "Trade Logic Strategy"; sc.StudyDescription = "Automated strategy using predefined levels and opening range."; sc.AutoLoop = 1; Input_Level.Name = "Predefined Level"; Input_Level.SetFloat(4000.0f); Input_StartTime.Name = "Opening Range Start Time"; Input_StartTime.SetTime(HMS_TIME(9, 30, 0)); sc.Input[2].Name = "Tick Bar Size"; sc.Input[2].SetInt(2000); Input_Stop.Name = "Stop Loss (Ticks)"; Input_Stop.SetInt(10); Input_Target.Name = "Target Profit (Ticks)"; Input_Target.SetInt(20); Input_Quantity.Name = "Order Quantity"; Input_Quantity.SetInt(1); sc.AllowMultipleEntriesInSameDirection = false; sc.MaximumPositionAllowed = 1; sc.SupportReversals = false; sc.SendOrdersToTradeService = false; return; } if (sc.Index == 0) return; float predefinedLevel = Input_Level.GetFloat(); int orderQuantity = Input_Quantity.GetInt(); int stopLossTicks = Input_Stop.GetInt(); int targetProfitTicks = Input_Target.GetInt(); //opening range const int date = sc.BaseDateTimeIn[sc.Index].GetDate(); int& r_LastDate = sc.GetPersistentInt(0); float& r_High = sc.GetPersistentFloat(0); float& r_Low = sc.GetPersistentFloat(1); int& r_OpeningRangeSet = sc.GetPersistentInt(2); //reset range on new session if (date != r_LastDate) { r_LastDate = date; r_OpeningRangeSet = 0; r_High = sc.High[sc.Index]; r_Low = sc.Low[sc.Index]; } //opening range SCDateTime now = sc.BaseDateTimeIn[sc.Index]; SCDateTime openingRangeStartTime = Input_StartTime.GetTime(); SCDateTime openingRangeEndTime = openingRangeStartTime + 3600; if (r_OpeningRangeSet == 0 && now >= openingRangeStartTime && now < openingRangeEndTime) { r_High = sc.High[sc.Index] > r_High ? sc.High[sc.Index] : r_High; r_Low = sc.Low[sc.Index] < r_Low ? sc.Low[sc.Index] : r_Low; } else if (now >= openingRangeEndTime) { r_OpeningRangeSet = 1; } //wait for range set if (r_OpeningRangeSet == 0) return; //trade conditions float lastPrice = sc.Close[sc.Index]; bool isAboveConditions = (lastPrice > predefinedLevel) && (lastPrice > r_High); bool isBelowConditions = (lastPrice < predefinedLevel) && (lastPrice < r_Low); bool tradeConditionsMet = isAboveConditions || isBelowConditions; //execution if (tradeConditionsMet) { s_SCNewOrder NewOrder; NewOrder.OrderType = SCT_ORDERTYPE_MARKET; NewOrder.OrderQuantity = orderQuantity; NewOrder.TimeInForce = SCT_TIF_GOOD_TILL_CANCELED; NewOrder.Target1Offset = targetProfitTicks * sc.TickSize; NewOrder.AttachedOrderTarget1Type = SCT_ORDERTYPE_LIMIT; NewOrder.Stop1Offset = stopLossTicks * sc.TickSize; NewOrder.AttachedOrderStop1Type = SCT_ORDERTYPE_STOP; if (isAboveConditions) sc.BuyEntry(NewOrder); else if (isBelowConditions) sc.SellEntry(NewOrder); } } Date Time Of Last Edit: 2025-03-24 15:05:00
|
[2025-03-25 01:28:59] |
User595847 - Posts: 5 |
Thanks so much, cmet, you have pointed me in the right direction. I am now testing in Sim, and have updated the script to reflect my full strategy. Script is below, in case it's of any benefit to you or others. It is an ES/MES momentum strategy, where I use the predefined level (ie your chosen support/resistance), opening range and short term momentum from tick bar closes as filters for trend/momentum, with the ability to also set a specific time when the trade triggers eg 1 hour after opening range to avoid whipsaws. Then using trailing stop with initial stop referencing the opening range high/low. As I live in Australia, I wanted to automate my strategy for trading the US Cash Session for ES/MES, as I'm typically sleeping at this time. #include "sierrachart.h" SCDLLName("Trade Logic Strategy"); SCSFExport scsf_TradeLogicStrategy(SCStudyInterfaceRef sc) { // inputs SCInputRef Input_Level = sc.Input[0]; SCInputRef Input_TimeRestrictionEnabled = sc.Input[1]; // Enable/Disable Time Restriction SCInputRef Input_RestrictionStartTime = sc.Input[2]; // Start Time for Time Restriction SCInputRef Input_Stop = sc.Input[3]; // Stop Loss in points from opening range SCInputRef Input_Target = sc.Input[4]; // Target Profit in ticks SCInputRef Input_Quantity = sc.Input[5]; // Order Quantity SCInputRef Input_OpeningRangeDuration = sc.Input[6]; // Opening Range Duration in minutes SCInputRef Input_OpeningRangeStartTime = sc.Input[7]; // Opening Range Start Time if (sc.SetDefaults) { sc.GraphName = "Trade Logic Strategy"; sc.StudyDescription = "Automated strategy using predefined levels and opening range."; sc.AutoLoop = 1; // Define Inputs Input_Level.Name = "Predefined Level"; Input_Level.SetFloat(4000.0f); Input_TimeRestrictionEnabled.Name = "Enable Time Restriction"; Input_TimeRestrictionEnabled.SetYesNo(1); // Default to enabled Input_RestrictionStartTime.Name = "Time Restriction Start Time"; Input_RestrictionStartTime.SetTime(HMS_TIME(11, 0, 0)); // Default start time at 11:00 AM ET Input_Stop.Name = "Stop Loss (Points from Opening Range)"; Input_Stop.SetInt(3); // Default stop loss: 3 points from the opening range Input_Target.Name = "Target Profit (Ticks)"; Input_Target.SetInt(20); // Default target profit: 20 ticks Input_Quantity.Name = "Order Quantity"; Input_Quantity.SetInt(1); // Default quantity: 1 contract Input_OpeningRangeDuration.Name = "Opening Range Duration (Minutes)"; Input_OpeningRangeDuration.SetInt(60); // Default duration: 60 minutes Input_OpeningRangeStartTime.Name = "Opening Range Start Time"; Input_OpeningRangeStartTime.SetTime(HMS_TIME(9, 30, 0)); // Default start time for U.S. session (9:30 AM ET) sc.AllowMultipleEntriesInSameDirection = false; sc.MaximumPositionAllowed = 1; sc.SupportReversals = false; sc.SendOrdersToTradeService = false; return; } if (sc.Index == 0) return; // Input values float predefinedLevel = Input_Level.GetFloat(); int orderQuantity = Input_Quantity.GetInt(); int stopLossPoints = Input_Stop.GetInt(); // Stop loss points from the opening range int targetProfitTicks = Input_Target.GetInt(); int openingRangeDuration = Input_OpeningRangeDuration.GetInt(); SCDateTime openingRangeStartTime = Input_OpeningRangeStartTime.GetTime(); bool timeRestrictionEnabled = Input_TimeRestrictionEnabled.GetYesNo() !=0; // Time restriction enabled/disabled SCDateTime restrictionStartTime = Input_RestrictionStartTime.GetTime(); // Time restriction start time // Opening range variables const int date = sc.BaseDateTimeIn[sc.Index].GetDate(); int& r_LastDate = sc.GetPersistentInt(0); float& r_High = sc.GetPersistentFloat(0); float& r_Low = sc.GetPersistentFloat(1); int& r_OpeningRangeSet = sc.GetPersistentInt(2); // Reset range on new session if (date != r_LastDate) { r_LastDate = date; r_OpeningRangeSet = 0; r_High = sc.High[sc.Index]; r_Low = sc.Low[sc.Index]; } // Opening range logic SCDateTime openingRangeEndTime = openingRangeStartTime + (openingRangeDuration * 60); SCDateTime now = sc.BaseDateTimeIn[sc.Index]; if (r_OpeningRangeSet == 0 && now >= openingRangeStartTime && now < openingRangeEndTime) { r_High = sc.High[sc.Index] > r_High ? sc.High[sc.Index] : r_High; r_Low = sc.Low[sc.Index] < r_Low ? sc.Low[sc.Index] : r_Low; } else if (now >= openingRangeEndTime) { r_OpeningRangeSet = 1; } // Wait for opening range to be set if (r_OpeningRangeSet == 0) return; // Time restriction logic if (timeRestrictionEnabled && now < restrictionStartTime) return; // Exit if time restriction is enabled and before the restriction start time // Trade conditions float lastPrice = sc.Close[sc.Index]; bool isAboveConditions = (lastPrice > predefinedLevel) && (lastPrice > r_High); bool isBelowConditions = (lastPrice < predefinedLevel) && (lastPrice < r_Low); bool tradeConditionsMet = isAboveConditions || isBelowConditions; // Execution logic if (tradeConditionsMet) { s_SCNewOrder NewOrder; NewOrder.OrderType = SCT_ORDERTYPE_MARKET; NewOrder.OrderQuantity = orderQuantity; NewOrder.TimeInForce = SCT_TIF_GOOD_TILL_CANCELED; // Set stop loss and target from opening range NewOrder.Stop1Offset = stopLossPoints * sc.TickSize; NewOrder.Target1Offset = targetProfitTicks * sc.TickSize; // Create and execute buy/sell orders if (isAboveConditions) sc.BuyEntry(NewOrder); else if (isBelowConditions) sc.SellEntry(NewOrder); } } |
To post a message in this thread, you need to log in with your Sierra Chart account: