Been trying to use this line of codes by sir @Tomasz on achieving properly my goal but i cant find correct solution.
What i am trying to achieve is to :
Limit consecutive losses per month on portfolio level and reset counter of losses at last day of month.
dn= Datenum();
tn= Timenum();
newday = dn != Ref(dn, -1);
//within the same month , if 4 consecutive losses on any symbol
//skip the following entry signal after consecutive losses of 4 and by
//every last day of month reset counting of consecutive losses to 0.
//resume counting of consloss on fisrtday of month and so on and so forth.
fisrtdayofmonth = month() != Ref(Month(), -1);
lastdayofmonth = TimeFrameExpand(1, inMonthly, ExpandPoint);
SetCustomBacktesterProc("");
if( Status("Action") == actionPortfolio ){
bo.GetBacktesterObject();
bo.PreProcess();
for(i = 0; i < BarCount; i++) {
if( inNewMonth[i] ) {
losses = 0; //initialize here or outside bar
prevprofit = 0;
for(trade=bo.GetFirstTrade();trade;trade=bo.GetNextTrade()){
profit = trade.GetProfit();
if( losses < 4 ){
if( profit > 0 ) losses = 0;
else
{
if( prevprofit > 0 AND ) losses = 0;
else
losses++;
if( lastdayofmonth )
losses = 0;
}
prevprofit = profit;
}
}
for(sig=bo.GetFirstSignal(i);sig;sig=bo.GetNextSignal(i) ){
if( sig.IsEntry() AND losses >= 4 )
sig.Price = -1;// this line totally skip all entry signal after 4 consecutive losses.
/* how can i reset "consloss" counter to 0 at every firstday of month and start
counting consloss until end of month ? */
}
bo.ProcessTradeSignals(i);
}
bo.PostProcess();
}
For starters, your code never defines the variable inNewMonth, so it wouldn't run even if you had included some Phase 1 logic to set Buy and Sell signals and prices. If you want help, please post complete working code. See #3 here: How to ask a good question
This code is not perfect, but it gets you close. It only counts consecutive losses for the "current" month and year, i.e. the month and year corresponding to the bar indicated by the index "i" in your outer loop.
I say it's not perfect because it will allow a new entry on the day that the 3rd loss occurs. The only way to prevent that would be to write a low level CBT and handle your own entries and exits.
SetSortColumns(5);
ma20 = MA( C , 20 );
ma50 = MA(C, 50 );
//sample buy&sell rule for testing idea only
Buy = RSI(14) > 70;
Sell = Cross( ma20, ma50 );
ApplyStop( stopTypeLoss , stopModePercent, 5, 1, False, 1 );
newmonth = Month() != Ref(Month(), -1 );
lastdayofmonth = TimeFrameExpand( 1, inMonthly, expandPoint );
inNewMonth = Flip( newmonth , lastdayofmonth );
dn = DateNum();
maxConsLoss = 3;
SetCustomBacktestProc("");
if (Status("action") == actionPortfolio)
{
bo = GetBacktesterObject();
bo.PreProcess();
dt = DateTime();
prevMonthYear = floor(dn[0]/100);
isTradingAllowed = True;
for (i = 0; i < BarCount; i++)
{
currMonthYear = floor(dn[i]/100);
bo.ProcessTradeSignals( i );
if (isTradingAllowed OR currMonthYear != prevMonthYear)
{
consLoss = 0;
isTradingAllowed = True;
for( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() )
{
tradeMonthYear = floor(DateTimeConvert(0, trade.ExitDateTime) / 100);
if (tradeMonthYear == currMonthYear)
{
profit = trade.GetProfit();
if (profit >= 0)
{
consLoss = 0;
}
else
{
++consLoss;
_TRACE(NumToStr(dn[i],8.0,False)+": "+trade.Symbol+" consLoss="+consLoss);
if (consLoss >= maxConsLoss)
{
isTradingAllowed = False;
_TRACE(NumToStr(dn[i],8.0,False)+": isTradingAllowed = False");
break;
}
}
}
}
}
if (!isTradingAllowed)
{
cnt = 0;
for (sig = bo.GetFirstSignal( i ); sig; sig = bo.GetNextSignal( i ) )
{
if(sig.IsEntry())
{
sig.Price = -1; // SKIP signal
cnt++; //counting skip signals for info only
}
// _TRACE("Date&Time: " + DateTimeToStr(dt[i]) + " consLoss: " + consLoss + " SkiP Signals count: " + cnt );
}
}
prevMonthYear = currMonthYear;
}
bo.PostProcess();
}