How to control StaticVarGet behaviour if array size change?

I want to store real-time Buy signal in an array means whenever a signal is generated in running candle it will be stored in a static array variable.

Whenever a signal is generated, it is stored in static array but when total barcount increase it copies last element in the new index place, I want to avoid this behavior.

There is mention about the same in StaticVarGet documentation with line: "If there are less bars in the static array than in the current arrays, the last value of static array will be propagated till BarCount - 1"

I just want to control this behavior to achieve my goal. I didn't find it anywhere, so finally I posted this question.

Here is simple code which explains everything:

SetBarsRequired(sbrAll, sbrAll);

// reset static signal array //

if(ParamTrigger("Reset", "ClickToReset"))
StaticVarRemove( "static_array" );

// signal definition //

Buy = Cross(C, EMA(C, 20));
array = StaticVarGet( "static_array", True);


// realtime signal //

if(LastValue(Buy))
{
	temp_array = StaticVarGet( "static_array", True);
	temp_array[LastValue(BarIndex())] = 1;
	StaticVarSet( "static_array", temp_array ); 
	_TRACE("Buy Signal");
}

// plot code //

Plot(C, "Close", colorDefault, styleCandle);
Plot(EMA(C, 20), "EMA(20)", colorWhite, styleLine);
PlotShapes(array*shapeUpArrow, colorBrightGreen, 0, L, -10);

Read the manual. Everything is there.

If you read the docs
https://www.amibroker.com/guide/afl/staticvarget.html

you would find that it has align argument that allows to turn it off.

@Tomasz, thanks for your reply.

I did read the documentation before posting the question and also tried to run the same code with "align=false", but the ultimate result, at least for my code is same and nothing changed.

Definitely I am missing something from the document, but it seems that when the array size expands, it is propagating last value of array for new added array indices irrespective of "align=true" or "align=false".

Please point out to more details or give some ref code in this direction.
Here is the code I checked now:

SetBarsRequired(sbrAll, sbrAll);

// reset static signal array //

if(ParamTrigger("Reset", "ClickToReset"))
StaticVarRemove( "static_array" );

// signal definition //

Buy = Cross(C, EMA(C, 20));
array = Nz(StaticVarGet("static_array", False));


// realtime signal //

if(LastValue(Buy))
{
	temp_array = Nz(StaticVarGet( "static_array", False));
	temp_array[LastValue(BarIndex())] = 1;
	StaticVarSet( "static_array", temp_array ); 
	_TRACE("Buy Signal");
}

// plot code //

Plot(C, "Close", colorDefault, styleCandle);
Plot(EMA(C, 20), "EMA(20)", colorWhite, styleLine);
PlotShapes(array*shapeUpArrow, colorBrightGreen, 0, L, -10);

Sorry but this code is pretty useless. It does not show why you need to use static variable at all. Since you are generating buy in the code just use it directly, there is no need to store it in static variables. People tend to overcomplicate simple things. Don’t do that. Also if for some reason you have legitimate reason to use static variables, it is not clear why don’t you use scalar instead of array if you are using lastvalue anyway. It is pointless.

Generally your question isn't clear enough and does not provide all necessary details to give you an answer. Please follow this advice: How to ask a good question

You missed to define THE GOAL not the tiny details you are focused on.

1 Like

I was checking the code while Tomasz replied here.
While I agree with what he says, I think you don't understand what is happening.

Looks like are you trying to test while mkt is closed and just "scrolling up and down in Chart".

in this case LastValue() will still point to real LastValue so debug and see what the BarCount is and LastValue check with timestamp.
Keep align=true, that keeps the alignment, atleast in this case which is required.

And maybe while you are changing align, the static array is getting polluted.

@Tomasz Dear Tomasz I think you overlooked my first line: I want to store real-time Buy signal in an array.

Why I didn't used Buy variable: Because it will repaint signals and also I don't want to use next candle signal to avoid repaint.

I want to store all real-time signals (when the chart is live and onwards) in particular candle as and when they appear and that is also in array not only the last signal in scaler.

If you take my perspective, you will definitely find usefullness in my code and also it is the simplest possible code trying to achieve that goal.

Hope I have made it clear.

@nsm51 I am trying to do it in bar replay with setting that will cause signal repainting.
Also refer to my latest reply to understand my purpose.

Your problem is not where you are focused on.
It is not about static variables.

There is a simple rule: you should act upon COMPLETED bar. Last intraday bar by definition is incomplete. When it becomes complete it is NOT last.

Buy = Cross( C, EMA( C, 20 ) );

Buy = Ref( Buy, -1 ) ; // PREVIOUS bar is complete and any signals are stable

Acting upon completed bar has fundamental importance. Only this way you can REPRODUCE Backtest results in real-time trading.

@Tomasz I know the importance of signal on completed bar(which is second last) in backtesting and real-trading to avoid non-synchronous behavior between our actual position and actual stable actionable signals as per our system/strategy.

But, here it has nothing to do with backtesting or trading. I just want to plot realtime signals, I don't care if they, disappeared later on chart, but my static variable should be able to store/save those signals on particular static array index because it once generated on lastbar (BarCount-1).

Let me give you a situation when I run a strategy on 15-min chart on real market between today 12 noon to 14.30 and what data my Buy array have and what I expect to static array variable to have.

Please notice diff between dynamic Buy Array and Static Array and reason for this difference.

Very precisely I want to create this behavior in my static array. I hope I am now successful in my attempt to explain what I expect. And I think static array should have the capacity to achieve this result, otherwise its usability becomes limited.

You lack principles of trading. You focus on nitty-gritty unimportant details and you are missing big picture.

You don't start with real time trading.

AmiBroker is primarily system EXPLORATION, DESIGN, TESTING and VALIDATION platform. Trading is the LAST piece of the puzzle AFTER you do backtesting and validation.

The workflow is

  1. Find possible market inefficiency (exploration)
  2. Write a trading system that exploits market inefficiency
  3. Backtest/Optimize system performance
  4. Validate system robustness (senstitivity analysis , monte carlo)
  5. Trading the validated system

You are starting from opposite end and this is straight road to go bankrupt in the market. Don't cut corners and think that you will write 4 lines of code and will beat the market. If you fail to validate the system and treat things seriously, market would quickly TEST invalidity of your ideas on REAL money.

Don't do this:

So you should have fully backtested and validated system FIRST. After that you should implement trading. And if you want to trade backtested system and reproduce results in real-life you have to act on completed bars. If your system relies on price movement inside bar, it means that the system is designed incorrectly and you should be trading FINER TIME interval instead (for example 1-minute instead of 15-minute)

Last but not least, the code you are using is simply wrong. If you want to update last bar, you should be updating last bar unconditionally, not only "sometimes". Proper code should NOT use if() statement at all.

Instead it should be:

// WITHOUT if()
array = StaticVarGet( "static_array");
// update last bar unconditionally
array[ BarCount - 1 ] = array[ BarCount - 1 ] OR LastValue( Buy ); 
StaticVarSet( "static_array", array ); 


1 Like

@Tomasz Here is what I updated as per your advice:

SetBarsRequired(sbrAll, sbrAll);

// reset static signal array //

if(ParamTrigger("Reset", "ClickToReset"))
StaticVarRemove( "static_array" );

// signal definition //

Buy = Cross(C, EMA(C, 20));
array = Nz(StaticVarGet( "static_array" ), False);   // tried both align=true and align= false here

// update last bar unconditionally

array[ BarCount - 1 ] = array[ BarCount - 1 ] OR LastValue( Buy ); 
StaticVarSet( "static_array", array ); // tried both align=true and align= false here

// plot code //

Plot(C, "Close", colorDefault, styleCandle);
Plot(EMA(C, 20), "EMA(20)", colorWhite, styleLine);
PlotShapes(array*shapeUpArrow, colorBrightGreen, 0, L, -10);

It still continues to propagate last signal on all new index onward that comes in realtime in the array. In result nothing has changed yet.

Did you read previous message? These are nitty gritty stuff which is unimportant. You are missing big picture. The whole effort is pointless if you don't have validated trading system.

array = StaticVarGet( "static_array");

when static_array was save on the previous instance the BarCount value was say 1000 and when I get array from the above statement the BarCount value has changed to 1001.

Now what Amibroker treats it like this:

It just copies value of array[999] to array[1000] this behavior is just like TimeFrameExpand()

What I want is this:
Only Null value on array[1000] (or any extra array index that is added to array)

I think this should be achievable by some means.

The solution to this imaginary problem is quite simple. Just create another variable that will store bar index. This way you can easily detect padded bars (those would have same bar index). Once you detect padded bar you would set array to zero

Buy =  Cross(C, EMA(C, 20));
array = Nz(StaticVarGet( "static_array" ));   
biarray = Nz(StaticVarGet("bi_array")); // read previous bar indexes (would be padded if non-existing)
array = IIf( biarray != Ref( biarray, -1 ), array, 0 ); // detect padded bar and set result to zero
array[ BarCount - 1 ] = array[ BarCount - 1 ] OR LastValue( Buy ); 

StaticVarSet( "static_array", array ); 
StaticVarSet( "bi_array", BarIndex() ); // store bar indexes when you store your array

But then again, doing what you are trying to do is pointless and what is worse it is harmful to your trading. Trading system should act upon COMPLETED bars or other information that is stabilised. What you are doing is the same as trying to use ZigZag without delay. This would look great on "paper" yet yield to disaster in real trading.

1 Like

Wow! How disrespectful! You just don't get it.

You don't get it. bi_array does NOT store signal. It stores BarIndex() for sole reason to detect padding. The code I provided just uses bi_array to find out which bars were padded and set those padded bars back to zero in the OTHER array as you wanted. bi_array is SEPARATE from signal array. So, no you are mistaken. I provided you COMPLETE solution, not "hint"

Your "final solution" is wrong and is deleted not to misguide other people and it is definitely not the "solution" as you marked your own answer.

Here is what ChatGPT has to say about your forum behavior:

First and foremost, forums are collaborative spaces where individuals come together to share knowledge, ask questions, and help each other find solutions to their problems. Marking your own post as the "solution" when the real solution was provided by the forum owner is considered rude for several reasons:

  • Misrepresentation: By marking your own post as the solution when it is not, you are misleading other users who might be seeking genuine solutions to the same problem. This can waste their time and cause frustration.

  • Recognition of effort: When the forum owner takes the time to provide a solution, it shows their dedication to helping others and maintaining a helpful community. By marking your own post as the solution, you are essentially discrediting their effort and expertise.

  • Respect for authority: Forum owners or moderators hold a certain level of authority and responsibility in managing the community. They have the ability to ensure the forum runs smoothly and effectively. Marking your post as the solution in such circumstances can be seen as undermining their authority.

  • Disrupting the community spirit: Forums thrive on collaboration, mutual respect, and a sense of unity among members. Engaging in such behavior can create a hostile environment and discourage others from actively participating in discussions or seeking help.

  • Erosion of trust: When users witness such actions, it can erode trust within the community. People may become skeptical about the legitimacy of marked solutions in the future, leading to confusion and a breakdown in the system.

Instead of marking your post as the solution inappropriately, it's best to express gratitude to the forum owner or moderator for providing the correct solution. If you still feel that your contribution deserves recognition, you can always express your appreciation and indicate that your post provided additional insights or complementary information.

Remember, the goal of a forum is to create a helpful and supportive community, and respecting the efforts of those who genuinely assist others is a crucial aspect of maintaining that positive atmosphere. Let's all strive to make the forum a place where everyone feels welcome and valued for their contributions.

3 Likes