How to use conditions from 3 different systems in one single system?

Hi there!

I have 3 different systems (different buy and sell conditions) that operate the same Stock. Each system has got 1000€.

I would like to merge the 3 systems in a single one with an initial capital of 3000€. The system should have 3 different buying and selling conditions, one for every subsystem and assigning 1/3 of the capital every time one of the buying conditions is true and scaling out 1/3 every time one of the selling conditions is true.

So, for example:

  • Example 1: If CondiBuy1 and CondiBuy2 in the same dayàBuy 2000€. If tomorrow CondiSell1àSell 1000€
  • Example 2: CondiBuy1àBuy 1000€. Next day CondiBuy3àBuy 1000€ more (so in total a 2000€ position)àNext day CondiSell1 and CondiSell3àSell 2000€
  • Example 3: CondiBuy1àBuy 1000€. Next day CondiSell2àDo not do anything because CondiBuy2 never has been true

I hope I explained myself correctly. What I want is to operate 3 systems in the same script.

To achieve this, I guess there are many ways to do it. The easiest one would be to replicate the ticker 3 times but this is not the most elegant way. I’m looking for something better.

I have been reading several posts in the forum but I was not able to find any clue. I tried this Tomasz’s tip but was not enough as when it’s bough for condition 1, it doesn’t buy more if condition 2 or 3 are true.

Does anyone know where I could find any hint to go on?

@Vegeta it appears that you want to learn how to Scale In and Scale Out of a position. Search this forum for many examples and the User Guide here,

https://www.amibroker.com/guide/h_pyramid.html

2 Likes

Hi,

Yes, I also think the solution is related to that using scalein and scaleout but I don't know how to apply it to my scenario.

I'm trying different ways but I can't see how to make it work.

This is my code that I'm using


// VARIABLES SETTINGS
Margin 				= 0; 			// 1 = 50% margin, 0 = cash
PositionsHeld 		= 1;			// Maximum number of simultaneously open positions	
OwnCapital 			= 10000; 		// Initial capital
AllocationPercent 	= IIf(Margin==1,(1/PositionsHeld)*200,(1/PositionsHeld)*100); 


// BACKTESTER SETTINGS

SetBacktestMode(backtestRegular);
SetPositionSize(AllocationPercent, spsPercentOfEquity);
SetOption("InitialEquity",OwnCapital);
SetOption("AllowSameBarExit",False);
SetOption("AccountMargin",IIf(Margin==1,50,100));
SetOption("maxopenpositions",PositionsHeld);
SetTradeDelays(1,1,0,0);
RoundLotSize = 1;
PositionSize = -100/PositionsHeld;

// EXAMPLE SYSTEM 01 --------------------------------
Buy_01 = Cross( MACD(), Signal() );
Sell_01 = Cross( Signal(), MACD() );


// EXAMPLE SYSTEM 02 --------------------------------
Buy_02 = Cross( MA( C, 10 ), MA( C, 50 ) );
Sell_02 = RSI(2) > 70;


// EXAMPLE SYSTEM 03 --------------------------------
Buy_03 = Cross( MA( C, 100 ), MA( C, 50 ) );
Sell_03 = RSI(2) > 60;


//Buy = Buy_01 OR Buy_02 OR Buy_03;
//Sell = Sell_01 OR Sell_02 OR Sell_03;

Buy = IIf( Buy_01, 1, IIf( Buy_02, sigScaleIn, 0 ) OR IIf( Buy_03, sigScaleIn, 0 ) );
Sell = IIf( Sell_01, 1, IIf( Sell_02, sigScaleOut, 0 ) OR IIf( Sell_03, sigScaleOut, 0 ) );
           
BuyPrice=O;
SellPrice=O;


Filter = 1;

AddColumn(Buy_01,"Buy_01",1,colorDefault,IIf( Buy_01 == 1, colorGreen, colorWhite ));
AddColumn(Buy_02,"Buy_02",1,colorDefault,IIf( Buy_02 == 1, colorGreen, colorWhite ));
AddColumn(Buy_03,"Buy_03",1,colorDefault,IIf( Buy_03 == 1, colorGreen, colorWhite ));

AddColumn(Sell_01,"Sell_01",1,colorDefault,IIf( Sell_01 == 1, colorRed, colorWhite ));
AddColumn(Sell_02,"Sell_02",1,colorDefault,IIf( Sell_02 == 1, colorRed, colorWhite ));
AddColumn(Sell_03,"Sell_03",1,colorDefault,IIf( Sell_03 == 1, colorRed, colorWhite ));

AddColumn(Flip(Buy_01,Sell_01),"InSystem01");
AddColumn(Flip(Buy_02,Sell_02),"InSystem02");
AddColumn(Flip(Buy_03,Sell_03),"InSystem03");

SetSortColumns( -2 );

How do I configure that I don' care which condition to buy is met first to increase? I mean, the buy01 condition doesn't necessarily have to be met first.

But I think I'm missing something, where I define that it increases 1/3 part each time or decreases?
Where should I put a line similar to this right?
SetPositionSize (50, spsPercentOfPosition * (Buy == sigScaleOut));

Could you help me? please

Did you follow @portfoliobuilder's advice?

Did you read the document carefully?

You are doing things differently (incorrectly) to the examples provided in the document!

1 Like

@Vegeta, as suggested by @TrendSurfer, you need to study the provided documentation carefully.

In particular, review this passage (the emphasis is mine):

All you have to do to implement pyramiding is to:

  • Assign sigScaleIn to BUY/SHORT variable if you want to scale-in (increase the size of) LONG/SHORT position
  • Assign sigScaleOut to BUY/SHORT variable if you want to scale-out (decrease the size of) LONG/SHORT position

So you are supposed to not assign signals to the Sell array (as per the examples).

Moreover, check your logic about the initial position sizing.

As indicated in the documentation, "if you want to see details about scaling you have to run backtest in "DETAILED LOG" mode as only then you will see how scaling-in /out works and how average prices are calculated". It will also show you if/when some trades are not eventually executed due to insufficient funds.

More in general, I suggest you to debug your code using the divide and conquer approach.

Start with the exploration, entirely commenting out the "scaleOut" logic. Check that your "scaleIn" rules provide enough signals so you can generate a detailed log reaching the full amount invested in multiple "scaleIn" trades.

When the "scaleIn" logic seems to work, try adding the "scaleOut" rules, one at a time, and again check in your exploration that your logic does not produce too many signals that will continuously scaleOut/exit positions.

Experiment with different instruments and progressively refine your formula.

Happy learning!

1 Like

AFAICS you rather repeat what others suggested.

And FYI debug thread exits already.

1 Like

Thank you all for your help. I finally understood scale in and out. I made the system easier considering only two subsistems, I mena, only two buy conditions and two sell conditions. It is working properly, it scales in and out as expected. The only problem I found (there might be more) is when you have an opened position and it has to scale out and in in the same candle as in the example below

imatge

As you can see, on 08/02/2013 should sell and buy but in the backtest it only sells. The following day, the Sell_02 is met and it buys when it should be selling the position bought the day before.

Here you can fin the system

SetOption("AllowSameBarExit",False);					 // Disable same bar exit as the strategy exits at open of the following day

//System 1

Lenght = 5; 
IBSm = (C-LLV(L,Lenght))/(HHV(H,Lenght)-LLV(L,Lenght))*100;
Level = 7; 
Days = 7; 
Buy_01 = Cross(Level,IBSm) AND IBSm==LLV(IBSm,Days);
Sell_01 = RSI(2)>75;

//System 2

fast =5;
slow = 7;
timeseries = High;
multiplier = 10;
MAFast1_WAverage = WMA(TimeSeries,Fast);
MAFast2_WAverage = WMA(TimeSeries,Slow);
MASlow1_WAverage = WMA(TimeSeries,Fast*Multiplier);
MASlow2_WAverage = WMA(TimeSeries,Slow*Multiplier);
MarkInd01 = MASlow1_WAverage>MASlow2_WAverage AND cross(ref(MAFast2_WAverage,-1),Ref(MAFast1_WAverage,-1));

Buy_02 = MASlow1_WAverage>MASlow2_WAverage AND cross(ref(MAFast2_WAverage,-1),Ref(MAFast1_WAverage,-1));
Sell_02 = RSI(2) > 70;

Buy_01=ExRem(Buy_01,Sell_01);
Sell_01=ExRem(Sell_01,Buy_01);

Buy_02=ExRem(Buy_02,Sell_02);
Sell_02=ExRem(Sell_02,Buy_02);

Buy = Buy_01 OR Buy_02;

Sell =Sell_01 OR Sell_02;

e = Equity(1); // generate equity without pyramiding effect 

InTrade = Flip( Buy, Sell ); 

DoScaleIn = ExRem( InTrade AND Buy_01 OR Buy_02, Buy );
DoScaleOut = ExRem( InTrade AND Sell_01 OR Sell_02, Sell ); 

// modify rules to handle pyramiding
Buy = Buy + sigScaleIn * DoScaleIn + sigScaleOut * DoScaleOut;

PositionSize = IIf( DoScaleOut,-50 , -50 ); // enter and scale-in size $1000, scale-out size: $500

Filter = 1;
AddColumn(Buy_01,"Buy_01",1,IIf( Buy_01 == 1, colorWhite, colorWhite ),IIf( Buy_01 == 1, colorGreen, colorWhite ));
AddColumn(Buy_02,"Buy_02",1,IIf( Buy_02 == 1, colorWhite, colorWhite ),IIf( Buy_02 == 1, colorGreen, colorWhite ));
AddColumn(Sell_01,"Sell_01",1,IIf( Sell_01 == 1, colorWhite, colorWhite ),IIf( Sell_01 == 1, colorRed, colorWhite ));
AddColumn(Sell_02,"Sell_02",1,IIf( Sell_02 == 1, colorWhite, colorWhite ),IIf( Sell_02 == 1, colorRed, colorWhite ));

What I can see is that the Scale out is not working properly (due to my incompetence) and that might be because in the sell condition I assigned signals. Then, should I write Sell=0; as in Example 4? If I do this it stops working. It does not sell anything.

And if I doce the DoScales like in example 3, it doesn't Scale In.

DoScaleIn = ExRem( InTrade AND Buy_01 OR Buy_02, Sell);
DoScaleOut = ExRem( InTrade AND Sell_01 OR Sell_02, Sell); 

No, that is just the initialization. If you take a closer look at the example you will see Sell[ i ] = exit + 1; // mark appropriate exit code.

As per the document sigScaleIn and sigScaleOut should be assigned to Buy/Short variables. Sell and Cover variables are for full exits.

2 Likes

Hi again and thanks for the guidence. IT's helping a lot.

Now I'm trying to make it work mixing examples 3 and 4, but I'm making some mistakes...

1.- Now when buy signal 1 (22/04/16) it buys half of the position and when buy signal 2 (28/04/16) it buys the other half.
2.- When two signals in the same day it buys the whole lot
3.- When sell signals 1 and 2 in the same day (09/05/16) it sells properly.
4.- It doesn't sell properly when there's only one of the two signals bought (20/05/16). Something is wrong with my scaleout. Does anyone know what I'm doing incorrectly?

I show you in this example as

imatge

SetOption("AllowSameBarExit",False);					 // Disable same bar exit as the strategy exits at open of the following day

//System 1

Lenght = 5; 
IBSm = (C-LLV(L,Lenght))/(HHV(H,Lenght)-LLV(L,Lenght))*100;
Level = 7; 
Days = 7; 
Buy_01 = Cross(Level,IBSm) AND IBSm==LLV(IBSm,Days);
Sell_01 = RSI(2)>75;

//System 2

fast =5;
slow = 7;
timeseries = High;
multiplier = 10;
MAFast1_WAverage = WMA(TimeSeries,Fast);
MAFast2_WAverage = WMA(TimeSeries,Slow);
MASlow1_WAverage = WMA(TimeSeries,Fast*Multiplier);
MASlow2_WAverage = WMA(TimeSeries,Slow*Multiplier);
MarkInd01 = MASlow1_WAverage>MASlow2_WAverage AND cross(ref(MAFast2_WAverage,-1),Ref(MAFast1_WAverage,-1));

Buy_02 = MASlow1_WAverage>MASlow2_WAverage AND cross(ref(MAFast2_WAverage,-1),Ref(MAFast1_WAverage,-1));
Sell_02 = RSI(2) > 70;

Buy_01=ExRem(Buy_01,Sell_01);
Sell_01=ExRem(Sell_01,Buy_01);

Buy_02=ExRem(Buy_02,Sell_02);
Sell_02=ExRem(Sell_02,Buy_02);

Buy = Buy_01 or Buy_02;
Sell =0;

InTrade = Flip( Buy, Sell ); 


Pos=0;
Exit=0;


for( i = 0; i < BarCount; i++ )
{
   if( Buy[ i ] )
    {
       pos=Buy_01 + Buy_02;
    }

   if( InTrade[i] AND Buy_01[i] OR Buy_02[i] )
    {
       DoScaleIn = ExRem( InTrade AND Buy_01 OR Buy_02, sell );
       
       // modify rules to handle pyramiding
		Buy[i] = sigScaleIn ;
	}
	
	if( InTrade[i] AND Sell_01[i] OR Sell_02[i] )
	{
		DoScaleOut = ExRem( InTrade AND Sell_01 OR Sell_02, Sell ); 
		Buy[i] = sigScaleout ;
	}
	
	if( InTrade[i] AND Sell_01[i] AND Sell_02[i] )
	{
		Buy[i] = 0 ;
		Sell[i] = 1;
	}

    }
PositionSize = IIf( DoScaleOut,-50*pos , -50*pos );

Filter = 1;
AddColumn(Buy_01,"Buy_01",1,IIf( Buy_01 == 1, colorWhite, colorWhite ),IIf( Buy_01 == 1, colorGreen, colorWhite ));
AddColumn(Buy_02,"Buy_02",1,IIf( Buy_02 == 1, colorWhite, colorWhite ),IIf( Buy_02 == 1, colorGreen, colorWhite ));
AddColumn(Sell_01,"Sell_01",1,IIf( Sell_01 == 1, colorWhite, colorWhite ),IIf( Sell_01 == 1, colorRed, colorWhite ));
AddColumn(Sell_02,"Sell_02",1,IIf( Sell_02 == 1, colorWhite, colorWhite ),IIf( Sell_02 == 1, colorRed, colorWhite ));
AddColumn(pos,"Posicion");

Did you read the ERROR message you get in red color? It is clear. Requested trade size is incorrect. You have ZERO passed as scale out size.

1 Like

You're right Tomasz! I was setting the sell position size to zero. I changed it and now it buys and sells when it must.

As you know, I have to different systems and I assign 50% of equity for each signal. When there's only one of the signals bought, I don't know the exact position I held. Nowadays, it tries to sell 50% of the equity, but that could mean to sell 99 shares instead of 100 that were bought.

How can I know the position for that signal? In this system I'm operating only two subsystems but I would like to find a solution to combine 3 or more subsistems, so I could have 3 of 5 subsystems bought and have to sell one of them.

The position size is where PosSell is the counter of sell signals and PosBuy the counter of Buy signals.

PositionSize = IIf( DoScaleOut,-50*PosSell , -50*PosBuy )

Hi again! I think I got it. I paste here the code in case anyone finds it useful. Now I'll have to check if it works when I add more systems,

Regards

SetOption("AllowSameBarExit",False);					 // Disable same bar exit as the strategy exits at open of the following day

//System 1

Lenght = 5; 
IBSm = (C-LLV(L,Lenght))/(HHV(H,Lenght)-LLV(L,Lenght))*100;
Level = 7; 
Days = 7; 
Buy_01 = Cross(Level,IBSm) AND IBSm==LLV(IBSm,Days);
Sell_01 = RSI(2)>75;

//System 2

fast =5;
slow = 7;
timeseries = High;
multiplier = 10;
MAFast1_WAverage = WMA(TimeSeries,Fast);
MAFast2_WAverage = WMA(TimeSeries,Slow);
MASlow1_WAverage = WMA(TimeSeries,Fast*Multiplier);
MASlow2_WAverage = WMA(TimeSeries,Slow*Multiplier);
MarkInd01 = MASlow1_WAverage>MASlow2_WAverage AND cross(ref(MAFast2_WAverage,-1),Ref(MAFast1_WAverage,-1));

Buy_02 = MASlow1_WAverage>MASlow2_WAverage AND cross(ref(MAFast2_WAverage,-1),Ref(MAFast1_WAverage,-1));
Sell_02 = RSI(2) > 70;

Buy_01=ExRem(Buy_01,Sell_01);
Sell_01=ExRem(Sell_01,Buy_01);

Sell_02=ExRem(Sell_02,Buy_02);
Buy_02=ExRem(Buy_02,Sell_02);


Buy = Buy_01 or Buy_02;
Sell =0;


InTrade = Flip( Buy, Sell ); 
In01=Flip(Buy_01,Sell_01);
In02=Flip(Buy_02,Sell_02);
In=In01+In02;
PosBuy=DoScaleOut=0;
PosSell=0;

for( i = 0; i < BarCount; i++ )
{
   if( Buy[ i ] )
    {
       PosBuy=Buy_01 + Buy_02;
    }
    
    if( IN[i] AND Sell_01[i] OR Sell_02[i] )
	{
		PosSell=Sell_01 + Sell_02;
	}
	
	if( Buy_01[i] OR Buy_02[i] )
    {
       DoScaleIn = ExRem( InTrade AND Buy_01 OR Buy_02, sell );
       
      	Buy[i] = sigScaleIn ;
	}
}
In=In01+In02;
Total=PosBuy-PosSell;

for( i = 0; i < BarCount; i++ )
{ 
	if(In[i]==0)
	{
		Buy[i] = 0 ;
		Sell[i] = 1;
	}
	
	
	
	if(In[i]==NOT 0)
	{
		
       	if (Total[i]==2)
		
		{
			DoScaleIn = ExRem( Buy_01 OR Buy_02, sell );
			Buy[i] = sigScaleIn ;
       	}
       	
       	if (Total[i]==0)
		
		{
			Buy[i]=0;
       	}
       	
       	if (Total[i]==-1)
		
		{
			DoScaleOut = ExRem( Sell_01 OR Sell_02, Sell ); 
			Buy[i] = sigScaleout ;
       	}
       	

    
	}
	
}

PositionSize = IIf( DoScaleOut,-49*PosSell, -49*PosBuy );


Filter = 1;
AddColumn(Buy_01,"Buy_01",1,IIf( Buy_01 == 1, colorWhite, colorWhite ),IIf( Buy_01 == 1, colorGreen, colorWhite ));
AddColumn(Buy_02,"Buy_02",1,IIf( Buy_02 == 1, colorWhite, colorWhite ),IIf( Buy_02 == 1, colorGreen, colorWhite ));
AddColumn(Sell_01,"Sell_01",1,IIf( Sell_01 == 1, colorWhite, colorWhite ),IIf( Sell_01 == 1, colorRed, colorWhite ));
AddColumn(Sell_02,"Sell_02",1,IIf( Sell_02 == 1, colorWhite, colorWhite ),IIf( Sell_02 == 1, colorRed, colorWhite ));
AddColumn(PosBuy,"PosicionCompra");
AddColumn(PosSell,"PosicionVenta");
AddColumn(In01,"In01");
AddColumn(In02,"In02");
AddColumn(In,"In");
AddColumn(InTrade,"InTRade");
AddColumn(Total,"Total");

2 Likes

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