New question on persistence of variables

Questions about MultiCharts and user contributed studies.
RWDickinson
Posts: 43
Joined: 01 Dec 2008
Has thanked: 2 times
Been thanked: 2 times

New question on persistence of variables

Postby RWDickinson » 08 Dec 2008

I want to code a simple state machine in a called function, and use that state machine in a signal. The state machine accepts a "context" input that tells what part of the state machine should be updated. My problem: since the function is called under various conditions, it sometimes gets called twice in the same bar, with different contexts. I don't know whether it is the "twice" or the "different contexts" that is causing my problem, but:
A variable that is set in the first call on a bar in context1 never shows that new value when called in context2, whether or not in the same bar.

***************
things I have tried
***************
I thought IntraBarPersist might help on the called function, so put that modifier on the function's variables. Does not help.

Sometimes (I don't quite understand this) when a function is called with different parameters, you actually get different instances of the same function and its variables, so I made the "context" parameter a variable in the calling signal, instead of a literal, since I want to have only one instance of the function and its variables. Does not help.

******************
simple demonstration
******************
I've coded a simplest-case signal and function (see attached). Note that after each "Resetting"/"Reset" pair, I want to get a "New Start" output, but that never occurs except on bar1 (where I didn't have to do a reset). In other words, I want the "Latest Start" numbers to increase by 10's as the signal progresses through the bars, but "Latest Start" always stays at 1.

Should be able to run this on any kind of chart. No signals are actually generated (no buy or sell statements) but the output in the PLEditor "output" tab shows what I'm talking about.

All suggestions gladly considered. Thanks.
Attachments
RD_StateTest_outputResult.txt
the output results
(1.35 KiB) Downloaded 397 times
RD_StateTestFunc.txt
the state-machine function
(484 Bytes) Downloaded 406 times
RD_StateTestSignal.txt
the calling signal
(476 Bytes) Downloaded 409 times
Last edited by RWDickinson on 10 Dec 2008, edited 1 time in total.

rsi77
Posts: 11
Joined: 03 Dec 2008
Location: Chicago

Postby rsi77 » 08 Dec 2008

OK, I didn't have time to thorougly study your problem, but try the following:

Place your function call inside an if state as follows:

IF BarStatu(1)=2 THEN Function Call;

This will call the function only on the last tick of the bar.

Next any variables which have been assigned values based on the function call will need to be defined with intrabarpersist.

I solved a problem somewhat similar to yours using the above.

Ron

RWDickinson
Posts: 43
Joined: 01 Dec 2008
Has thanked: 2 times
Been thanked: 2 times

Postby RWDickinson » 08 Dec 2008

Thanks. In this very simple demo, I don't store the result from the function call anywhere, so there are no variables in the caller dependent on the value returned from the function (at least I think that's what you meant). All of the code is now guarded by "if barstatus=2" so state machine function and counter update is only happening once per bar (I think this was true anyway) but this did not change my results at all.

When I say called multiple times in a bar I mean that in a single pass of my calling code (when, say, barstatus=2) I check multiple conditions and may call the function multiple times before reaching the end of the code. The variables in the called function do not have the same value on the second and subsequent calls.

But I'm now more inclined to think it has to do not with the fact of multiple calls but that somehow I'm getting multiple instance of the variables - in the same way the XAverage(high,10) gives me a different instance of the variables than XAverage(high,20): Each of them internally uses XAverage[1] but they're different series.

Basically I just don't understand what's happening here. Very frustrating. Oh, help.
Last edited by RWDickinson on 10 Dec 2008, edited 1 time in total.

drwar
Posts: 218
Joined: 31 Jul 2005

Postby drwar » 10 Dec 2008

IF BarStatu(1)=2 THEN Function Call; Will not work as you want

IF BarStatus(1)=2 Then // Code // Will work

Functions will be executed regardless of the logic statement. You could code the barstatus command into all appropriate functions.

J~

RWDickinson
Posts: 43
Joined: 01 Dec 2008
Has thanked: 2 times
Been thanked: 2 times

Postby RWDickinson » 10 Dec 2008

Drwar, are you saying that barstatus does not work in top-level code and has to be coded in the called function? Or are you just pointing out the typo 'barstatu' in rsi77's code? The latter is fine, I ignored the typo and assumed he meant 'barstatus'. The former would just astound me and cause me to abandon EL forever. Or maybe I'm missing your point altogether?

In any case, I can't code the 'barstatus' (if it's needed in the first place) in the called function: the logic just won't flow from there. What would I do with calls that came in on a non-last-tick? Just abandon them?

Still very confused.

RWDickinson
Posts: 43
Joined: 01 Dec 2008
Has thanked: 2 times
Been thanked: 2 times

Postby RWDickinson » 10 Dec 2008

I just modified my original post to add the output results, so that people don't have to run the example to see what its results are. There's only about 20 lines of code total here, and several of those are print statements.

drwar
Posts: 218
Joined: 31 Jul 2005

Postby drwar » 10 Dec 2008

RW
I you are running update every tick and you are trying to use the Barstatus command to exclude a function from executing on every tick. It will not work unless the barstatus command is in the function being called. If you can code the exclude outside the function, It can be coded inside the function. What difference does it matter if it is wrapped externally or internally by the logic.

J~

RWDickinson
Posts: 43
Joined: 01 Dec 2008
Has thanked: 2 times
Been thanked: 2 times

Postby RWDickinson » 10 Dec 2008

drwar: First, you would have to give me some reason other than you word for it that the barstatus function can be called from some contexts and not others. That would make PL such a strange language that I would totally give up on ever using it. The documentation makes no such claim that I can find.
Second, it makes a difference because the called function doesn't have all the context that the outer code has, and because the outer code can't know (after the fact) whether the call had the intended effect:

----------------------------------------------
{outer}
variable x(0);
if x=... and barstatus=2 then begin
funccall(dosomething);
x += 1;
end;

{function}
inputs: command("dosomething");
if command="dosomething" then begin
<code goes here>
end;
----------------------------------------------

if you move the barstatus check to the called function, how would the outer code know whether the dosomething had been done? If it hasn't, then he shouldn't update his x variable.
And what shoud the function do with the call if barstatus <> 2? ignore it? and how would it let the outer code know that nothing had been accomplished? I don't understand how you can possibly be confused about this. Your belief that the check can be moved with no ramifications could only be true in a pure language with no side effects at all..... and there are no such languages. Certainly PL is not one.

drwar
Posts: 218
Joined: 31 Jul 2005

Postby drwar » 10 Dec 2008

Then don't take my word for it. I was just attempting to help you out. Prove or disprove it to yourself, thats all that matters for a programmer.

J~

P.S. - I never said that it had anything to do with the context of barstatus. You are reading into what I posted.

User avatar
Marina Pashkova
Posts: 2758
Joined: 27 Jul 2007

Postby Marina Pashkova » 18 Dec 2008

Hi everybody,

If somebody needs an answer to the above (we have helped Rob to code what he's talking about in the posts above):

Here's the code for the function:

Code: Select all

Inputs:
Context (StringSimple),
TrueStateBar(NumericSimple);

Variables:
StateBar (0);

StateBar = TrueStateBar ;

If Context = "Reset" then begin
print(Date," ",Time_s," ",currentBar," Reset ");
StateBar = 0;
end
else begin
if StateBar=0 then begin
print(Date," ",Time_s," ",currentBar," New Start ");
StateBar = CurrentBar;
end;
end;

RD_StateTestFunc_ = StateBar;
And here's the one for the indicator:

Code: Select all

Variables:
Count (0),
StateTestContext (""),
intrabarpersist _State(0);

if Count >= 10 then begin
print(Date," ",Time_s," ",currentBar," Resetting ");
StateTestContext = "Reset";
_State = RD_StateTestFunc_(StateTestContext, _State);
Count = 0;
end;

StateTestContext = "";
_State = RD_StateTestFunc_(StateTestContext, _State);

print(Date," ",Time_s," ",currentBar," Latest Start ", _State);

Count += 1;
Regards.


Return to “MultiCharts”