Rotational trading

I have a license of Amibroker and I am using v 6.20.1.

I have a question about Rotational trading

How can I instruct the program to actually go long the top 2 stocks and go short the 2 bottom stocks even if the score is positive? My code, which does not do that now.

np=2;
MaxPositions = 2*np;
SetOption("WorstRankHeld", -1000);
SetOption("MaxOpenPositions",maxpositions);
SetOption("MaxOpenLong", np);
SetOption("MaxOpenShort", np);
SetOption("SeparateLongShortRank", True);
SetPositionSize( 100 / MaxPositions, spsPercentOfEquity ); 
SetOption("allowsamebarexit", true);
SetTradeDelays( 0,  0,  0, 0 );
SetBacktestMode( backtestRotational );
Score =ROC(C,15); 
PositionScore = Score;
BuyPrice=ShortPrice=close;
Sellprice=CoverPrice=close;

Moderator comment: added required code tags

With this code short position will only be initiated if the score is negative but I want to go long the two with best score and short two with lower score even if it is positive.

Thanks in advance for help

@makhar88 There are probably different ways you can solve this.

If you recall, by default ranking is performed using ABSOLUTE value of PositionScore.

If your position score is NOT symmetrical, this may mean that you are not getting desired top-ranked signals from one side. Therefore, to fully utilize long/short systems in rotational balanced ("market neutral") it is desired to perform SEPARATE ranking for long signals and short signals.

And don't forget to enable separate long/short ranking use:
SetOption("SeparateLongShortRank", True ); (which I see you have done already).

3 Likes

Thanks. Separate ranking does not resolve this. As you can see I have already done that.

see this thread:
https://forum.amibroker.com/t/rotational-system-going-long-and-short-at-the-same-time/5076

You need to make sure that PositionScore is NEGATIVE for all symbols that you want to SHORT.

If you want even positive score to be considered for shorts, you have to SUBTRACT some value to make them negative. An easy solution for your problem is :

a) calculate average ROC on bar by bar by dividing sum of ROC() from each symbol by number of symbols
b) subtract average computed in step a)

The following is pseudo code (not "copy paste code" but code that shows you the idea) to do that:


if( Status( "stocknum" ) == 0 )
{
    sumroc = 0;

    SymList = CategoryGetSymbols( categoryWatchList, ...the watch list you use ... );

    for( i = 0; ( symbol = StrExtract( SymList, i ) ) != ""; i++ )
    {
        change = ROC( Foreign( "symbol", "C" ), 15 );
        sumroc += change;
    }

    StaticVarSet( "avgroc", sumroc / i );
}

...// your code

PositionScore = ROC( C, 15 ) - StaticVarGet( "avgroc" );
6 Likes

Tomasz, thanks, I start getting the idea . Is it maybe better to subtract the median since a large score for a top stock will skew the score towards the top?

Also, how can I do that if my score values are from custom indicator imported in AUX1?

I understand that with Amibroker you can do almost anything you want but often guidance is necessary with the code.

BTW, you are the best!

I didn't want to start a new thread so I thought I would join this one.

I am trying to program a rotational backtest but for some reason I get the odd short trade even if I make the score value huge.

anyone got any pointers?

combinedmom = tickermom + sectormom;
score = 100000 ;
score = IIf(sectorrank <=5 AND tickerrank <=20 AND sectormom >0 AND tickermom >0 AND indexfilter,score,0);
//score = IIf(sectormom >0,score,0);
//Score = IIf(tickermom >0, score, 0);
score = score + combinedmom;
score = IIf(NorgateIndexConstituentTimeSeries("$SPX") AND liquid ,score,0);
PositionScore = IIf(Month() != Ref(Month(),-1),score,scoreNoRotate); 

as you can see I make sure that all values within the score are positive before the final position score

any help gratefully received!

Don't trust your "expectations". Test what the code is really doing instead. Use exploration as explained: How do I debug my formula?

Display score in Exploration if it is really always positive:

Filter = PositionScore <= 0; // display 0 and negative scores
AddColumn( PositionScore, "PS");
1 Like

Thank you

I had tried that but had too many items on my filter so I was filtering out the negative values!

just had to re-order the scoring sequence to achieve the intended purpose

Amibroker has amazing service

Hi Tomasz,

Your code above has been very helpful. Is it possible to modify it to also calculate the median ROC in addition to the average, avgroc?

Thanks in advance.