Multiple sell tied to multiple buy

buycondition1 = buycondition1
buycondition2 = buycondition2
buycondition3 = buycondition3
sellcondition1 = sellcondition1
sellcondition2 = sellcondition2
sellcondition3 = sellcondition3

buy = buycondition1 or buycondition2 or buycondition3
sell = ???

How can i link sellconditions to the corresponding buyconditions?
For example, i would like to sell (when sellcondition3 is true) only when i have previously bought based on buycondition3.
Thank you

Note: multiple signals may occur at same bar.

Solution:
Apply power of two and looping.
Sell is dependent on information of Buy.
So it is similar to P/L stop code.

As you can see in below sample picture... it works.

15

Sorry fxshrat, didn't understand your solution.
I try to better describe my problem.

buy = buycond1 or buycond2 or buycond3
sell = sellcond1 or sellcond2 or sellcond3

Suppose that buycond1 = 0 , buycond2=0, buycond3 = 1
I want that trade triggered by buycond3 it should be sold only when sellcond3 is fulfilled.
But i'm afraid that if sellcond1 is triggered before sellcond3, the former is applied and the latter could be applied to a trade that eventually should arise in the meantime.

Just as an example, in easlylanguage the problem is solved applying a label to entry trades:
if buycond1 then buy ("label1") this bar on Close;
if buycond2 then buy ("label2") this bar on Close;
...
if sellcond1 Sell from entry ("label1") this bar on Close;
if sellcond2 Sell from entry ("label2") this bar on Close;
...

My question basically concerned how to reproduce a logic of this type in amibroker
Possible to apply a label or the like?
Other ways around the problem?

You don't need to describe further. I fully understand what you meant.
And it is the way I wrote in 2nd post (look at the picture and the length of the green/red lines at signal).
You have to attach power of two to signals so that signals do not return just true/false. You have to make signals return value unique. And to store value at entry and reset at exit you would have to write looping code.
And if you want to consider only single signal at a bar you would still have to apply what is written above.

3 Likes

@Heisenberg this example might be helpful.

1 Like

Thanks @portfoliobuilder
Buy and sell variable can take values greater then 1?
buy = 2; sell =2; what does this mean and which is the difference from buy =1; sell = 1;
please help me to understand this point

Here is flexible code of Post #2.

procedure fxTiedLongExit(Entryname,Exitname,systemnum,delay) {
	/// @link https://forum.amibroker.com/t/multiple-sell-tied-to-multiple-buy/22244/7
	/// by fxshrat@gmail.com	
	/// Commercial use prohibited
	global Buy, Sell;
	local i, n, pow, BuySig, SellSig;
	BuySig = SellSig = 0;
	for (n = 0; n < systemnum; n++) {		
		//https://en.wikipedia.org/wiki/Power_of_two
		BuySig += (VarGet(Entryname+(n+1))*2^n);
		SellSig += (VarGet(Exitname+(n+1))*2^n);
	}	
	BuySig = Ref(BuySig,-delay);
	SellSig = Ref(SellSig,-delay);
	//
	pow = 0; 
	for ( i = 0; i < BarCount; i++ ) {			
		if (BuySig[ i ] > 0 AND pow == 0) {			
			pow = BuySig[ i ];
			Buy[ i ] = pow*10;			
		} else Buy[ i ] = 0;
		//
		if ((pow & SellSig[ i ]) AND pow > 0 ) {
			// multiplying by 10 because Sell == 2 to Sell == 6
			// are reserved to ApplyStop
			Sell[ i ] = SellSig[ i ]*10;
			pow = 0;
		} else Sell[ i ] = 0;
	}
}

SetTradeDelays(0,0,0,0);
SetPositionSize(1, spsShares);

Buy1 = Cross( C, MA( C, 20 ) );
Buy2 = Cross( 30, RSI() );
Buy3 = Cross( MACD(), Signal() );
//add further

Sell1 = Cross( MA( C, 20 ), C );
Sell2 = Cross( RSI(), 70 );
Sell3 = Cross( Signal(), MACD() );
// add further

systemnum = n = 3;// Set number of systems

delay = 0;
if ( delay > 0)	BuyPrice = SellPrice = O;
else BuyPrice = SellPrice = C;

Short = Cover = 0;
fxTiedLongExit("Buy","Sell",systemnum,delay);

Plot(C, "Price", colorDefault, styleBar);
Plot(Buy, "Buy", colorGreen, styleHistogram | styleOwnScale, mini = (-2^n-1)*10, maxi = (2^n-1)*10);
Plot(-Sell, "Sell", colorRed, styleHistogram | styleOwnScale, mini, maxi);

StaticVarSet( "BuySig_" + Name(), Buy/10 ); 
StaticVarSet( "SellSig_" + Name(), Sell/10 ); 

// Result list output
SetCustomBacktestProc("");
if ( Status( "action" ) == actionPortfolio ) {
    bo = GetBacktesterObject();
    bo.Backtest( 1 );
    
    // Iterate through closed trades
    for ( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() )  {
        BuySig = StaticVarGet( "BuySig_" +trade.Symbol ); 
        trade.AddCustomMetric( "BuySig", Lookup( BuySig, Trade.EntryDateTime ), 0 );
        SellSig = StaticVarGet( "SellSig_" +trade.Symbol ); 
        trade.AddCustomMetric( "SellSig", Lookup( SellSig, Trade.ExitDateTime ), 0 );
    }

    bo.ListTrades();
}

16

5 Likes

Before coming to forum it is mandatory advice to search/read entire knowledge base.
Majority of basic questions are covered there already.

http://www.amibroker.com/kb/2014/09/24/how-to-identify-which-signal-triggers/

Quote:

.....
.....

With regard to exit signals they can be visualized in a similar way as shown above, but there is also an additional functionality in the backtester, which allows to indicate the exit condition directly in the trade list. This can be done by assigning values higher than 1 (but not more than 127) to Sell variable.

Sell1 = Cross( Signal(), MACD() );
sell2 = Cross( MA(Close, 50), Close );
Sell = Sell1 * 10 + Sell2 * 20;

The above expression will result in assigning value of 10 to Sell variable for the bars where Sell1 is true, 20 for the bars where Sell2 is true and 30 for the bars where both conditions are true.

These values will be indicated in the trade list:

photo_2020-11-01_19-26-22

It is worth to mention that values 1 to 9 are reserved for built-in stops and used internally by the backtester, and have special meaning:

  1. normal exit
  2. maximum loss stop
  3. profit target stop
  4. trailing stop
  5. n-bar stop
  6. ruin stop (losing 99.96% of entry value)
  7. reserved
  8. reserved
  9. reserved

Note also that you must not assign value greater than 127 to Sell or Cover variable. If you assign bigger value it will be truncated.

Buy/Sell/Short/Cover are numbered arrays. Every value greater zero is considered TRUE signal while zero is considered FALSE.

3 Likes

And here is code to consider only single signal occurrence at every single bar.

procedure fxTiedLongExit2(Entryname,Exitname,systemnum,delay) {
	/// @link https://forum.amibroker.com/t/multiple-sell-tied-to-multiple-buy/22244/9
	/// by fxshrat@gmail.com
	/// Commercial use prohibited	
	global Buy, Sell;
	local i, n, pow, BuySig, SellSig;
	BuySig = SellSig = 0;
	mat = Matrix(systemnum,1);
	for (n = 0; n < systemnum; n++) {		
		//https://en.wikipedia.org/wiki/Power_of_two
		pow = mat[n][0] = 2^n;
		BuySig += (VarGet(Entryname+(n+1))*pow);
		SellSig += (VarGet(Exitname+(n+1))*pow);
	}	
	BuySig = Ref(BuySig,-delay);
	SellSig = Ref(SellSig,-delay);
	//
	pow = 0;  
	for ( i = 0; i < BarCount; i++ ) {			
		for ( n = 0; n < systemnum; n++ ) {
			if (BuySig[ i ] == mat[n][0] AND pow == 0) {			
				pow = BuySig[ i ];
				Buy[ i ] = pow*10;
				break;
			} else Buy[ i ] = 0;
		}
		if (SellSig[ i ] == pow AND pow > 0 ) {
			Sell[ i ] = SellSig[ i ]*10;
			pow = 0;
		} else Sell[ i ] = 0;
	}
}

SetTradeDelays(0,0,0,0);
SetPositionSize(1, spsShares);

Buy1 = Cross( C, MA( C, 20 ) );
Buy2 = Cross( 30, RSI() );
Buy3 = Cross( MACD(), Signal() );
//add further

Sell1 = Cross( MA( C, 20 ), C );
Sell2 = Cross( RSI(), 70 );
Sell3 = Cross( Signal(), MACD() );
//add further

systemnum = n = 3;// set number of systems

delay = 0;
if ( delay > 0)	BuyPrice = SellPrice = O;
else BuyPrice = SellPrice = C;

Short = Cover = 0;
fxTiedLongExit2("Buy","Sell",systemnum,delay);

Plot(C, "Price", colorDefault, styleBar);
Plot(Buy/10, "Buy", colorGreen, styleHistogram | styleLeftAxisScale, mini = (-2^n-1), maxi = (2^n-1));
Plot(-Sell/10, "Sell", colorRed, styleHistogram | styleLeftAxisScale, mini, maxi);

StaticVarSet( "BuySig_" + Name(), Buy/10 ); 
StaticVarSet( "SellSig_" + Name(), Sell/10 ); 

// Result list output
SetCustomBacktestProc("");
if ( Status( "action" ) == actionPortfolio ) {
    bo = GetBacktesterObject();
    bo.Backtest( 1 );
    
    // Iterate through closed trades
    for ( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() )  {
        BuySig = StaticVarGet( "BuySig_" +trade.Symbol ); 
        trade.AddCustomMetric( "BuySig", Lookup( BuySig, Trade.EntryDateTime ), 0 );
        SellSig = StaticVarGet( "SellSig_" +trade.Symbol ); 
        trade.AddCustomMetric( "SellSig", Lookup( SellSig, Trade.ExitDateTime ), 0 );
    }

    bo.ListTrades();
}

So since there are three entry/exit signals in upper code Buy and Sell signals at a bar will either be 1 (Sig1) or 2 (Sig2) or 4 (Sig3).

16

4 Likes

Wow @fxshrat this is very impressive!
Never could I have written all this alone.
However, I must note that under no circumstances are buys followed by another buy before the sales conditions are met. I give an example. Buy1 is always temporally followed by Sell1 while in reality nested sequences could and should happen: buy1 -> buy2 -> sell2 -> sell1
I hope I was clear

My study of @fxshrat codes continues.
I noticed that produced the same results of @Tomasz code:
https://forum.amibroker.com/t/different-exits/3011/3

However both has the same problem: when a buy is made, no other buy is accepted until the first buy is sold.

In the case of Tomasz's code the cause is represented by the expression:
switch (InTrade)

InTrade doesn't turn 0 until a sell is made.

Is there a way to make the buy conditions independent and then make a second o third buy before everything is sold?

Thank you

@Heisenberg your initial question clearly asked to match Sells with the appropriate Buy signals. Now you come back and in the 11th post of the discussion write

You must realize that sounds like you are discussing SCALE TRADING, ie scaling into and out of positions with multiple buys and sells on the same security. You never mentioned scale trading in the earlier posts (in fact you still have not used that terminology). Am I misinterpreting your intention to scale into your position?

So forum members spend their time and energy solving your question only to have you reveal a different question or intent. Very frustrating. Please read (carefully) this following post, in your case specifically " Give us all the background Information and explain the GOAL you want to accomplish".

And search the forum and the user guide as there is plenty of info on scale trading.

3 Likes

You've got quite some nerve I must tell you.

Same old story as in your previous thread...
Lack of information right at start and as result wasting time of people.
But of course further demand, demand... (without "Thank you for taking the time").
Copy&paste is just so easy.

And FYI the codes don't have problem. As you can see they work according to post #1 (one for multi signals at a bar and other one for single signal at a bar). It is just a matter of what is being looked for and corresponding implementation. I already wrote in post #2 what to do concerning linking exit to entry (since that was original question which did not include info about intention to hold multi positions). (As aside, forum is not supposed to be code writing service)

AFAICS, you owe me two beer... one per (working) code.

6 Likes

@portfoliobuilder, @fxshrat

I'm sorry you felt offended, it wasn't my intention.
I'm sorry for mistakes and inaccurancies, it's done in good faith.

In the specific case it is true that I omitted to say that it was a form of scalein, but this happened for two reasons:

  1. the scalein I had in mind was not based on price (as is typically the case for scalein) but on different entry rules. This fooled me and I didn't think it was essentially a form of scalein
  2. As mentioned in the previous post, in easylanguage the question is resolved in two lines, regardless of whether it is scalein or not. This also misled me.

I'm sorry you feel like you've worked for nothing. This is not the case because your interventions are always illuminating.

But let me understand one thing.

I have been an Amibroker supporter for years and hopefully I think I am also in the future. In other words, I am a loyal customer.
I learned that the forum is the place where the Amibroker company gives assistance to its customers (in the past there was email).

I don't even know if you work for Amibroker or are an indipendent customer that love stay here to help people.

In the case you are an indipendet customer i can better understand your bad feeling.
Many users helping people on stack overflow request a donation. For example this one:

You may want to consider such a solution. You may not get rich but it seems right to me to compensate you. Maybe a lot of people in this forum would be happy to give back with many small contributions.

In the case you prefer the two beers instead, there is absolutely no problem. When you have the opportunity to come to Italy you will be my guess. Our hospitality, kindness and good life are legendary :wink:

2 Likes

@Heisenberg,

Understand that it’s not about generous helpers wanting financial compensation, it’s about generous helpers not wanting their time and efforts wasted and disrespected by unclear help requests, especially when it's through lack of care. I’m sure you can understand why it’s very frustrating when that happens. So when forum members request assistance they need to do their bit at their end first – that’s all.

Continue to learn and grow with AmiBroker!

3 Likes

For the sake of clarity and hoping not to commit another behavior violation, I have developed a sample code for the sole purpose of illustrating well the nature of what I was asking.
It is financial nonsense I know, but it is for illustrative purposes only.

Starting from a simple intraday time series, we have 3 entry and 3 exit conditions, each independent of the other.

What I was asking in the forum is an example of the best way, if possible, to achieve this in amibroker.

I repeat, just to understand and learn.


Var: P1(0),NDay(0),P2(0),P3(0),P4(0),P5(0);
if D <> D[1] then NDay=NDay+1;
if Marketposition <> 0 then
begin


 if Time >=1600 and NDay > 0 then
 begin
   Sell from entry ("B1") this bar on Close;
   buy to cover from entry ("S1") this bar on Close;
 end;
 
 if Time >=1015 and NDay > 0 then
 begin
   Sell from entry ("B2") this bar on Close;
   buy to cover from entry ("S2") this bar on Close;
 end;
 
 if Time >=945 and NDay > 0 then
 begin
   Sell from entry ("B3") this bar on Close;
   buy to cover from entry ("S3") this bar on Close;
 end;
 
 
end;


//ENTRY 1 
if Time=1315 then P1=Close;
if Time=1415  then
begin
if P1 > 0 then begin
  if (C / P1 -1) *100 > 0 then buy ("B1") this bar on Close; 
  if (C / P1 -1) *100 < 0 then sell short ("S1") this bar on Close; ;
  NDay=0;
end;  
end;

//ENTRY 2
if Time=1430  then
begin
if P1 > 0 then begin
  if (C / P1 -1) *100 > 0.1 then buy ("B2") this bar on Close; 
  if (C / P1 -1) *100 < -0.1 then sell short ("S2") this bar on Close; ;
  NDay=0;
end;  
end;

//ENTRY 3 
if Time=1130 then P2=Close;
if Time=1530  then
begin
if P2 > 0 then begin
  if (C / P2 -1) *100 > 0.2 then buy ("B3") this bar on Close; 
  if (C / P2 -1) *100 < -0.2 then sell short ("S3") this bar on Close; ;
  NDay=0;
end;  
end;

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