Help with scripting language for temporal filtering


I have been trying to create the simplest of a number of planned temporal (bar-to-bar) filters that operate on a sequence of price-related binary pulses with a ‘1’ or 'ON' duration of D bars where D >= 1. These pulses are separated by at least one bar of binary ‘0’ or 'OFF'. A filter of this type accepts a binary stream in and produces a binary stream out. By cascading these filters end to end, a final filtered waveform is produced and this is the required output of the code. In any one call attached to a bar (in a SHOWPLOT, for example), the filter must remember and use variables set up in the previous bar before they are later recomputed for the next bar. Changes in dynamics mean that I must be able to, on occasion, assert variables at more than one place in the sequence of the lines of code.

The bare minimum functionality is to be able to modulate measured input pulses to introduce delays-to-ON and delays-to-OFF. This has the effect of being able to filter out specific noisy pulses in the input stream. This is elementary digital filtration I could do easily in every other language I am familiar with. But no matter what I do I cannot implement the filter using Optuma script for 1 fundamental reason:

The scripting language insists that variable declaration and assertion must happen on the same line and the variable cannot be referenced until that line is executed.

Before discussions ensue, some notes:

  1. I have tried huge numbers of combinations of SWITCH or COUNTSINCESIGNAL or TIMESINCESIGNAL and IF().
  2. I am conversant with the pascal [n] backwards array referencing. It does not solve the problem.
  3. I have tried many different ways of using duplicate scripts early in the script. Bat-to-bar timing means it does not work because no matter what you do, in Bar N, you need to first examine a variable by name that was asserted at the end of the previous bar's (N-1) processing, and before the variable is reassigned later in (N) ... a reassignment that is dependent on the original reference early in bar N. Of particular note is the need to examine the state of a counter (COUNTSINCESIGNAL ) variable assigned at the end of the previous bar's processing.
  4. I can't use NOREPEAT() because there's no examples in the knowledge base of how to embed NOREPEAT() into the above functions at the moment of their call. Without knowing what NOREPEAT actually does it's function is mysterious.


a) I have not found the right way to use the Optuma scripting language


b) The basic scripting language is fundamentally ill-suited to this problem.

I am, as usual, starting with the premise I have missed something. I assume you can help me see how to do it. I am looking for ways ahead.

Q. How do you use NOREPEAT as per 4. above? (it probably doesn't matter ... it was only a guess it might be able to be coerced into doing what I want.)

Q. Have I missed something? Is there some function that does what I want?

Q. Does the Pascal programming environment relieve the programmer of the scripting limitation?

I look forward to your comments. I have placed below a basic test functionality which I claim is impossible to do in Optuma basic script.


Test functionality (I have tried many dozens of times to do this)



I work only in daily bars. Two price related binary pulse streams A and B (1 bar wide pulses) that never coincide. A is always followed by a B and a B is always followed by an A. (Think of a A = 'crossing up' and B = 'crossing down' to create it).


Measure the gap (in bars) between A and B.

If the gap exceeds N bars, then wait for B and then inhibit any and all A that occur for M bars after B.

else do nothing (pass through the next B without doing anything).


A) output stream is the same is the input EXCEPT the inhibited A pulses are missing

B) output stream is the same is the input B stream.

The problem? The 'inhibit' signal' that deletes the A pulses, is a product of the previous bar, must be examined early, before later being recomputed based on the previous processing.


Hi Colin

The non repeat function will return true when its source returns true, but once set to true it will ignore any other signals from source for up to the number or bars specified. e.g.

x = CLOSE() > OPEN();


If you put this in a showview you will see that once it is triggered it will not trigger again for at least 10 bars.

This is function is covered in the advanced scripting course


The current list of non tool functions is here

This list is continually being updated, and will be updated in the near future with new functions.

The tool programming functionality has much more options to creating custom tools or functions. However it does require basic programming knowledge.

There have been a few issues found with self referencing variables and the fixes are currently being tested in beta.

Can you please send through an example of your script using notation and we will see if it is fixed by the recent changes.

see here for info on self referencing variables


I attempted to meet your criteria without self referencing, does this script meet your conditions ?

a1 = CLOSE() CrossesAbove  MA();
b1 = CLOSE() CrossesBelow MA() ;
c1 = a1 or b1;
c2 = NOREPEAT(c1, BARS=5);
o1 = if (n > 3, c2, c1);
plot1 = b1;
plot1.Colour = Red;
plot2 = o1;
plot2.Colour = Blue;


Hi Peter,

In relation to the test program. I have run it and no it doesn't. It produces pulse extensions, not pulse removal. It This may be because of the way I specified it! I have to investigate. I also have to become familiar with the NOREPEAT and TIMESINCE... functions before I can comment further.

Nevertheless.... Thanks for the links and the directions to explore... appreciated! It's all I can really expect at this stage .... watch this space... I'll report back. Very helpful.




See below for the functionality I require and that I have been struggling to implement.

I will now set about writing the script using a timing function and SWITCH.




This is the first run at the code from the spec. of the previous posting. Simple enough:


This shows the code was accepted by the script editor.

This is the script:


// Filter setpoints Non_1 = 4; // A->B interval threshold Nih_1 = 3; // number of A pulses to inhibit after next B pulse //Filter inputs A_1 = CLOSE() CrossesAbove MA(); B_1 = CLOSE() CrossesBelow MA() ; // Filter processing A_1_cnt = COUNTMATCHSINCESIGNAL( 1, A_1 and (inhibit_1[1] == 0) ); B_1_cnt = Nih_1 + 1 - COUNTMATCHSINCESIGNAL( 1, B_1 and (A_1_cnt >= Non_1) ); inhibit_1 = SWITCH( (A_1_cnt >= Non_1), (B_1_cnt <= 0) ); // Filter outputs A_2 = A_1 and (inhibit_1 == 0); B_2 = B_1; // Plot values plot1 = 12 + A_1; plot1.Plotstyle = Step; plot1.Colour = Blue; plot2 = 10 + B_1; plot2.Colour = Red; plot2.Plotstyle = Step; plot3 = A_1_cnt; plot3.Colour = Blue; plot3.Plotstyle = Step; plot4 = B_1_cnt; plot4.Colour = Red; plot4.Plotstyle = Step; plot5 = -4+inhibit_1; plot5.Plotstyle = Step; plot5.Colour = Black; plot6 = -6 + A_2; plot6.Colour = Blue; plot6.Plotstyle = Step; plot7 = -8 + B_2; plot7.Colour = Red; plot7.Plotstyle = Step; plot8 = 0.0; plot8.Colour = Gray; plot8.Plotstyle = line; plot8.Linestyle = LongDashDotDot;


I could not use the editor PRE/POST option. It simply didn't allow me to. Sorry!

This is what the failed output looks like:


I look forward to forum advice!






This is clearly an issue out of my control, with Optuma not behaving as expected, so I'll raise a tech support ticket and see how I go.