Trailing stop not saving when Amibroker is closed when you use Norgate plug

Hi

I have got an AFL that uses on screen buttons to plot and save a trailing stop onto a chart. The formula has been working well for quite a while but recently it isn't saving correctly when I close Amibroker.

Here is an example of the problem.

  1. I open up $spx and apply the trailing stop to the weekly chart on bar (25/9/20) and save the trail.

  2. Close Amibroker

  3. I restart Amibroker and I have no trail.

  4. I restart Amibroker again and I now have the trail that I saved in step 1.

As another example.

  1. I open up $spx and apply the trailing stop to the weekly chart on bar (25/9/20) and save the trail.

  2. Close Amibroker

  3. I restart Amibroker and I have no trail.

  4. I decide to reapply a new trail on $spx on bar (5/3/21)

  5. I close Amibroker

  6. I restart Amibroker. Instead of the most recent trail that I plotted on 5/3/21 it now displays the original one that I plotted on 25/9/20

  7. I close Amibroker and restart it again and it now displays the trail that I plotted on 5/3/21

I have tried uninstalling Amibroker from my computer and installing it from new. I registered it and then tried applying the trail to the default database that comes with Amibroker. The trail saved perfectly every time I closed the program. I tried approx 20 times and it always worked correctly.

I get my data from Norgate so I opened up the data updater and clicked the Amibroker integration to install the Amibroker plugin. Once I did this the trail started playing up again just like before.

I also noticed that another AFL that I have that uses a paramtrigger is doing the exact same thing.

I contacted Norgate to find out if it is an issue with the plugin but I was told that it's not that.

Can anyone please tell me what might be causing this?

I'm running Amibroker Professional 6.40 on Windows 10.

Thank you.

@Ozzietrader is talking about code I wrote in 2017. I do not have this problem on my computer. What Ozzie is saying is he stores a persistent static variable and then exits Amibroker. When he starts Amibroker back up it seems gone. Then if he starts Amibroker back another time it is back.

Ozzie. Can you test it with this simple code and see if the problem persists

per = Param( "Period", 20, 2, 100, 1 );
trig1 = ParamTrigger( "Draw MA", "Press here" );
trig2 = ParamTrigger( "Clear Static Variable", "Press here" );

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "C", colorYellow, styleCandle, Null, Null, 0, 0, 1 );

if( trig1 )
{
    ma1 = MA( C, per );
    StaticVarSet( "ma1", ma1, persist = True );
}

if( trig2 )
{
    StaticVarRemove( "ma1" );
}

ma1 = Nz( StaticVarGet( "ma1" ) );
Plot( IIf( ma1, ma1, Null ), "ma1", colorAqua, styleLine, Null, Null, 0, 0, 2 );

so the problem Ozzzie is having can be described as follows:

using the test code posted in the previous post:

  1. trigger "Draw MA" button. Now the Moving average appears in the chart.
  2. then go to Menu, File, Exit and exit Amibroker
  3. then start Amibroker back up and then the Moving Average IS NOT visible in the chart
  4. then exit Amibroker again
  5. then start Amibroker back up and the Moving Average IS visible again

So personally (that is me empottasch) I do not have this problem. At my end everything works fine. The question is what could cause this problem to happen? Since Ozzie has this.

The strange thing is that when I uninstalled Amibroker and installed a fresh new copy I didn't have this problem. Everything worked fine on the database that came with Amibroker. The problem reappeared when I installed the Norgate database and then opened the Norgate updater and added the Amibroker plugin.

I still haven't found the cause of this problem. I deleted the Norgate plugin this morning to see if the problem went away. Sure enough, as soon as the plugin was removed the moving average will save to the chart every time I close Amibroker. Is there someone that uses Norgate data able to copy the moving average formula that was supplied by empottasch and see if the moving average saves correctly every time Amibroker is closed?

Thanks, Oz

In our testing here on AB 6.40.0 64bit on Windows 10 and Windows 11, persistent variables code as shown earlier in this thread, are saved by AmiBroker at program close time with either "Data Source: Local database" or "Data Source: Norgate Data Plug-in" set. It works fine in both scenarios.

I can't really think why persistent variables would be affected by the database plugin used, but clearly there's "something" triggering it.

Try trimming everything back to the basics (i.e. a simple, unadorned chart, no use of any Norgate Data functions etc.) and see if it's resolved. If so, slowly add those things back and when it starts to fail then you can figure out the culprit.

Static variables are UNRELATED to database. They are saved to PersistVars.bin file in current working directory (pretty much all paths in AmiBroker are relative not absolute). The only problem may appear when plugin (or anything else) changes current working directory for the program. Unfortunately, unlike Unix/Linux, in Windows there is some "standard" of using absolute paths (even with fixed things like "C:" drive that is always assumed), and programs, Windows OS (file dialogs) and pretty much everything seem to use "don't care" approach to current working directory and change it on number of occasions. AmiBroker prevents this in many cases for example by using OFN_NOCHANGEDIR flag in file dialogs, but plugins are free to call any OS functions including ones that change working directory and if they do, they would create problems.

For the record: I am NOT saying that Norgate is doing or not doing that.

I am still having a lot of trouble trying to find the cause of the problem. This morning I decided to give it one more try and I uninstalled Amibroker for the third time. I then went into program files and deleted the Amibroker folder. I uninstalled the Norgate updater and deleted all databases. I then opened up the registry and deleted all of the Norgate files. I also used to have Beyond charts on this computer which also used Norgate data so I deleted everything to do with that. Once I was sure everything was removed I did a full install of Amibroker and I reinstalled the Norgate updater. I then installed the Norgate plug-in and opened up a new database in Amibroker for Norgate.

After doing all of that the problem still remains. I have no idea what is going on. Iā€™m now noticing something else which is kind of strange. When I apply that moving average to a chart and I close Amibroker, when I restart Amibroker the moving average that I applied seems to be using data from another ticker. To hopefully try and explain this the following data relates to the closing price of the moving average that I applied to the chart before I closed Amibroker and then as I reopened Amibroker.

The format of the following data is as follows.

Symbol ā€“ MA value before I close Amibroker - MA value when I reopen Amibroker.

A LL ā€“ 45.59 ā€“ 307.65
ANZ ā€“ 27.86 ā€“ 405.59
APT ā€“ 121.72 ā€“ 27.86
BHP ā€“ 37.65 - 121.72

What seems to be happening is every time I close Amibroker and restart it, somehow the moving average is using the data from the prior time that I plotted it on another symbol. If I close Amibroker again and restart it. It uses the correct symbols data. No idea how this is happening. Iā€™m clearing the static variables before moving to the next symbol each time.

The following 3 photos are as follows.

  1. Before I close Amibroker the first time
  2. After restarting Amibroker
  3. After restarting Amibroker again

MQG before close
MQG when I open first time
MQG when I close and open second time

@Ozzietrader Can you please explain why are you using Parameter functions in conjunction with static variables instead of only Parameter functions? What is the main reason?

You need to remember that Parameters' values are cached and it might pose some problems in your situation. See here:

You need to understand that you are using SINGLE static variable that is SHARED and you are not using any key to differentiate between static variables for various symbols. Keying static variables is explained here:

http://www.amibroker.org/userkb/2007/04/21/using-a-static-variable-key/

If you use fixed static var name, it is shared among all symbols. So if your code is executed in the context of other symbol, you will get data from "previous" symbol that saved that static var earlier (unless you overwrite it with new data).
BTW: this code:

IIf( ma1, ma1, Null )

is pointless. It does not do anything, it is the same as you would just write ma1.

2 Likes

not true with respect to

IIf( ma1, ma1, Null )

because I call:

ma1 = Nz( StaticVarGet( "ma1" ) );

which is 0 when empty and would have messed up the chart in the code I posted previously. But it is irrelevant to the problem reported. So in my original code I added such a "key" as mentioned but for the example code I had not added that because it is just test code to be executed on the same symbol and same timeframe. But I added a key (in the code below) and Ozzie tested it again with the same problem.

So I post the slight adjusted code (adding this "key" ) again below.

Ozzie reports the following problem:

  1. load the code
  2. press "Draw MA" button
  3. exit Amibroker
  4. start Amibroker

then MA should now still be there. But Ozzie does not see the MA. He has to exit Amibroker for a second time and then start Amibroker up again and only then the MA appears. So to be clear. I do not have this problem.

So the question is: what could cause such a problem the occur?

per = Param( "Period", 20, 2, 100, 1 );
trig1 = ParamTrigger( "Draw MA", "Press here" );
trig2 = ParamTrigger( "Clear Static Variable", "Press here" );

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "C", colorYellow, styleCandle, Null, Null, 0, 0, 1 );

if( trig1 )
{
    ma1 = MA( C, per );
    StaticVarSet( "ma1" + Name(), ma1, persist = True );
}

if( trig2 )
{
    StaticVarRemove( "ma1" + Name() );
}

ma1 = Nz( StaticVarGet( "ma1" + Name() ) );
Plot( IIf( ma1, ma1, Null ), "ma1", colorAqua, styleLine | styleNoRescale, Null, Null, 0, 0, 2 );

Yes of course, therefore you should NOT be using Nz() function in first place. If you remove BOTH Nz() and IIF() functions you will get the same effect as with BOTH of them in place.
Without those calls the code will be easier, shorter and faster.

I already explained the reason of problems that he might have:
inability to save PersistVars.bin file in correct place (in AmiBroker directory). This can be for three reasons:

  1. some 3rd party (MAYBE plugin) is changing current working directory so file is saved in wrong location
    OR
  2. some 3rd party (MAYBE antivirus) is playing games and prevents PersistVars.bin from writing
  3. he did not install AmIBroker correctly and the directory is redirected to Windows Virtual Store, see this: Can't Find AFL Files - #2 by Tomasz

Antiviruses nowadays go absolutely CRAZY including deleting your stuff. This thread Bad Image (0xC000020) error - McAfee gone mad is one example, but this applies to ALL 3rd party antiviruses that currently do more harm than good.

Note: since I might have been misunderstood: I was talking about 3rd party antiviruses, Windows built-in antivirus (Windows Defender) is fine and it does not seem to interfere with data files (other than slowing down reading/writing), for maximum speed you might consider adding AmiBroker data files to "exclusions" in Windows Defender settings.

ok thanks for your reply.

yes you are correct about the ma1. But it is basically irrelevant for the question. I am so used to adding Nz when retrieving a static variable because I usually need them to be 0 if they do not exist. But in this case indeed the ma1 is already Null, so test code can be written as:

per = Param( "Period", 20, 2, 100, 1 );
trig1 = ParamTrigger( "Draw MA", "Press here" );
trig2 = ParamTrigger( "Clear Static Variable", "Press here" );

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "C", colorYellow, styleCandle, Null, Null, 0, 0, 1 );

if( trig1 )
{
    ma1 = MA( C, per );
    StaticVarSet( "ma1" + Name(), ma1, persist = True );
}

if( trig2 )
{
    StaticVarRemove( "ma1" + Name() );
}

//ma1 = Nz( StaticVarGet( "ma1" + Name() ) );
//Plot( IIf( ma1, ma1, Null ), "ma1", colorAqua, styleLine | styleNoRescale, Null, Null, 0, 0, 2 );

ma1 = StaticVarGet( "ma1" + Name() );
Plot( ma1, "ma1", colorAqua, styleLine | styleNoRescale, Null, Null, 0, 0, 2 );

After some discussion with @Ozzietrader it become apparent the persistent data are saved properly but only after 4-5 seconds when Norgate plugin was in use.

Apparently Norgate plugin is slow to deinitialize / shutdown and that causes this delay.

Persistent variables are saved at very late stage, AFTER all plugins return from the Release() and AFTER all plugins are unloaded (FreeLibrary).

Apparently Norgate Plugin spends about 4-5 seconds in either Release() or DllMain DLL_PROCESS_DETACH

If new instance of AmiBroker was run BEFORE previous instance exited (due to time spent in Norgate plugin cleanup), then new instance was loading PREVIOUS CONTENT of persistent variable file, because new content wasn't yet written by instance that was not yet exited.

If you use Norgate plugin you need to wait 5 seconds before running a new instance of the program because previous instance did not exit.

9 Likes

Thanks very much everyone for your help. Much appreciated. Oz

1 Like