Writing Algorithms
Parameters
Introduction
Parameters are project variables that your algorithm uses to define the value of internal variables like indicator arguments or the length of lookback windows.
Parameters are stored outside of your algorithm code, but we inject the values of the parameters into your algorithm when you run a backtest, deploy a live algorithm, or launch an optimization job. To use parameters, add some parameters to your project and add the GetParameter
method to your code files.
Set Parameters
You can add parameters, set default parameter values, and remove parameters from your projects.
Add Parameters
Follow these steps to add an algorithm parameter to a project:
- Open the project.
- In the Project panel, click .
- Enter the parameter name.
- Enter the default value.
- Click .
- Add the
GetParameter
method to your code files to inject the parameter value into your algorithm.
The parameter name must be unique in the project.
Set Default Parameter Values
Follow these steps to set the default value of an algorithm parameter in a project:
- Open the project.
- In the Project panel, hover over the algorithm parameter and then click the pencil icon that appears.
- Enter a default value for the parameter and then click .

The Project panel displays the default parameter value next to the parameter name.
Delete Parameters
Follow these steps to delete an algorithm parameter in a project:
- Open the project.
- In the Project panel, hover over the algorithm parameter and then click the trash can icon that appears.
- Remove the
GetParameter
calls that were associated with the parameter from your code files.

Get Parameters
The GetParameter
method returns the parameter value with the numeric type of the default value. If you don't provide a default value, the method returns a string, and you need to cast it to the data type you need. If there are no parameters in your project that match the name you pass to the method and you provide a default value to the method, it returns the default value.
The following table describes the arguments the GetParameter
method accepts:
Argument | Data Type | Description |
---|---|---|
name | string str | The name of the parameter to get |
defaultValue | string str , or number | The default value to return |
namespace QuantConnect.Algorithm.CSharp { public class ParameterizedAlgorithm : QCAlgorithm { public override void Initialize() { // Get the parameter value and return an integer var intParameterValue = GetParameter("<int-parameter-name>", 100); // Get the parameter value and return a double var doubleParameterValue = GetParameter("<double-parameter-name>", 0.95); // Get the parameter value and return a decimal var decimalParameterValue = GetParameter("<decimal-parameter-name>", 0.05m); // Get the parameter value as a string var stringParameterValue = GetParameter("<parameter-name>") // Cast it to an integer var castedParameterValue = Convert.ToInt32(stringParameterValue); } } }
class ParameterizedAlgorithm(QCAlgorithm): def Initialize(self) -> None: # Get the parameter value and return an integer int_parameter_value = self.GetParameter("<int-parameter-name>", 100) # Get the parameter value and return a double float_parameter_value = self.GetParameter("<float-parameter-name>", 0.95) # Get the parameter value as a string string_parameter_value = self.GetParameter("<parameter-name>") # Cast it to an integer parameter_value = int(string_parameter_value)
The Parameter(name)
attribute on top of our fields or properties sets their values. If there are no parameters in your project that match the name you pass to the attribute and you provide a default value to the method, it returns the default value.
namespace QuantConnect.Algorithm.CSharp { public class ParameterizedAlgorithm : QCAlgorithm { [Parameter("<int-parameter-name>")] public int IntParameterValue = 100; [Parameter("<double-parameter-name>")] public double DoubleParameterValue = 0.95; [Parameter("<decimal-parameter-name>")] public decimal DecimalParameterValue = 0.05m; } }
The parameter values are sent to your algorithm when you deploy the algorithm, so it's not possible to change the parameter values while the algorithm runs.
Overfitting
Overfitting occurs when a function is fit too closely fit to a limited set of training data. Overfitting can occur in your trading algorithms if you have many parameters or select parameters values that worked very well in the past but are sensitive to small changes in their values. In these cases, your algorithm will likely be fine-tuned to fit the detail and noise of the historical data to the extent that it negatively impacts the live performance of your algorithm. The following image shows examples of underfit, optimally-fit, and overfit functions:

An algorithm that is dynamic and generalizes to new data is more likely to survive across different market conditions and apply to other markets.
Look-Ahead Bias
Look-ahead bias occurs when an algorithm makes decisions using data that would not have yet been available. For instance, in optimization jobs, you optimize a set of parameters over a historical backtesting period. After the optimizer finds the optimal parameter values, the backtest period becomes part of the in-sample data. If you run a backtest over the same period using the optimal parameters, look-ahead bias has seeped into your research. In reality, it would not be possible to know the optimal parameters during the testing period until after the testing period is over. To avoid issues with look-ahead bias, optimize on older historical data and test the optimal parameter values on recent historical data. Alternatively, apply walk forward optimization to optimize the parameters on smaller batches of history.
Live Trading Considerations
To update parameters in live mode, the algorithm can implement schedule events that downloads dynamic data from a remote file:
private Dictionary_parameters = new(); public override void Initialize() { if (LiveMode) { Schedule.On( DateRules.EveryDay(), TimeRules.Every(TimeSpan.FromMinutes(1)), ()=> { var content = Download(urlToRemoteFile); // Convert content to _parameters }); } }
def Initialize(self): self.parameters = { } if self.LiveMode: def download_parameters(): content = self.Download(url_to_remote_file) # Convert content to self.parameters self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.Every(timedelta(minutes=1)), download_parameters)
Examples
Call QCAlgorithm.GetParameter(name)
in your algorithm to retrieve the string value of a parameter and use that instead of constant values. For example, the ema-fast
, and ema-slow
parameters can be used like this:
namespace QuantConnect.Algorithm.CSharp { public class ParameterizedAlgorithm : QCAlgorithm { private ExponentialMovingAverage _fast; private ExponentialMovingAverage _slow; public override void Initialize() { SetStartDate(2020, 1, 1); SetCash(100000); AddEquity("SPY"); var fastPeriod = GetParameter("ema-fast", 100); var slowPeriod = GetParameter("ema-slow", 200); _fast = EMA("SPY", fastPeriod); _slow = EMA("SPY", slowPeriod); } } }
class ParameterizedAlgorithm(QCAlgorithm): def Initialize(self) -> None: self.SetStartDate(2020, 1, 1) self.SetCash(100000) self.AddEquity("SPY") fast_period = self.GetParameter("ema-fast", 100) slow_period = self.GetParameter("ema-slow", 200) self._fast = self.EMA("SPY", fast_period) self._slow = self.EMA("SPY", slow_period)
Alternatively, add attributes using Parameter(name)
on top of our fields or properties that should receive their values from the job and use that instead of constant values. For example, the ema-fast
, and ema-slow
parameters can be used like this:
namespace QuantConnect.Algorithm.CSharp { public class ParameterizedAlgorithm : QCAlgorithm { [Parameter("ema-fast")] public int FastPeriod = 100; [Parameter("ema-slow")] public int SlowPeriod = 200; private ExponentialMovingAverage _fast; private ExponentialMovingAverage _slow; public override void Initialize() { SetStartDate(2020, 1, 1); SetCash(100000); AddEquity("SPY"); _fast = EMA("SPY", FastPeriod); _slow = EMA("SPY", SlowPeriod); } } }