Changed: How to change input settings after initialization?

Questions about MultiCharts .NET and user contributed studies.
Talky_Zebra
Posts: 45
Joined: 07 Mar 2024
Has thanked: 13 times
Been thanked: 1 time

Changed: How to change input settings after initialization?

Postby Talky_Zebra » 23 Apr 2024

Ok, this might seem a small thing, but I might want my study to be "intelligent" and change an input setting after the study is initialized. For instance, I am working out a way to save Input preferences so if I remove a study, I can reload them later, especially if there are different inputs for different symbols all using the same study.

Now, I notice that after changing the input variables, the on-chart list of settings does not change. See what I am referring to here:
inputsettings.JPG
(14.33 KiB) Not downloaded yet
This is the toy code I am using to test this out. I am even trying two different methods of changing the value of the input property. (in StartCalc, one of them is commented out, but either will work) While both update the value, neither method shows the change on the chart.

How do I show this updated input value on the chart (replacing "default", in this case)?

Code: Select all

using System; using System.Drawing; using System.Linq; using PowerLanguage.Function; using ATCenterProxy.interop; using System.Reflection; namespace PowerLanguage.Strategy { public class _TEST_updateinput : SignalObject { public _TEST_updateinput(object _ctx):base(_ctx){ this_input = "default"; } [Input] public string this_input {get;set;} protected override void Create() { Output.Clear(); Output.WriteLine("Create() this_input: {0}", this_input); } protected override void StartCalc() { // PropertyInfo pi = this.GetType().GetProperty("this_input"); // pi.SetValue(this, "setvalue changed input", null); this_input = "direct changed input"; Output.WriteLine("StartCalc() this_input: {0}", this_input); } bool notified = false; // so the output doesn't continue to write after the first change protected override void CalcBar(){ if (this_input != "default") { if (notified == false) { Output.WriteLine("CalcBar() this_input: {0}", this_input); notified = true; } } } } }
The Output shows the expected changes:

Code: Select all

Create() this_input: default StartCalc() this_input: direct changed input CalcBar() this_input: direct changed input

Talky_Zebra
Posts: 45
Joined: 07 Mar 2024
Has thanked: 13 times
Been thanked: 1 time

Re: Changed: How to change input settings after initialization?

Postby Talky_Zebra » 25 Apr 2024

Hi Multicharts team and expert coders - I have changed my original question from above. I have noticed that when changing an [Input] property in an indicator or signal programmatically after the indi or signal is initialized causes unexpected behaviors - ie: it breaks. Using a similar example to the above, let's say we have an input like so:

Code: Select all

[Input] public int my_int { get ;set; } ... protected override void StartCalc(){ my_int = 20; }
Later in the code, I have the following... perhaps as part of signal logic, loading data from file, or mouse clicks on the chart:

Code: Select all

PropertyInfo pi = this.GetType().GetProperty("my_int "); pi.SetValue(this, 5, null);
This method is especially useful if I want to make re-usable code, what introspection is built for. In this kind of use I would loop through the properties and get their names and values like so:

Code: Select all

var type = this.GetType(); PropertyInfo[] properties = type.GetProperties(); var prep_serialization_input_dictionary = new ExpandoObject() as IDictionary<string, object>; foreach (var this_property in properties) { object[] att = this_property.GetCustomAttributes(typeof(PowerLanguage.InputAttribute), false); if (att.Length > 0) { string this_name = this_property.Name; dynamic this_value = this_property.GetValue(this, null); if (this_property.PropertyType.IsEnum) { this_value = this_property.GetValue(this, null).ToString(); } prep_serialization_input_dictionary.Add(this_name, this_value); Output.WriteLine("{0}, {1}", this_name, this_value); } }
and then set the property similar to

Code: Select all

this_property.SetValue(this, this_value, null);
What happens when trying to set the properties
- If I try to Format Indicator or Format Signal after the above code is run... and change the inputs, those changes are ignored
- Built in functions will show erratic responses. Such as if the above my_int variable was to change the length of AverageFC(), the resulting average line is not what you'd expect.

Trying to remediate this by implementing a method that calls this.StartCalc() as the below does not help:

Code: Select all

protected override void OnMouseEvent(MouseClickArgs arg) { this.my_int++; this.StartCalc(); }
And trying a call to this.Create() in an attempt to recreate the series or function objects gives an error, so that's unusable?

Trying non-Reflection functions, such as:

Code: Select all

my_int = 50;
after initialization will lead to similar unexpected results.

So, is there any way to make this type of change programmatically, and then triggering something similar to a re-initialization? Are there example techniques for this?

BD.
Posts: 20
Joined: 02 Feb 2024
Has thanked: 4 times
Been thanked: 2 times

Re: Changed: How to change input settings after initialization?

Postby BD. » 03 May 2024

if you want to store values and then retrieve them later after program was closed, from my understanding, the only way is to actually save them. you can save them by saving values to .txt and then retrieving from the same file.

Code: Select all

File.WriteAllText(Path.Combine(@"C:\Users\make\sure\path exist to\folder\", "myEasyToFind.txt"), 1230.ToString());

Code: Select all

File.ReadAllText(Path.Combine(@"C:\Users\make\sure\path exist to\folder\", "myEasyToFind.txt"));//output.writeline()
when retrieving I assume you'd need to parse string. easy task if you made an original file.

Or are you trying to change functions inputs dynamically? You can do so by using a variable. initialize variable with input value. assign variable to whatever, then change variable any time.

Code: Select all

if (Bars.CurrentBar==200000) { xAvgSlow.Length = 1; //or var=1 } if (Bars.CurrentBar == 202000) { xAvgSlow.Length = 120; }


Return to “MultiCharts .NET”