Different position sizes for long and short

Hi,
I am trying to have different position sizes for long and short trades. In particular, I want to cut my short position sizes in half when the SP500 is above it's 200DMA. I thought this would be an easy task but my code is not producing the correct result.

setpositionsize ( IIf( Short AND SPY>MA(SPY, 200), 5, 10), spsPercentofEquity);

In my results (see attached), the SPY has not been below the 200DMA in 2021, yet as you can see, the short position sizes are not 5% ($5k)- many are 10% ($10k)

Thanks in advance for any help.

Untitled

It's working here as you can see in below picture.
You have not posted your entire reproducible code.

Maybe your SPY symbol does not exist in your database (then it would use data of applied symbol).

Use below code, set your SPY symbol and check via Explorer whether it is Y for Yes or N for No.
If yes then run backtest.
If no in 2021 then check symbol.

Report back.

m = MA( Close, 20 );
Buy = Cross( Close, m ); 
Sell = Cross( m, Close );
Short = Sell;
Cover = Buy;

SPY = Foreign("^GSPC", "C");

Setpositionsize( IIf(Short AND SPY>MA(SPY, 200), 5, 10), spsPercentofEquity);

// Check via explorer
// Y - Yes
// N - No
Filter = 1;
AddColumn(SPY, "SPY Close", 1.2);
AddColumn(MA(SPY, 200), "MA(SPY, 200)", 1.2);
AddColumn(IIf(SPY>MA(SPY, 200), 'Y','N'), "SPY above MA?", formatChar);

23


BTW have you looked at your BT report

cd2f5194e08b9bcc3b1e26660be1daf83ffc0581
It shows 5% at some occasions.
To me it looks like your SPY symbol does not exist in your DB.

@fxshrat - thank you for your help.

so I've narrowed it down to seeming to have something to do with tradedelays. when I set trade delays to 0, it works properly. when I set trade delays to 1, it stops working.

BuyPrice = SellPrice = ShortPrice = CoverPrice = C; 
TD = 0;
SetTradeDelays(TD, TD, TD, TD);

SetOption("InitialEquity", 100000);
SetOption("AccountMargin", 50); 
SetOption ("MaxOpenPositions", 20);
SetOption ("MaxOpenLong", 10);
SetOption ("MaxOpenShort", 10);
SetOption("SeparateLongShortRank", True ); 
SetOption("ActivateStopsImmediately", True);

Buy = Cross(MA(C, 50), MA(C,200)); 
Short = Cross(MA(C, 200), MA(C,50));
Sell = Cover = 0;

ApplyStop(stopTypeNBar, stopModeBars, 5); 

PositionScore = 100 + ROC(C, 252); 

SPY = Foreign("SPY", "C", True);
PS = IIf( Short AND SPY > MA(SPY, 200), 50, 100 );
SetPositionSize( PS, spsShares); 


Filter = Short; 
AddColumn(Short, "Short");
AddColumn(SPY >= MA(SPY,200), "SPY>200D");
AddColumn(PS, "PS");

Exploration output for PS is correct when tradedelays is 0 or 1.

Here is backtest results with no trade delays:
Untitled

Here are results with trade delays set to 1:
Untitled

That's why it is important to post entire code in first post in first place!
Much time going down the drain and being wasted because of that.

TD = 1;

SetTradeDelays(TD, TD, TD, TD);

array = Iif(TD>0, Open, Close);

BuyPrice = SellPrice = ShortPrice = CoverPrice = array;

SetOption("InitialEquity", 100000);
SetOption("AccountMargin", 50); 
SetOption ("MaxOpenPositions", 20);
SetOption ("MaxOpenLong", 10);
SetOption ("MaxOpenShort", 10);
SetOption("SeparateLongShortRank", True ); 
SetOption("ActivateStopsImmediately", True);

Buy = Cross(MA(C, 50), MA(C,200)); 
Short = Cross(MA(C, 200), MA(C,50));
Sell = Cover = 0;

ApplyStop(stopTypeNBar, stopModeBars, 5); 

PositionScore = 100 + ROC(C, 252); 

SPY = Ref(Foreign("SPY", "C", True), -TD);
PS = IIf( Ref(Short,-TD) AND SPY > MA(SPY, 200), 50, 100 );

SetPositionSize( PS, spsShares); 

@fxshrat - fair criticism and appreciate your help.

could you help me understand though why we are using

Short = Cross(MA(C, 200), MA(C,50));
which is the current bar for the signal

Ref(Short,-TD)
but referring to the previous bar for the position size?

isn't that a mismatch in timeframes? is there some specific about the way the backtester operates?

No, it is not timeframe mismatch!

SetRadeDelays affects reserved variables such as
Buy,Sell,Short,Cover, PositionScore in backtest.

SPY and PS are custom variables.
So you need to take care of delays for custom arrays yourself.
Also if position sizing is dependent on reserved signal variables and delays being not zero.

Unsurprisingly it is mentioned in manual already (see SetTradeDelays).

It appears to me that the documentation for SetTradeDelays is not 100% correct, as it states:

Note that NO OTHER variables are affected by trade delays

But I believe that when you use Trade Delays your PositionScore is automatically adjusted so that you will get the PositionScore from the bar on which the signal was generated, not the bar on which the trade entered. Perhaps @Tomasz can confirm.

In contrast, the PositionSize for the trade will be the value in the PositionSize array on the entry bar, not the signal generation bar, just as @fxshrat described. That means that for completeness, you should really include your SPY check in the Ref statement as well, or else you have a small future leak because you are using the closing price of SPY on Bar X to determine your position size, but entering at the open of Bar X. Therefore, the example given above should look like this:

PS = IIf(Ref(Short AND SPY > MA(SPY, 200), -TD), 50, 100 );

In English: If on the signal bar there was a short signal and SPY was above its 200-day moving average, then use a position size of 50, otherwise use a position size of 100.

Did you read post of before?


Once again did you read posts of before?

I repeat did you read?

You just repeat what has been written already.

@mradtke and @fxshrat

thank you both for your help. I did refer back to the manual on settradedelays and it is clear to me now what the problem was.

Thank you both for helping me understand amibroker better.

2 Likes

@fxshrat: yes, I did miss the fact that you were using Ref() in two different places, my apologies for that. Your code examples are usually models of efficient coding, so I didn't expect that approach.

Participating in the forum isn't meant to be a competition, and no one is questioning your enormous contributions here. In my experience, there are times when expressing things a different way or clarifying a point which may not be obvious to all readers can be helpful to others who are still climbing the learning curve.

4 Likes

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.