I have custom backtesting codethat sets the buy price but i notice that the
I notice that the fill price for buy is high of the day or the fill price sell is low price of day.
I assumed that my buyprice code will override the fill price as per the backtester. can someone validate this for me.
for eg. in the code below in lines 118-122, i set the buy price. But it gets overridden
SetChartOptions( 0, chartShowArrows | chartShowDates );
_N( Title = StrFormat( "{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) Vol " + WriteVal( V, 1.0 ) + " {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ) );
//https://www.raoufx.com/trading%20with%20ichimoku%20clouds%20the%20essential%20guide%20to%20ichimoku%20kinko%20hyo%20technical%20analysis.pdf
Plot( C, "Close", colorDefault, styleNoTitle | GetPriceStyle() );
_SECTION_BEGIN( "Tenkan-Sen" );
TenkanPer = Param( "Tenkan-Sen Period", 9, 1, 100, 1 );
TenkanCol = ParamColor( "Tenkan-Sen Color", colorRed );
TenkanSty = ParamStyle( "Tenkan-Sen Style", styleLine | styleThick );
Tenkan = ( HHV( H, TenkanPer ) + LLV( L, TenkanPer ) ) / 2;
Plot( Tenkan, "Tenkan", TenkanCol, TenkanSty );
_SECTION_END();
_SECTION_BEGIN( "Kijun-Sen" );
KijunPer = Param( "Kijun-Sen Period", 22, 1, 100, 1 ); // using 22 instead of 26 as there are only 22 trading days in a month.
KijunCol = ParamColor( "Kijun-Sen Color", colorBlue );
KijunSty = ParamStyle( "Kijun-Sen Style", styleLine | styleThick );
Kijun = ( HHV( H, KijunPer ) + LLV( L, KijunPer ) ) / 2;
Plot( Kijun, "Kijun", KijunCol, KijunSty );
_SECTION_END();
_SECTION_BEGIN( "Chikou Span" );
ChikouShft = Param( "Chikou Span Shift", 22, 1, 100, 1 ); // using 22 instead of 26 as there are only 22 trading days in a month.
ChikouCol = ParamColor( "Chikou Span Color", colorViolet );
ChikouSty = ParamStyle( "Chikou Span Style", styleLine | styleNoLabel );
Chikou = C;
Plot( Chikou, "", ChikouCol, ChikouSty, Null, Null, -ChikouShft );
_SECTION_END();
_SECTION_BEGIN( "Senkou-Kumo" );
SenkouKumoShft = Param( "Senkou-Kumo Shift", 21, 0, 100, 1 );
_SECTION_END();
_SECTION_BEGIN( "Senkou Span A" );
SenkouACol = ParamColor( "Senkou Span A Color", colorSeaGreen );
SenkouASty = ParamStyle( "Senkou Span A Style", styleLine );
SenkouA = ( Tenkan + Kijun ) / 2;
Plot( SenkouA, "Senkou A", SenkouACol, SenkouASty, Null, Null, SenkouKumoShft ) ;
_SECTION_END();
_SECTION_BEGIN( "Senkou Span B" );
SenkouBPer = Param( "Senkou Span B Period", 42, 1, 200, 1 );
SenkouBCol = ParamColor( "Senkou Span B Color", colorPink );
SenkouBSty = ParamStyle( "Senkou Span B Style", styleLine );
SenkouB = ( HHV( H, SenkouBPer ) + LLV( L, SenkouBPer ) ) / 2;
Plot( SenkouB, "Senkou B", SenkouBCol, SenkouBSty, Null, Null, SenkouKumoShft ) ;
_SECTION_END();
_SECTION_BEGIN( "Kumo" );
KumoUpCol = ParamColor( "Kumo UP Color", colorSeaGreen );
KumoDnCol = ParamColor( "Kumo DN Color", colorPink );
PlotOHLC( SenkouA, SenkouA, SenkouB, SenkouB, "", IIf( SenkouA > SenkouB, KumoUpCol, KumoDnCol ), styleCloud | styleNoLabel, Null, Null, SenkouKumoShft );
_SECTION_END();
// need to fiture out how many HH7 i got since the Tenkan < Kijun and how many since Tenkan > Kijun
// i need to take the first HH7 signal.
RANGE = H - L;
hh7 = RANGE == HHV( RANGE, 7 );
dailyRange=ATR(14);
longHH7 = C > O AND hh7 ;
shortHH7 = C < O AND hh7;
crossedLong = Cross( Tenkan, Kijun );
crossedShort = Cross( Kijun, Tenkan );
crossedShort_barssince=BarsSince(crossedShort );
PlotShapes( crossedShort*shapeSmallCircle, colorYellow, layer = 0, L + range / 2 );
PlotShapes( crossedLong*shapeSmallDownTriangle, colorYellow, layer = 0, L + range / 2 );
PlotShapes( hh7*shapeDigit7, colorYellow, layer = 0, L + range / 2 );
String1 =Name();
String2 = "-IDEALPRO-CASH";
forex= StrMatch( String1, "*" + String2 );
GappedUp=GapUp();
GappedDown=GapDown();
volumeCheck= forex OR ( V > MA( V, 50 ) * 1.4 AND MA( V, 50 ) > 250000 );
pricecheck =forex OR MA( C, 15 ) > 1 ;//AND MA( C, 15 )<40;
//volumeCheck = pricecheck=True;
LongSignal = volumeCheck AND pricecheck AND hh7 AND C>O AND Tenkan > Kijun AND BarsSince( Cross( Tenkan, Kijun ) ) < 3;
// do all declarations
i = 0;
breakoutprice = Null;
stopprice = Null;
entryBar = -1;
inLongPosition = False;
countHH7 = 0;
countLongHH7SinceCrossedShort = SumSince( crossedShort AND BarsSince(crossedShort)<BarsSince(crossedLong) , longHH7 ) ;
countLongHH7SinceCrossedLong = SumSince( crossedLong AND BarsSince(crossedShort)>BarsSince(crossedLong) , longHH7 ) ;
atrvalue = ATR( 14 );
dt = DateTime() ;
Sell = Buy = 0;
PlotShapes( LongSignal*shapeDigit2, colorPink, layer = 0, L - range / 4 );
entryDate = Null;
SignalBar=0;
for( i = 1; i < BarCount; i++ )
{
if( LongSignal[i] AND !inLongPosition )
{
// store the low so i can cancel the buy signal if it goes below low
// mark the breakotu price so i can enter long when it enters breakout price
breakoutprice = High[i];
stopprice = Low[i];
SignalBar=i;
_TRACE( DateTimeToStr( dt[i] , 3 ) + "got signal " + " buy price" + breakoutprice + " loop id " + i );
}
if( inLongPosition == False AND !IsNull( breakoutprice ) AND i >SignalBar) // if high crosses breakout price then enter position.
{
_TRACE( DateTimeToStr( dt[i] , 3 ) + "checking breakout price " + breakoutprice + " loop id " + i );
if( High[i] > breakoutprice )
{
inLongPosition = True;
Buy[i] = True;
if(GappedUp[i] AND Open[i]>breakoutprice)
{
BuyPrice = Open[i];
}
else
{
BuyPrice = breakoutprice;
}
entryBar = i;
countHH7 = 0;
entryDate = DateTimeToStr( dt[i] , 3 ) ;
StaticVarSet( FullName() + entryDate, countHH7 );
StaticVarSet( FullName() + "L" + entryDate, countLongHH7SinceCrossedShort[i]-countLongHH7SinceCrossedLong[i] );
StaticVarSet( FullName() + "hh7beforeentry" + entryDate, countLongHH7SinceCrossedLong[i-1] ); // this is to count hh7 after it turns long but before entry. it does not include entry bar but includes signal bar
StaticVarSet( FullName() + "entryRisk" + entryDate, (breakoutprice-stopprice)/breakoutprice ); // entry risk is (entry price-stop price)/entry price
StaticVarSet( FullName() + "BreakoutRange" + entryDate, (breakoutprice-stopprice)/dailyRange[i] ); // entry risk is (entry price-stop price)/entry price
StaticVarSet( FullName() + "EntryGapUp" + entryDate, GappedUp[i] ); // gappedup on entry
StaticVarSet( FullName() + "BarDelays" + entryDate, i-SignalBar ); // how many bars after entry did i get signal.
_TRACE( DateTimeToStr( dt[i] , 3 ) + "got long " + " buy price" + breakoutprice );
}
else
{
if( Low[i] < stopprice )
{
// reset and cleanup
breakoutprice = Null;
stopprice = Null;
_TRACE( DateTimeToStr( dt[i] , 3 ) + "cleaned out price and cancelled " );
PlotText( "CAncelled Long", C[i], i, colorBlack, bkcolor = colorDefault, yoffset = 0 ) ;
}
}
}
if( inLongPosition AND i > entryBar )
{
if( hh7[i] AND H[i] > breakoutprice )
{
countHH7 += 1;
StaticVarSet( FullName() + entryDate, countHH7 );
_TRACE( DateTimeToStr( dt[i] , 3 ) + FullName() + entryDate );
}
if( Low[i] < stopprice )// close and cleanup
{
Sell[i] = True;
if(GappedDown[i] AND Open[i]<stopprice )
{
SellPrice = Open[i];
}
else
{
SellPrice = Low[i];
}
inLongPosition = False;
_TRACE( DateTimeToStr( dt[i] , 3 ) + "stopped long " + " stopprice" + Low[i] );
breakoutprice = Null;
stopprice = Null;
entryBar = -1;
}
else
{
//targetprice=BuyPrice+atrvalue[i];
if( High[i] >= ( breakoutprice + 3 * atrvalue[i] ) )
{
Sell[i] = True;
SellPrice = breakoutprice + atrvalue[i];
_TRACE( DateTimeToStr( dt[i] , 3 ) + "got target " + " targetprice" + ( breakoutprice + atrvalue[i] ) );
inLongPosition = False;
breakoutprice = Null;
stopprice = Null;
entryBar = -1;
}
}
}
}
//Buy = LongSignal; //=h>ValueWhen(LongSignal,High,1);// AND LowestSince(LongSignal,Low,1)>ValueWhen(LongSignal,Low,1);
Filter = true;
Short = Cover = False;
AddColumn( LongSignal, "LongSignal" );
AddColumn( countLongHH7SinceCrossedShort, "countLongHH7SinceCrossedShort" );
AddColumn( countLongHH7SinceCrossedLong, "countLongHH7SinceCrossedLong" );
//AddColumn(C>ValueWhen(LongSignal,High,1) ,"buysignal");
//AddColumn(LowestSince(Ref(LongSignal,1),Low,1),"lowestlow");
SetCustomBacktestProc( "" );
/* Now custom-backtest procedure follows */
if( Status( "action" ) == actionPortfolio )
{
bo = GetBacktesterObject();
bo.Backtest( 1 ); // run default backtest procedure
// iterate through closed trades first
for( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() )
{
// do your calculations involving trade objects (list of closed trades)
_TRACE( "inside backtester" );
countHH7 = StaticVarGet( trade.FullName + DateTimeToStr( trade.EntryDateTime , 3 ) ); // your value here
countLongHH7SinceCrossedShort=StaticVarGet(trade.FullName + "L" + DateTimeToStr( trade.EntryDateTime , 3 ));
trade.AddCustomMetric( "HH7bars", countHH7 );
trade.AddCustomMetric( "BeforeCrossHH7", countLongHH7SinceCrossedShort);
trade.AddCustomMetric( "hh7beforeentry", StaticVarGet(trade.FullName + "hh7beforeentry" + DateTimeToStr( trade.EntryDateTime , 3 )));
trade.AddCustomMetric( "EntryRisk", StaticVarGet(trade.FullName + "entryRisk" + DateTimeToStr( trade.EntryDateTime , 3 )));// entry risk is (entry price-stop price)/entry price
trade.AddCustomMetric( "BreakoutRange", StaticVarGet(trade.FullName + "BreakoutRange" + DateTimeToStr( trade.EntryDateTime , 3 )));// entry risk is (entry price-stop price)/entry price
trade.AddCustomMetric( "EntryGapUp", StaticVarGet(trade.FullName + "EntryGapUp" + DateTimeToStr( trade.EntryDateTime , 3 )));// gapped up on entry.
trade.AddCustomMetric( "BarDelays", StaticVarGet(trade.FullName + "BarDelays" + DateTimeToStr( trade.EntryDateTime , 3 )));// how many bars after signal did i enter
}
bo.ListTrades();
}