Hello all, Needed to test fixed Equity for PositionSize. This CBT code is what I came up with. Hope it can help someone. Of course, the code is final and provided as is. FE
//------------------------------------------------------------------- //CUSTOM BACTESTER //Limit Trade positions to a fixed Equity (Initial Equity) /*Notes: (1) ScaleIn/Out positionsize not calculated */ SetCustomBacktestProc(""); if( Status("action") == actionPortfolio ) { bo = GetBacktesterObject(); InitEq = bo.InitialEquity(); bo.PreProcess(); for( bar = 0; bar < BarCount; bar++ ) { //------------------------------------------------------------------- //handle EXIT signals for ( sig=bo.GetFirstSignal(bar); sig; sig=bo.GetNextSignal(bar) ) { if (sig.IsExit() && sig.Price != -1 ) { // Exit Signal bo.ExitTrade(bar,sig.symbol,sig.Price); } } //update stats after closing trades bo.UpdateStats(bar, 0); //------------------------------------------------------------------- //Handle ENTRY signals //determine Open Trade Capital BEFORE executing current signals OpnEq = 0; EntPosn = 0; for( Openpos=bo.GetFirstOpenPos(); Openpos; Openpos=bo.GetNextOpenPos() ) { OpnEq = OpnEq + OpenPos.GetPositionValue(); EntPosn = EntPosn + OpenPos.GetEntryValue(); } //calc available capital AvailCapital = InitEq - EntPosn; //------------------------------------------------------------------- //Find the signals and adjust positionsize for available capital //I think the list is in positionscore rank, highest to lowest for ( sig=bo.GetFirstSignal(bar); sig; sig=bo.GetNextSignal(bar) ) { if( sig.IsEntry() && sig.Price != -1 ) { //------------------------------------------------------------------- //Calculate the dollar value for positionsize fSize = sig.PosSize; switch( fSize ) { //values below -2000 encode share count, case fSize < -2000: PosnSize = fSize*sig.Price; break; //values between -2000 AND -1000 encode % of current position //NOT CODED - scaleIn/Out (see note 1) case fSize < -1000 AND fSize >= -2000: //PosnSize = int( ??? * abs(fSize) / 100 ); break; //values between -1000 AND 0 encode % of portfolio FIXED Equity case fSize < 0 AND fSize >= -1000: PosnSize = int( InitEq * abs(fSize) / 100 ); break; //values above 0 encode dollar value case fSize > 0: default: PosnSize = fSize; break; } //------------------------------------------------------------------ //ignore signal if not enough capital for position if( PosnSize > AvailCapital ) { sig.Price = -1; } //take the (Long) trade & re-calculate AvailCapital else { bo.EnterTrade( bar, sig.symbol, sig.IsLong(), sig.Price, sig.PosSize, sig.PosScore ); AvailCapital = AvailCapital - PosnSize; } }//if IsEntry }//for sig //MAE/MFE is updated when timeinbar is set to 1 bo.UpdateStats(bar, 1); bo.UpdateStats(bar, 2); //remove section below if composite not needed //------------------------------------------------------------------- //Update Capital in Open Trades for current bar signals NumTrades[bar] = 0; OpenEquity[bar] = 0; EntryPosn[bar] = 0; for( Openpos=bo.GetFirstOpenPos(); Openpos ; Openpos=bo.GetNextOpenPos() ) { NumTrades[bar]++; OpenEquity[bar] = OpenEquity[bar] + OpenPos.GetPositionValue(); EntryPosn[bar] = EntryPosn[bar] + OpenPos.GetEntryValue(); } //end of remove section }//for bar bo.PostProcess(); //remove section below if composite not needed //------------------------------------------------------------------ //save info to composite FlagFixedCapital = atcFlagEnableInPortfolio | atcFlagDefaults; AddToComposite(NumTrades, "~FixedCapital", "V", FlagFixedCapital); AddToComposite(OpenEquity, "~FixedCapital", "C", FlagFixedCapital); AddToComposite(EntryPosn, "~FixedCapital", "O", FlagFixedCapital); //end of remove section }//if actionportfolio //END CBT CODE /*=========================================================== Settings ===========================================================*/ TimeFrameSet(inDaily); Capital = Param("Initial Equity",100000,50000,300000,10000); SetOption("Initialequity", Capital); SetOption("MaxOpenPositions", 17 ); SetOption("PriceBoundChecking", True ); SetOption("AllowPositionShrinking",False); SetOption("MinPosValue",5000); SetOption("CommissionMode",2);//no commission SetOption("CommissionAmount",0); SetOption("UsePrevBarEquityForPosSizing",True); SetOption("HoldMinBars",0); SetBacktestMode( BacktestRegularRaw); //keeps redundant entry signals SetTradeDelays(0,0,0,0); //long only; delays=1 in code //------------------------------------------------------------------- // your trading system here fast = 12;//Optimize("fast", 12, 5, 20, 1 ); slow = 26;//Optimize("slow", 26, 10, 25, 1 ); BuySetup = Cross(MACD(fast,slow),Signal(fast,slow)); SellSetup = Cross(Signal(fast,slow),MACD(fast,slow)); /*=========================================================== BUY/SELL (long) ===========================================================*/ dt = 0; if( Status("Action")==actionBacktest ) { dt = 1; }//delay trade 1 bar Buy = Ref(BuySetup,-dt); Sell = Ref(SellSetup,-dt); BuyPrice = O; SellPrice = O; /*=========================================================== POSITIONSIZE ===========================================================*/ SetPositionSize(10000,spsValue);