Hi,
I would like to run multiple buy and multiple sell rules on 1 symbol. Multiple open positions per symbol allowed.
- Every buy 1 gets a corresponding sell 1 which results in trade 1.
- Every buy 2 gets a corresponding sell 2 which results in trade 2.
- ... and so on.
The trades can overlap:
Example:
Is there a way to match Entry Signal1 to Exit Signal 1, Entry Signal 2 to Exit Signal 2, etc., when running custom backtest.
My database consists out of daily futures, max 100 symbols, mostly 50 symbols, so I think it won't be a memory problem.
I read about the ScaleIn option, but that way the information "which rule created what trade" gets lost and I would like to create individual reports for each rule, or combinations thereof, or all rules together.
I need the Equity array to do some position sizing based on current equity, so I can't really run the separate backtests conveniently.
The last thing I can think of is to make duplicates of every symbol (I.e. 4 rules, 4 duplicate symbols) and run a normal backtest which brakes up each rule to the corresponding symbol list, seems rather unconventional to me.
Here is the code that doesn't work, it runs, but doesn't achieve my goal - I cannot match entry signal to corresponding exit signal.
SetOption("UseCustomBacktestProc",1);
SetBacktestMode(backtestRegularRaw2Multi);
SetPositionSize(1,spsShares);
buy1 = BarIndex() == 100;
StaticVarSet(Name()+"buy1",IIf(buy1,1,0));//
buy2 = BarIndex() == 100;
StaticVarSet(Name()+"buy2",IIf(buy2,1,0));//
buy3 = BarIndex() == 100;
StaticVarSet(Name()+"buy3",IIf(buy3,1,0));//
sell1 = BarIndex() == 106;
StaticVarSet(Name()+"sell1",IIf(sell1,1,0));//
sell2 = BarIndex() == 105;
StaticVarSet(Name()+"sell2",IIf(sell2,1,0));//
sell3 = BarIndex() == 108;
StaticVarSet(Name()+"sell3",IIf(sell3,1,0));//
PlotShapes(shapedigit1*sell1,colorred,0,L-3*ATR(10));
PlotShapes(shapedigit2*sell2,colorred,0,L-4*ATR(10));
PlotShapes(shapeDigit3*sell3,colorred,0,L-5*ATR(10));
PlotShapes(shapedigit1*buy1,colorGreen,0,H+3*ATR(10));
PlotShapes(shapedigit2*buy2,colorGreen,0,H+4*ATR(10));
PlotShapes(shapeDigit3*buy3,colorGreen,0,H+5*ATR(10));
Buy=buy1 OR buy2 OR buy3;
Sell=sell1 OR sell2 or sell3;
SetCustomBacktestProc("");
if (Status("action") == actionPortfolio)
{
_TRACE("!CLEAR!");
bo = GetBacktesterObject(); // Get backtester object
bo.PreProcess(); // Do pre-processing
for (i = 0; i < BarCount; i++) // Loop through all bars
{
for (sig = bo.GetFirstSignal(i); sig; sig = bo.GetNextSignal(i))
{ // Loop through all signals at this bar
buy1 = staticvarget(sig.symbol + "buy1");//
buy2 = staticvarget(sig.symbol + "buy2");//
buy3 = staticvarget(sig.symbol + "buy3");//
sell1= staticvarget(sig.symbol + "sell1");//
sell2= staticvarget(sig.symbol + "sell2");//
sell3= staticvarget(sig.symbol + "sell3");//
if( sig.IsExit() && sell1[i] )//
{
bo.ExitTrade(i,sig.Symbol,sig.Price);
b1=bo.GetSignalQty(i,2);
_TRACE("Sig.Price1 =" + sig.Price);
_TRACE("EXIT-bar1 = " + i);
_TRACE("EXIT-sell1 = " + sell1[i]);
_TRACE("EXIT-sigQTYsell1 = " +b1);
_TRACE("EXIT-isExit1 = " + sig.IsExit());
_TRACE(" ");
}
if( sig.IsExit() && sell2[i] )//
{
bo.ExitTrade(i,sig.Symbol,sig.Price);
b2=bo.GetSignalQty(i,2);
_TRACE("Sig.Price2 =" + sig.Price);
_TRACE("EXIT-bar2 = " + i);
_TRACE("EXIT-sell2 = " + sell2[i]);
_TRACE("EXIT-sigQTYsell2 = " +b2);
_TRACE("EXIT-isExit2 = " + sig.IsExit());
_TRACE(" ");
}
if( sig.IsExit() && sell3[i] )//
{
bo.ExitTrade(i,sig.Symbol,sig.Price);
b3=bo.GetSignalQty(i,2);
_TRACE("Sig.Price3 =" + sig.Price);
_TRACE("EXIT-bar3 = " + i);
_TRACE("EXIT-sell3 = " + sell3[i]);
_TRACE("EXIT-sigQTYsell3 = " +b3);
_TRACE("EXIT-isExit3 = " + sig.IsExit());
_TRACE(" ");
}
if (buy1[i] == 1 && sig.IsEntry() && sig.IsLong())//
{
a1=bo.GetSignalQty(i,1);
sig.PosSize = -2002;
bo.EnterTrade(i, sig.Symbol, True, sig.Price, sig.PosSize);
_TRACE("ENTRY-bar1 = " + i);
_TRACE("ENTRY-buy1 = " +buy1[i]);
_TRACE("ENTRY-sigQTY1 = " +a1);
_TRACE("ENTRY-possize1 = " + sig.PosSize);
_TRACE("ENTRY-isExit1 = " + sig.IsExit());
_TRACE("ENTRY-isEntry1 = " + sig.IsEntry());
_TRACE("ENTRY-isLong1 = " + sig.IsLong());
//_TRACE("roundlotSize1= "+ sig.RoundLotSize);
//_TRACE("PointValue1= "+ sig.PointValue);
_TRACE(" ");
}
if (buy2[i] && sig.IsEntry() && sig.IsLong())
{
sig.PosSize = -2004;
bo.EnterTrade(i, sig.Symbol, True, sig.Price, sig.PosSize);
a2=bo.GetSignalQty(i,1);
_TRACE("ENTRY-bar2 = " + i);
_TRACE("ENTRY-buy2 = " +buy2[i]);
_TRACE("ENTRY-sigQTY2 = " +a2[i]);
_TRACE("ENTRY-possize2 = " + sig.PosSize);
_TRACE("ENTRY-isExit2 = " + sig.IsExit());
_TRACE("ENTRY-isEntry2 = " + sig.IsEntry());
_TRACE("ENTRY-isLong2 = " + sig.IsLong());
_TRACE(" ");
}
if (buy3[i] && sig.IsEntry() && sig.IsLong())
{
sig.PosSize = -2016;
bo.EnterTrade(i, sig.Symbol, True, sig.Price, sig.PosSize);
a3=bo.GetSignalQty(i,1);
_TRACE("ENTRY-bar3 = " + i);
_TRACE("ENTRY-buy3 = " +buy3[i]);
_TRACE("ENTRY-sigQTY3 = " +a3[i]);
_TRACE("ENTRY-possize3 = " + sig.PosSize);
_TRACE("ENTRY-isExit3 = " + sig.IsExit());
_TRACE("ENTRY-isEntry3 = " + sig.IsEntry());
_TRACE("ENTRY-isLong3 = " + sig.IsLong());
_TRACE(" ");
}
}
// End of for loop over signals at this bar
//bo.HandleStops(i); // Handle programmed stops at this bar
bo.UpdateStats(i, 1); // Update MAE/MFE stats for bar
bo.UpdateStats(i, 2); // Update stats at bar's end
} // End of for loop over bars
bo.PostProcess(); // Do post-processing
}
The entry works (I think):
but there are several exit signals which I don't know where they come from:
Exit 2 (red tick is ok)
Exit 1 (yellow, creates 2 exit signals, I don't know why - any ideas?)
Exit 3 (green, creates 2 exit signals, - no idea why)