Australian (ASX) Stock Market Forum

Amibroker FAQ

Hello trash

Thank you for the reply, and code! Much kudos to you, and much obliged myself /bow

I seem to get an error with the code you posted though. When I click Backtest, an error message appears, to which I click the Try to Continue button. Then I need to click on the red square stop button. Then the error message: "The results file can not be open for writing." appears. The code works fine, in that the daily p/l is listed at the bottom of the Report. However, no additional columns are added to the Backtest Analysis (just the default values as normal). Also, the Report Explorer doesnt seem to work. If you have any ideas, I would again be most appreciative. I did some google searching and it seems like those errors are said to occur when Excel or Word is open, but I had neither of these open when running the backtest.

Yes, I'm very sorry for the large font! I posted the original message on a device with a very small screen, and it was more for my own benefit than anyone else's. I checked on my desktop and it is indeed rather large! O_O I would edit it back to normal size, but there doesnt seem to be an edit function on previous posts. Sorry about that.

Anyway, thanks again for the help. It is sincerely appreciated.

Ato

The code works fine here.

Go to AB support. Maybe you destroyed some Windows registry dependencies.
 
Go to AB support. Maybe you destroyed some Windows registry dependencies.

You may try an AB full re-installation.

However, no additional columns are added to the Backtest Analysis (just the default values as normal).

The CBT code is for report explorer. To get output to Analysis result list you need additional code.
But if you trade EOD spanning over several days then output to result list makes no sense since result list lists trades (entry date and exit date) so you would get eq daily return just for exit date but not all ones of a trade's "life time". It would make more sense if you would trade intra-day only (not holding overnight).

On the other hand in the report all daily returns are listed (also if trading EOD).
 
Hi trash

I contacted support and they suggested that the Setforeign( "~~~EQUITY" ); line was incorrect because it is old or something. They said to use bo.EquityArray. Anyway, I'm not sure if they are correct or not, but I modified the code as below (it's basically the same but with the object bo and class equityarray). It seems to work, but I'm still getting the errors. I sent support another query. I need to install 5.9, as I'm still running 5.8, so maybe I'll do that and see what happens. When you mentioned "second click on Backtest", what do you mean here? I just click it once. Maybe that is the problem?

You're right about listing to Analysis, it doesnt make sense for a non-intraday system. Good call!

Do you know how to get the values listed on the report explorer (it's HTML format, I think) into a csv format so I can dump them into Excel?

Code:
Code:
dt = DateTime();
EOD = Day() != Ref( Day(), 1 );
bir = Status( "barinrange" );

SetCustomBacktestProc("");
// Now custom-backtest procedure follows
if( Status( "action" ) == actionPortfolio ) {
    bo = GetBacktesterObject(); // Retrieve the interface to portfolio backtester
    bo.Backtest();
    
    eq = bo.EquityArray();
    ret = ( eq/Ref( eq, -1 ) -1 ) * 100;

    bo.AddCustomMetric( "Daily %P/L:" );
    for( i = 0; i < BarCount; i++ ) {
        if( EOD[i] && ret[i] != 0 && bir[i] )            
            bo.AddCustomMetric( DateTimeToStr( dt[i] ), ret[i] );
    }
}

Thanks again
 
No, Setforeign( "~~~EQUITY" ); is not incorrect. You have probably misunderstood. Yes, it is old way to call portfolio equity.

You current code can not be used for intra-day since you would need to use TimeFrame functions to get previous day close.

As for error.. I don't get an error message. I don't know what you are doing wrong in general.

As for 2nd click if using my code version ... no, it means that Equity symbol gets written in 2nd phase and in same phase you wanna calculate and send to report. So you have to click a 2nd time to calculate on updated or first time created Equity symbol.

As for Excel simply copy from report and paste into Excel. Works here. But I guess you will get error message again. lol
 
Here is a way using equityarray with TimeFrame functions.
First you hit backtest and then you hit exploration (either in same analysis window or in a secondly opened one)

Code:
// daily return output to exploration (after backtest)
// one of billions of solutions by trash
// https://www.aussiestockforums.com/forums/showthread.php?t=1679&page=120&p=874231&viewfull=1#post874231
// first hit backtest then hit explore then copy&paste result list to Excel
// Apply 'Explore' in same TF you have backtested in.

EOD = Day() != Ref( Day(), 1 );
bir = Status( "barinrange" );

SetCustomBacktestProc( "" );
if ( Status( "action" ) == actionPortfolio ) {
    bo = GetBacktesterObject();
    bo.Backtest();
    StaticVarSet( "PortfolioEquity", bo.EquityArray );    
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

// some dummy system
SetPositionSize( 25, spsPercentOfEquity );

period = 20; // number of averaging periods 
m = MA( Close, period ); // simple moving average
Buy = Cross( Close, m ); // buy when close crosses ABOVE moving average
Sell = Cross( m, Close ); // sell when closes crosses BELOW moving average
 
Short = Sell;
Cover = Buy;

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

if( Status( "action" ) == actionExplore ) {
	TimeFrameSet( inDaily );
	cl = StaticVarGet( "PortfolioEquity" );
	refcl = Ref( cl, -1 );
	ret = ( cl / refcl - 1 ) * 100;
	TimeFrameRestore();
	ret = TimeFrameExpand( ret, inDaily, expandFirst );

	Filter = EOD AND ret != 0 AND bir;
	AddColumn( ret, ""Daily %Returns"", 1.2 );
}
 
This one seems to work better and now also outputs to report. Just one time click of backtest button is required to create and to update values. Also exploration mode still included.


Code:
// daily return output to report and to exploration (after backtest)
// one of billions of solutions by trash
// https://www.aussiestockforums.com/forums/showthread.php?t=1679&page=120&p=874231&viewfull=1#post874231
// first hit backtest then hit explore then copy&paste result list to Excel

dt = DateTime();
EOD = Day() != Ref( Day(), 1 );
bir = Status( "barinrange" );

SetCustomBacktestProc( "" );
if ( Status( "action" ) == actionPortfolio ) {
	bo = GetBacktesterObject();
	bo.Backtest();    

	eq = bo.EquityArray;
	StaticVarSet( "PortfolioEquity", eq );

	TimeFrameSet( inDaily );
	cl = StaticVarGet( "PortfolioEquity" );
	refcl = Ref( cl, -1 );
	ret = ( cl / refcl - 1 ) * 100;
	TimeFrameRestore();
	ret = TimeFrameExpand( ret, inDaily, expandFirst );

	bo.AddCustomMetric( "Daily %P/L:" );
	for( i = 0; i < BarCount; i++ ) {
		if( EOD[i] && ret[i] != 0 && bir[i] )            
			bo.AddCustomMetric( DateTimeToStr( dt[i] ), ret[i] );
	}

	StaticVarSet( "PortfolioEqDaily%Return", ret );     
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

// some dummy system
SetPositionSize( 25, spsPercentOfEquity );

period = 20; // number of averaging periods 
m = MA( Close, period ); // simple moving average
Buy = Cross( Close, m ); // buy when close crosses ABOVE moving average
Sell = Cross( m, Close ); // sell when closes crosses BELOW moving average
 
Short = Sell;
Cover = Buy;

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

if( Status( "action" ) == actionExplore ) {
	ret = StaticVarGet( "PortfolioEqDaily%Return" );

	Filter = EOD AND ret != 0 AND bir;
	AddColumn( ret, "Daily %Returns", 1.2 );
}
 
Hello trash

Thanks again for your help!

The code you have provided works very nicely thanks. I could copy and paste from the report to Excel without any errors, too!!! :)

I also updated to 5.9. Unfortunately the crash/error thing still seems to occur. Marcin on support, couldnt replicate the error either, like yourself. So there must be something screwy with what I'm doing. I'll do a fresh install at some point, but even though the error is a little annoying, it doesnt actually affect the results or output. I can get everything I need!

Anyway, much kudos to you!

Kind regards
 
Tray running as administrator. It seems you have no permissions to write to location.
Wait for Tomasz. He is on holiday till mid of next week as Marcin told me.
 
Hi trash

That was it! Run as admin fixed the issue. No more crashes/errors!!!

Thanks a whole bunch. You have a good weekend!

Kind regards
 
Hi,
I am just a newbie to Amibroker. I have just bought the trial version and trying to write some afl.
I want a simple condition that if 6-ema crosses 18-ema then buy at next day's open price.
Sell on the open price on the day after buy was executed. for eg. if buy on 1st jan then sell on 2nd jan open price.
I only want to go long and not short.

I wrote the following AFL but it wasn't getting executed properly

fastma = MA(C,6);
slowma = MA(C,18);
SetTradeDelays(1,2,1,1);
BuyPrice=Open;
SellPrice=Open;
Buy=Cross(fastma,slowma);
Sell=Cross(fastma,slowma);
ExRem(Buy,Sell);


Could someone please explain me exrem function. I am not clear on how it works.

Thanks :)
 
Hi,
I am just a newbie to Amibroker. I have just bought the trial version and trying to write some afl.
I want a simple condition that if 6-ema crosses 18-ema then buy at next day's open price.
Sell on the open price on the day after buy was executed. for eg. if buy on 1st jan then sell on 2nd jan open price.
I only want to go long and not short.

I wrote the following AFL but it wasn't getting executed properly

fastma = MA(C,6);
slowma = MA(C,18);
SetTradeDelays(1,2,1,1);
BuyPrice=Open;
SellPrice=Open;
Buy=Cross(fastma,slowma);
Sell=Cross(fastma,slowma);
ExRem(Buy,Sell);


Could someone please explain me exrem function. I am not clear on how it works.

Thanks :)

Here is code for analysis.

Code:
SetOption( "HoldMinBars", 1 );
SetOption( "Allowsamebarexit", 1 );

SetPositionSize( 1, spsShares );
SetTradeDelays( 0, 0, 0, 0 ); // set to zero as we use Ref()

fastma = MA( C, 6 );
slowma = MA( C, 18 );

BuyPrice = O;
SellPrice = O;

Buy = Ref( Cross( fastma, slowma ), -1);
Sell = 1;

Short = Cover = 0;

Exrem removes excessive signals just as the function reference description explains.
https://www.amibroker.com/guide/afl/exrem.html
Also it returns value so it is used the same way as described in documentation. So I don't know why you use it differently.

It is not required in backtest because backestRegular (which is default backtest mode) takes care of excessive signals itself. (As aside there are 6 backtest modes https://www.amibroker.com/guide/afl/setbacktestmode.html )
Exrem is rather used in chart pane or exploration, scan if you want to remove signals.
 
Here is code for analysis.

Code:
SetOption( "HoldMinBars", 1 );
SetOption( "Allowsamebarexit", 1 );

SetPositionSize( 1, spsShares );
SetTradeDelays( 0, 0, 0, 0 ); // set to zero as we use Ref()

fastma = MA( C, 6 );
slowma = MA( C, 18 );

BuyPrice = O;
SellPrice = O;

Buy = Ref( Cross( fastma, slowma ), -1);
Sell = 1;

Short = Cover = 0;

Hi Trash,

Thanks for your help. :)

I did run your code in Amibroker. It still doesn't work properly.


pic1.PNG

pic2.PNG

I want to buy on the next day after the signal has been generated. (cross of 2 EMAs)
It is buying and selling on the same day, whereas I want to sell on the day after it is bought.

My scenario:
signal generated on 1st jan
I buy on open price on 2nd Jan and sell at open price on 3rd Jan.
 
It is buying and selling on the same day, whereas I want to sell on the day after it is bought.

Nonsense!

You do not need to repeat the same thing all over again. In contrast to you I can actually read.
The problem once again is that there is someone on the other side of the fence who can not read what is written.
I wrote the code is for analysis!

Fg9g6PV.png

3Je4b0S.png

URdMdOt.png

idJZPqj.png
 

Attachments

  • Fg9g6PV.png
    Fg9g6PV.png
    31.6 KB · Views: 0
  • 3Je4b0S.png
    3Je4b0S.png
    6.7 KB · Views: 0
  • URdMdOt.png
    URdMdOt.png
    31.4 KB · Views: 0
  • idJZPqj.png
    idJZPqj.png
    15.2 KB · Views: 0
Howdy,


now that ASIC has spat the dummy, does anybody have a new data source for live intraday Forex prices?
preferably one that's easy to setup with AB ?

kind regards
Jon
 
Hi,

I am a newbie to Amibroker. I am now starting to conduct a testing on my exit by using random entries. I want to use the metric "Exit Efficiency Ratio" to evaluate my exit. The ratio is calculated as below:

Firstly, define the time period between entry and exit (as the variable "t").
Then, find the highest/lowest possible price in the "2t" timeframe.(the perfect exit)
Finally, divide the actual return by the perfect return in each trade.

The score of the exit efficiency ratio should range between 1.0 for perfect and 0.0 for worst.

Can someone help me how to write the afl code for this ratio?

And is this evaluation method is also a kind of pure hindsight?

Thanks.
Phoebus
 
Hi All,

I've recently established a database for real-time MT4 feed ---- using the DDE plugin. Every so often, the bar advance ceases, but the bid and ask (in RT Quote window) is still active. When this occurs, I do notice the "Last" value is not updating (in synch with the bid...as is the typical behavior).

The only solution to get things working as desired is to select "reconnect", from the status icon. Anyone have a clue about what I may be doing incorrectly?

Also, I have witnessed the BarNumber (X-axis display) and BarIndex (plotted from staticvar) moving in reverse ---anyone ever see this happen?

Thanks,
RutheezKey
 
Hello everyone,

I just went to the ASX website and downloaded the company directory CSV file.

Then I copied and pasted them all into a text file and renamed it .tls

I know I'm probably late to the party but here's the file so you can use it in AmiQuote to get EOD data from Yahoo Historical. A few of the codes have the error message and I don't know why... maybe someone can help answer this question?

Took me about half an hour to add a slash to the end of each ticker and then find replace .AX

Hope it helps the newbies!

View attachment ASXALL-AX.tls.txt
 
Hello everyone,

I just went to the ASX website and downloaded the company directory CSV file.

Then I copied and pasted them all into a text file and renamed it .tls

I know I'm probably late to the party but here's the file so you can use it in AmiQuote to get EOD data from Yahoo Historical. A few of the codes have the error message and I don't know why... maybe someone can help answer this question?

Took me about half an hour to add a slash to the end of each ticker and then find replace .AX

Hope it helps the newbies!

View attachment 63384

Hi,

If you ever want to do that again, there's a faster way to add .AX to each code. In Excel, use the formula =B1&".AX". (B1 being the cell with the company code in it.)

Excel append.PNG

I don't use AmiQuote so I can't help with the error. But I did notice a mistake in your txt file. Scroll through it and you'll find "BPL.AX,.AX,".
 
Top