Persistent Variable

Hi

I need help with this afl, could someone please check where I went wrong please? The point of this afl is to set my entry, target and stoploss point, save it to disk and then I can set it for many other symbols without I need to open so many charts, just 1 chartID.

_SECTION_BEGIN("MyTrade");


PersistentPath = "C:\\Program Files (x86)\\AmiBroker\\PersistentVariables\\";
 
 function PersistentVarSetText( VarName, String )
         {
         global PersistentPath;
         fh = fopen( PersistentPath+VarName+Name()+".pva","w" );
         if( fh )
                 {
                 fputs( String, fh );
                 fclose( fh );
                 }
         return fh;
         }
 
 function PersistentVarGetText( VarName )
         {
         global PersistentPath;
         fh = fopen( PersistentPath+VarName+Name()+".pva","r" );
         if( fh )
                 {
                 String = fgets( fh );
                 fclose( fh );
                 }
         else string = "";
         return String;
         }

 function PersistentVarSet( VarName, Number )
         {
         global PersistentPath;
                        String = NumToStr(Number);
         fh = fopen( PersistentPath+VarName+Name()+".pva","w" );
         if( fh )
                 {
                 fputs( String, fh );
                 fclose( fh );
                 }
         return fh;
         }
 
 function PersistentVarGet( VarName )
         {
         global PersistentPath;
         fh = fopen( PersistentPath+VarName+Name()+".pva","r" );
         if( fh )
                 {
                 String = fgets( fh );
                 fclose( fh );
                 }
         else string = "";
                        Number = StrToNum(String);
         return Number;
         }

function PersistentVarRemove( VarName )
{
		global PersistentPath;
		Fn=PersistentPath + VarName + Name()+ ".pva";
		fh=fdelete( Fn ) ;
		return fh;
}


LastVisiblebar = Status("firstvisiblebarindex");
FirstVisibleBar= Status("lastvisiblebarindex");
d=FirstVisibleBar-LastVisiblebar;

ShowTC   = ParamToggle("Show Trade","No|Yes", 0);

CurrentSymbol = PersistentVarGetText("TestNumber4");

if( CurrentSymbol == "" )
{
EntryDate = DateNum() == ParamDate("Date", "12/02/2018", 0);
TotEquity = Param("Equity (x1000)", 100000, 5000,100000,1000);
PerToRisk = Param("PercentToRisk", 2, 2,10,1);
entry = Param("Entry", 13000, 50,100000,1);
target = Param("Target", 15000, 50,100000,1);
stoploss = Param("Stoploss", 12000, 50,100000,1);

PersistentVarSet( "TestNumber1", EntryDate );
PersistentVarSet( "TestNumber2", TotEquity );
PersistentVarSet( "TestNumber3", PerToRisk );
PersistentVarSet( "TestNumber4", entry );
PersistentVarSet( "TestNumber5", target );
PersistentVarSet( "TestNumber6", stoploss );

Reward=Target-Entry;
Risk=Entry-StopLoss;
RR=Reward/Risk;
p_reward=reward*100/Entry;
p_Risk=Risk*100/Entry;
TradeSize = ((((PerToRisk*TotEquity*1000)/100)/Risk)/500);
}
else
{
PVAEntryDate = PersistentVarGet("TestNumber1");
PVATotEquity = PersistentVarGet("TestNumber2");
PVAPerToRisk = PersistentVarGet("TestNumber3");
PVAEntry = PersistentVarGet("TestNumber4");
PVATarget = PersistentVarGet("TestNumber5");
PVAStopLoss = PersistentVarGet("TestNumber6");
}

if(ShowTC)
{

Plot(PVAEntryDate , "", colorRose, styleHistogram | styleOwnScale | styleNoLabel); //vertical line on entered day
Plot(PVAentry, "", colorGold, styleLine, Null, Null, 10 ); 
Plot(PVAstoploss, "", colorRed, styleLine, Null, Null, 10 ); 
Plot(PVAtarget, "", colorGreen, styleLine, Null, Null, 10 ); 

PlotText("Risk: "+Prec(abs(Risk), 2 )+" ("+Prec(abs(P_Risk), 2 )+"%)",FirstVisibleBar-int((d*12)/100),StopLoss+Risk/2,colorRed);
PlotText("Reward: "+Prec(abs(Reward), 2 )+" ("+Prec(abs(p_reward), 2 )+"%)",FirstVisibleBar-int((d*12)/100),Entry+Reward/2,colorGreen);

    Title += StrFormat("\nReward / Risk: " +WriteVal(RR,1.1)   + "\nTrade Size: " +WriteVal(TradeSize,1.0) + " lots" );
}

_SECTION_END();

Thanks.

Hello
Can you tell us what amibroker version you are runing

Currently, I am running Amibroker 5.7. I have Amibroker 6.2 on another computer.

5.70 is not supported.

6.00 and higher are. Starting from 5.80 persistency is built-in and you don't need to write such functions at all as everything is automatically handled via StaticVarSet:
http://www.amibroker.com/guide/afl/staticvarset.html

Hi

I already upgraded to 6.28. Here is the code that I changed to StaticVarSet, but it still shows the same problem, after I set the parameter of entry, target and stoploss of one symbol (example Symbol A), and then save it, after that I made changes the parameters for another symbol (example Symbol B), after that I come back to Symbol A, the parameters seems not saved the first time because now I see that Symbol A is using Symbol B parameters. Please help me where I went wrong.

_SECTION_BEGIN("My Trade");

LastVisiblebar = Status("firstvisiblebarindex");
FirstVisibleBar= Status("lastvisiblebarindex");
d=FirstVisibleBar-LastVisiblebar;

ShowTC   = ParamToggle("Show Trade","No|Yes", 0);

PVAEntryDate = StaticVarGet("TestNumber1"+Name());
PVAEntryDate = DateNum() == ParamDate("Date", "12/02/2018", 0);
StaticVarSet("TestNumber1"+Name(), PVAEntryDate);

PVATotEquity = StaticVarGet("TestNumber2"+Name());
PVATotEquity = Param("Equity (x1000)", 100000, 5000,100000,1000);
StaticVarSet("TestNumber2"+Name(), PVATotEquity);

PVAPerToRisk = StaticVarGet("TestNumber3"+Name());
PVAPerToRisk = Param("PercentToRisk", 2, 2,10,1);
StaticVarSet("TestNumber3"+Name(), PVAPerToRisk);

PVAEntry = StaticVarGet("TestNumber4"+Name());
PVAEntry = Param("Entry", 13000, 50,100000,1);
StaticVarSet("TestNumber4"+Name(), PVAEntry);

PVATarget = StaticVarGet("TestNumber5"+Name());
PVATarget = Param("Target", 15000, 50,100000,1);
StaticVarSet("TestNumber5"+Name(), PVATarget);

PVAStopLoss = StaticVarGet("TestNumber6"+Name());
PVAStopLoss = Param("Stoploss", 12000, 50,100000,1);
StaticVarSet("TestNumber6"+Name(), PVAStopLoss);

EntryDate = PVAEntryDate;
TotEquity = PVATotEquity;
PerToRisk = PVAPerToRisk;
entry = PVAEntry;
target = PVATarget;
stoploss = PVAStopLoss;

Reward=Target-Entry;
Risk=Entry-StopLoss;
RR=Reward/Risk;
p_reward=reward*100/Entry;
p_Risk=Risk*100/Entry;
TradeSize = ((((PerToRisk*TotEquity*1000)/100)/Risk)/500);

if(ShowTC)
{

Plot(PVAEntryDate , "", colorRose, styleHistogram | styleOwnScale | styleNoLabel); //vertical line on entered day
Plot(PVAentry, "", colorGold, styleLine, Null, Null, 10 ); 
Plot(PVAstoploss, "", colorRed, styleLine, Null, Null, 10 ); 
Plot(PVAtarget, "", colorGreen, styleLine, Null, Null, 10 ); 

PlotText("Risk: "+Prec(abs(Risk), 2 )+" ("+Prec(abs(P_Risk), 2 )+"%)",FirstVisibleBar-int((d*12)/100),StopLoss+Risk/2,colorRed);
PlotText("Reward: "+Prec(abs(Reward), 2 )+" ("+Prec(abs(p_reward), 2 )+"%)",FirstVisibleBar-int((d*12)/100),Entry+Reward/2,colorGreen);

    Title += StrFormat("\nReward / Risk: " +WriteVal(RR,1.1)   + "\nTrade Size: " +WriteVal(TradeSize,1.0) + " lots" );
}

_SECTION_END();

upgraded-still-same-problem

Hello did you check the 3rd parameter of StaticVarSet ?

Hi

I am sorry, but which one, Panos? I am really newbie to programming.

Your logic does not make sense.

PVAEntryDate = StaticVarGet("TestNumber1"+Name());
PVAEntryDate = DateNum() == ParamDate("Date", "12/02/2018", 0);
StaticVarSet("TestNumber1"+Name(), PVAEntryDate);

The above code is the same of

PVAEntryDate = DateNum() == ParamDate("Date", "12/02/2018", 0);
StaticVarSet("TestNumber1"+Name(), PVAEntryDate);
2 Likes

@newbietrader please review the StaticVarSet documentation here: https://www.amibroker.com/guide/afl/staticvarset.html as @Tomasz suggested. Static variables are not persistent by default, so if you want them to be persistent, you need to specify that.

Pay attention to @awilson as well. He has rightfully pointed out that your AFL is probably not doing what you want. I assume you're trying to retrieve a saved date, and then allow it to be changed with the ParamDate statement before saving it again?

1 Like

Hi,

Thank you, I already tried adding "persistent = true" to the StaticVarSet and then change the calling, like this:

PVAEntry1 = StaticVarGet("TestNumber4"+Name());
PVAEntry = Param("Entry", 13000, 50,100000,1);
StaticVarSet("TestNumber4"+Name(), PVAEntry, persistent =true);

It seems working for 2 symbols, but then the 3rd symbol is not working.

Yes, mradtke, that's what I want to do. I want to save the parameters for each Symbol so I don't need to open so many charts, just within 1 chartID.

That is not correct AFL syntax. Try this:

StaticVarSet("TestNumber4"+Name(), PVAEntry, true);

To perform the date retrieve/modify/save, something similar to this UNTESTED code should work:

PVAEntryDate = ParamDate("Date", StaticVarGet("PVAEntryDate"+Name()), 1);
StaticVarSet("PVAEntryDate"+Name(), PVAEntryDate, True);

Note that this will cause PVAEntryDate to be a string, not a DateNum or DateTime value. If you need a different format, you will need to convert PVAEntryDate accordingly.

Why? One can assign values to variables within function arguments. I am not seeing any issue doing it as he did.

StaticVarSet("TestNumber4"+Name(), PVAEntry, persistent =true);

I am confused why you changed to date string there. Is he looking for string? And if you change to string then wouldn't StaticVarSetText be a more appropriate function?

@newbietrader, as @awilson has pointed out one of your main problems is different assignments to same variable names at several occasions. You should fix that first. Then post code update.

@codejunkie you are correct that you can assign variables within function calls. However, my sense was that @newbietrader was trying to use something akin to VBA syntax where you specify the name of the parameter and its value, without regard to ordering. And having worked with many traders new to AFL, my experience is that most of them find it confusing to assign variables inside the function arguments like this, even when it's done correctly.

Regarding your second point, the ParamDate() documentation says that the default date argument needs to be a string. I don't typically use this function, so I'm assuming the documentation is correct. The net result is that if we want to use the output from ParamDate() as the default value argument next time we call it, we should keep everything in string format, or else commit to appropriate conversions. My point here was to illustrate the basic mechanism for retrieving and modifying the date.

You are of course correct about using StaticVarSetText() instead of StaticVarSet(). @newbietrader, please take note of that.

Hi

I still don't know where I am wrong here. Please guide me.

_SECTION_BEGIN("My Trade");

LastVisiblebar = Status("firstvisiblebarindex");
FirstVisibleBar= Status("lastvisiblebarindex");
d=FirstVisibleBar-LastVisiblebar;

ShowTC   = ParamToggle("Show Trade","No|Yes", 0);

PVASymbol = Name() + "_";
PVAEntryDate = PVASymbol + "EntryDate";
PVATotEquity = PVASymbol + "TotEquity";
PVAPerToRisk = PVASymbol + "PerToRisk";
PVAEntry = PVASymbol + "Entry";
PVATarget = PVASymbol + "Target";
PVAStopLoss = PVASymbol + "StopLoss";

EntryDate = DateNum() == ParamDate("Date", "12/02/2018", 0);
TotEquity = Param("Equity (x1000)", 100000, 5000,100000,1000);
PerToRisk = Param("PercentToRisk", 2, 2,10,1);
Entry = Param("Entry", 13000, 50,100000,1);
Target = Param("Target", 15000, 50,100000,1);
StopLoss = Param("Stoploss", 12000, 50,100000,1);

StaticVarSet(PVAEntryDate, EntryDate, persistent = true);
StaticVarSet(PVATotEquity, TotEquity, persistent = true);
StaticVarSet(PVAPerToRisk, PerToRisk, persistent = true);
StaticVarSet(PVAEntry, Entry, persistent = true);
StaticVarSet(PVATarget, Target, persistent = true);
StaticVarSet(PVAStopLoss, StopLoss, persistent = true);

PVAEntryDate1 = StaticVarGet(PVAEntryDate);
PVATotEquity1 = StaticVarGet(PVATotEquity);
PVAPerToRisk1 = StaticVarGet(PVAPerToRisk);
PVAEntry1 = StaticVarGet(PVAEntry);
PVATarget1 = StaticVarGet(PVATarget);
PVAStopLoss1 = StaticVarGet(PVAStopLoss);

EntryDate = PVAEntryDate1;
TotEquity = PVATotEquity1;
PerToRisk = PVAPerToRisk1;
entry = PVAEntry1;
target = PVATarget1;
stoploss = PVAStopLoss1;

Reward=Target-Entry;
Risk=Entry-StopLoss;
RR=Reward/Risk;
p_reward=reward*100/Entry;
p_Risk=Risk*100/Entry;
TradeSize = ((((PerToRisk*TotEquity*1000)/100)/Risk)/500);

if(ShowTC)
{

Plot(PVAEntryDate1 , "", colorRose, styleHistogram | styleOwnScale | styleNoLabel); //vertical line on entered day
Plot(PVAentry1, "", colorGold, styleLine, Null, Null, 10 ); 
Plot(PVAstoploss1, "", colorRed, styleLine, Null, Null, 10 ); 
Plot(PVAtarget1, "", colorGreen, styleLine, Null, Null, 10 ); 

PlotText("Risk: "+Prec(abs(Risk), 2 )+" ("+Prec(abs(P_Risk), 2 )+"%)",FirstVisibleBar-int((d*12)/100),StopLoss+Risk/2,colorRed);
PlotText("Reward: "+Prec(abs(Reward), 2 )+" ("+Prec(abs(p_reward), 2 )+"%)",FirstVisibleBar-int((d*12)/100),Entry+Reward/2,colorGreen);

    Title += StrFormat("\nReward / Risk: " +WriteVal(RR,1.1)   + "\nTrade Size: " +WriteVal(TradeSize,1.0) + " lots" );
}

_SECTION_END();

Hello @newbietrader
I think you have to rewrite the code form the begin with your logic step by step also write few comments to help you reading later on.

I just read the last code and I can see that, the two lines continues writing staticvar
For me, with the way you wrote that is wrong.

// this is wrong way to use StaticVarSet.
EntryDate = DateNum() == ParamDate("Date", "12/02/2018", 0);
Entry = Param("Entry", 13000, 50,100000,1);
StaticVarSet(PVAEntryDate, EntryDate, persistent = true);
StaticVarSet(PVAEntry, Entry, persistent = true);

Why?

To SET a staticvarSet has to be only ONCE, per event.
For that reason you must say IF that happen execute this part of the code once and NOT constantly.
To achieve this try to unterstand the documentation of ParamTrigger(), and how to use IF()

https://www.amibroker.com/guide/afl/paramtrigger.html

http://www.amibroker.com/kb/2015/10/06/how-to-run-certain-piece-of-code-only-once/

Note: There are many technics to execute part of the code. i said ParamTrigger() because you a new on coding and I believe you will understand better

2 Likes

Hi

So, is it not possible to use Parameter option for making changes and save the changes to the disk? The way I understand is that if I use ParamTrigger, I can not set the parameters for each symbol through the Parameters option.

yes you can.
let me Quick do few corections on you last code, and then you have to study

Parameters can be tricky.... see this other thread for a potential issue:

Hello @newbietrader
I hope this one will cover your needs

but remeber..... YOU did most of the job Bravo

// How to use this afl
// First open the Symbol in the chart then use Parameters and Last press Save My Events 
// Version 2 By Panos
// http://forum.amibroker.com/t/persistent-variable/4654

Plot( C, "Price", colorDefault, styleCandle );

_SECTION_BEGIN("My Trade Version 2"); 
if ( Version() < 5.80 ) Title = " YOU NEED TO UPGRADE TO LATEST VERSION ";

LastVisiblebar = Status("firstvisiblebarindex");
FirstVisibleBar= Status("lastvisiblebarindex");
d=FirstVisibleBar-LastVisiblebar;

// Use this Text to store in the StaticVar
PVASymbol = Name() + "_";
PVAEntryDate = PVASymbol + "EntryDate";
PVATotEquity = PVASymbol + "TotEquity";
PVAPerToRisk = PVASymbol + "PerToRisk";
PVAEntry = PVASymbol + "Entry";
PVATarget = PVASymbol + "Target";
PVAStopLoss = PVASymbol + "StopLoss";

// Parameters to input values
ShowTC   = ParamToggle("Show Trade","No|Yes", 0); 
EntryDate = DateNum() == ParamDate("Date", "12/02/2018", 0);
TotEquity = Param("Equity (x1000)", 100000, 5000,100000,1000);
PerToRisk = Param("PercentToRisk", 2, 2,10,0.2);
Entry = Param("Entry", 13000, 0.1,100000,1);
Target = Param("Target", 15000, 0.01,100000,0.1);
StopLoss = Param("Stoploss", 12000, 0.01,100000,01);
trigger = ParamTrigger( "Save My Events", "Click here Once" );

// Write Events to harddrive
if( trigger )
{
    StaticVarSet( PVAEntryDate, EntryDate,  true );
    StaticVarSet( PVATotEquity, TotEquity,  true );
    StaticVarSet( PVAPerToRisk, PerToRisk,  true );
    StaticVarSet( PVAEntry, Entry,  true );
    StaticVarSet( PVATarget, Target,  true );
    StaticVarSet( PVAStopLoss, StopLoss,  true );
}

// read the StaticVar
EntryDate = Nz(StaticVarGet(PVAEntryDate),0);  // NZ = Converts Null/Nan/Infinity values to zero (or user defined value)
TotEquity = StaticVarGet(PVATotEquity);
PerToRisk = StaticVarGet(PVAPerToRisk);
Entry = StaticVarGet(PVAEntry);
Target = StaticVarGet(PVATarget);
StopLoss = StaticVarGet(PVAStopLoss);

// calculation
Reward=Target-Entry;
Risk=Entry-StopLoss;
RR=Reward/Risk;
p_reward=reward*100/Entry;
p_Risk=Risk*100/Entry;
TradeSize = ((((PerToRisk*TotEquity*1000)/100)/Risk)/500);


if( ShowTC )
{
    Plot( EntryDate , "", colorRose, styleHistogram | styleOwnScale | styleNoLabel ); //vertical line on entered day
    Plot( entry, "", colorGold, styleLine, Null, Null, 10 );
    Plot( stoploss, "", colorRed, styleLine, Null, Null, 10 );
    Plot( target, "", colorGreen, styleLine, Null, Null, 10 );

    PlotText( "Risk: " + Prec( abs( Risk ), 2 ) + " (" + Prec( abs( P_Risk ), 2 ) + "%)", FirstVisibleBar - int( ( d * 12 ) / 100 ), StopLoss + Risk / 2, colorRed );
    PlotText( "Reward: " + Prec( abs( Reward ), 2 ) + " (" + Prec( abs( p_reward ), 2 ) + "%)", FirstVisibleBar - int( ( d * 12 ) / 100 ), Entry + Reward / 2, colorGreen );

    Title = StrFormat( "\nReward / Risk: " + WriteVal( RR, 1.1 )   + "\nTrade Size: " + WriteVal( TradeSize, 1.0 ) + " lots" );
}

_SECTION_END();
7 Likes