Hi all. It seems I am stuck with understanding what for VariableObject and VariableSeries are needed. I meet them in many examples, uderstand their functionality, but do not get why we can not use the simple int (or double, or short - does not matter) insted of them.
Here is the code of pre-build Signal MovAvg_Cross_LE
Can anyone explain why we create m_counter variable as private VariableObject, but not as simple int in this case? It would work the sme way, but why to use something that make code less readable? I am sure there is a reason here and think if I get it so I get the functionality of the VariableObject. Thanks.
Real usage of VariableObject
- JoshM
- Posts: 2195
- Joined: 20 May 2011
- Location: The Netherlands
- Has thanked: 1544 times
- Been thanked: 1565 times
- Contact:
Re: Real usage of VariableObject
I'm also curious to hear why `VariableObject<T>` is used here; I agree with you that it needlessly complicates things.Can anyone explain why we create m_counter variable as private VariableObject, but not as simple int in this case? It would work the sme way, but why to use something that make code less readable? I am sure there is a reason here and think if I get it so I get the functionality of the VariableObject. Thanks.
Actually, speaking of 'real usage' for `VariableObject<T>`: I cannot think of any. If I search all my script files in Visual Studio, then I've only used `VariableObject<T>` once, and that was to explore how it works..
I suppose that other people may use it much more often than I do, but for my purposes it's always more intuitive (for me) to use a regular collection or a simple counting variable.
This probably also just shows that there are more ways to approach something, and that it's also a matter of personal preference which approach to use.
-
- Posts: 8
- Joined: 12 Mar 2016
- Has thanked: 1 time
Re: Real usage of VariableObject
The only idea I have after considering this is that if using ordinary int in this case, the problem would come up at real-time trading, cause the int m_counter would be recalculated on every tick, while you need it to be +1 after every bar that close is higher than given MA.I'm also curious to hear why `VariableObject<T>` is used here; I agree with you that it needlessly complicates things.Can anyone explain why we create m_counter variable as private VariableObject, but not as simple int in this case? It would work the sme way, but why to use something that make code less readable? I am sure there is a reason here and think if I get it so I get the functionality of the VariableObject. Thanks.
Actually, speaking of 'real usage' for `VariableObject<T>`: I cannot think of any. If I search all my script files in Visual Studio, then I've only used `VariableObject<T>` once, and that was to explore how it works..
I suppose that other people may use it much more often than I do, but for my purposes it's always more intuitive (for me) to use a regular collection or a simple counting variable.
This probably also just shows that there are more ways to approach something, and that it's also a matter of personal preference which approach to use.
But I an not sure I am right here.
And if I am right here I then do not see the difference, why sometimes I have to use VariableObject and sometimes VariableSeries. Can not get it practical..
- JoshM
- Posts: 2195
- Joined: 20 May 2011
- Location: The Netherlands
- Has thanked: 1544 times
- Been thanked: 1565 times
- Contact:
Re: Real usage of VariableObject
That's true, but I think that problem also happens with the `VariableObject<int>` here. That integer that's tied to the specific bar that's being evaluated by the script is also updated on every real-time tick. The difference is (from how I look at it) that there's no 'carryover effect': every bar there's a new object (int in this case) that's used with the calculations. However, if we use a single integer variable, we can of course reset that variable so there isn't a real problem that's solved by using `VariableObject<T>` here (from my understanding).The only idea I have after considering this is that if using ordinary int in this case, the problem would come up at real-time trading, cause the int m_counter would be recalculated on every tick, while you need it to be +1 after every bar that close is higher than given MA.
By the way, we can use `Bars.Status` (for the first data series) or `BarsOfData(x).Status` (for the xth data series) to check whether the script is calculated on bar close. That way the counter variable will be only incremented once per bar, for example:
Code: Select all
protected override void CalcBar()
{
double m_Avg = m_AverageFC[0];
if (Bars.Status == EBarState.Close && PublicFunctions.DoubleGreater(Price[0], m_Avg))
{
++m_Counter.Value;
}
else
{
m_Counter.Value = 0;
}
if (PublicFunctions.DoubleGreater(Bars.CurrentBar, ConfirmBars)
&& m_Counter.Value == ConfirmBars)
{
m_MACrossLE.Send();
}
}
-
- Posts: 8
- Joined: 12 Mar 2016
- Has thanked: 1 time
Re: Real usage of VariableObject
Actually it seems that VariableObject solves exactly this problem if I understand the manual.That's true, but I think that problem also happens with the `VariableObject<int>` here. That integer that's tied to the specific bar that's being evaluated by the script is also updated on every real-time tick. The difference is (from how I look at it) that there's no 'carryover effect': every bar there's a new object (int in this case) that's used with the calculations. However, if we use a single integer variable, we can of course reset that variable so there isn't a real problem that's solved by using `VariableObject<T>` here (from my understanding).
By the way, we can use `Bars.Status` (for the first data series) or `BarsOfData(x).Status` (for the xth data series) to check whether the script is calculated on bar close. That way the counter variable will be only incremented once per bar, for example:
(This same can also be done with a simple int counting variable, of course).Code: Select all
protected override void CalcBar()
{
double m_Avg = m_AverageFC[0];
if (Bars.Status == EBarState.Close && PublicFunctions.DoubleGreater(Price[0], m_Avg))
{
++m_Counter.Value;
}
else
{
m_Counter.Value = 0;
}
if (PublicFunctions.DoubleGreater(Bars.CurrentBar, ConfirmBars)
&& m_Counter.Value == ConfirmBars)
{
m_MACrossLE.Send();
}
}
Here is the quote:
So they say here that if you want something to be calculated once a bar (not oftener) use the VariableObject.Those, who are familiar with C# or other OOP programming languages know such things as class fields.
Together they form the state of the object of the given class. In PL.NET there are special classes of variables
which make the writing logic of functions, indicators and signals easier regardless of whether the calculation
is executed based on historical or real-time data. When calculating a study on historical data, CalcBar()
method will be called once for each bar. This is an example of such a version of CurrentBar:
public class CurrentBar : FunctionSimple<int>When calculating on historical data this function will return correct values only if it is called once per bar. InCode: Select all
{
public CurrentBar(CStudyControl master) : base(master){}
private int m_current_bar;
protected override int CalcBar(){
return ++m_current_bar;
}
protected override void StartCalc(){
36
m_current_bar = 0;
}
}
real-time calculation, CalcBar will be called on each tick of bar, the function will not work correctly. To make
it work correctly, its logic should be changed. For example:As we can see, the value of the variable has to be incremented only at the bar close. For these cases specificCode: Select all
protected override int CalcBar(){
var _result = m_current_bar + 1;
if (Bars.Status==EBarState.Close)
++m_current_bar;
return _result;
}
variables exist: VariableSeries<T> and VariableObject<T>. VariableSeries<T> should be
used when it is necessary to call for the values of the previous bars variable. Considering this, the example
would look like this:
public class CurrentBar : FunctionSimple<int>Code: Select all
{
public CurrentBar(CStudyControl master) : base(master){}
private VariableObject<int> m_current_bar;
protected override int CalcBar(){
return ++m_current_bar.Value;
}
protected override void Create(){
m_current_bar = new VariableObject<int>(this);
}
}
Henry, or someone from Multicharts, is that right?
- Henry MultiСharts
- Posts: 9165
- Joined: 25 Aug 2011
- Has thanked: 1264 times
- Been thanked: 2957 times
Re: Real usage of VariableObject
That is correct.So they say here that if you want something to be calculated once a bar (not oftener) use the VariableObject.
Henry, or someone from Multicharts, is that right?