Mike -

Hard to follow these threads sometimes, but when Markus wrote -

"And in signal list, I can only specify the position size in
terms of money rather than the number of shares ..."

I thought that he didn't see how to encode number of shares directly in 
sig.PosSize in the Signal object in the CBT and have it used for the trade.  
So, I referred him to the help which details the encoding - that is, -2000 for 
number of shares.  This can be calculated from cash and be set in the CBT 
signal list before making mid or low level calls to process signal trades.

-- BruceR


--- In [email protected], "Mike" <sfclimb...@...> wrote:
>
> Bruce,
> 
> In this case he is trying to calculate shares based on portfolio cash 
> position. So, SetPositionSize using spsShares does not apply since portfolio 
> cash is not known except in the custom backtester.
> 
> Mike
> 
> --- In [email protected], "bruce1r" <brucer@> wrote:
> >
> > Markus -
> > 
> > Saw this post also in skimming.  Another easy one that can be summed up as 
> > check the help (ALWAYS).  In this case look for the function related to 
> > PositionSize.  It is SetPositionSize().  See how # of shares is encoded in 
> > the signal object for the backtester.  Then, you can read or write it 
> > before processing the signal in the CBT.
> > 
> > Just a suggestion since you indicated you were new to this, but targeted 
> > search of the help file for additional related info is something that 
> > you'll find yourself doing often.
> > 
> > -- BruceR
> > 
> > 
> > --- In [email protected], "Mike" <sfclimbers@> wrote:
> > >
> > > Markus,
> > > 
> > > To simplify your life, start first by not using any commissions in your 
> > > backtest (see Settings of Auto Analysis window). Then do as you have 
> > > outlined; set the position size to the Signal.Price multiplied by the 
> > > number of shares desired. You definitely do not want to work with either 
> > > trade list, that's too late - the trade has already taken place.
> > > 
> > > If you have any rounding issues, post your formula here, or send it  to 
> > > support and they can help clarify for you.
> > > 
> > > Mike
> > > 
> > > --- In [email protected], "Markus Witzler" <funnybiz@> wrote:
> > > >
> > > > Hi Mike,
> > > > 
> > > > thanks loads for your thorough explanations!
> > > > 
> > > > I´ll need to digest what you wrote but I´m still a little confused. I 
> > > > had read the pdf you mentioned a couple of weeks ago but as it turns 
> > > > out completely misunderstood!
> > > > 
> > > > I don´t understand how I make sure that exactly the number of shares is 
> > > > being bought that I want (whatever amount of money that means)? If I 
> > > > specify sig.possize in signal loop (which implies a given number 
> > > > shares?!), this could maybe (in some cases) result - due to rounding 
> > > > issues- in a slightly differing number of shares, right (I don´t know 
> > > > how AB rounds up or down)? Buying/selling the exact number of shares is 
> > > > crucial for my purposes!
> > > > 
> > > > So, where do I do that? The closed trade list probably is not the right 
> > > > spot to determine # of shares since the trades already have been 
> > > > closed. The open trade list probably not as well since there the trades 
> > > > already have been initiated, right? And in signal list, I can only 
> > > > specify the position size in terms of money rather than the  number of 
> > > > shares, even if I did it like this:
> > > > sharesize=round(((Heat*bo.cash)/(y*ATRmultiplier))/250)*250; // i.e. # 
> > > > of shares/contracts
> > > > 
> > > > sig.possize=sharesize*sig.price;     // i.e. position value in terms of 
> > > > USD
> > > > 
> > > > The other issue you mentioned (determening a trade´s bar number) needs 
> > > > to wait until I have understood this issue - but it sounds somehat 
> > > > complicated...
> > > > 
> > > > Sorry for my ignorance!
> > > > 
> > > > Markus
> > > > 
> > > > 
> > > >   ----- Original Message ----- 
> > > >   From: Mike 
> > > >   To: [email protected] 
> > > >   Sent: Wednesday, July 15, 2009 4:40 AM
> > > >   Subject: [amibroker] Re: Using CBI the first time
> > > > 
> > > > 
> > > > 
> > > > 
> > > > 
> > > >   Markus,
> > > > 
> > > >   If you haven't already, it would be a good idea to read "AmiBroker 
> > > > Custom Backtester Interface.pdf" found in the files section of this 
> > > > group.
> > > > 
> > > >   The way your code is now, you are trying to mix and match signals 
> > > > with trades, which is not permitted.
> > > > 
> > > >   A signal does not become a trade until *after* the signal has been 
> > > > processed by the backtester. There are a number of portfoliio 
> > > > restrictions that may prevent a signal from actually being accepted and 
> > > > made into a trade. For example, you may not have sufficient funds, you 
> > > > may have exceeded the number of allowable open positions, etc.
> > > > 
> > > >   You need to set the position size on the Signal object. If the signal 
> > > > becomes a trade, that is what will later dictate the Trade object's 
> > > > shares. Note that a Signal's PosSize property can be expressed as a 
> > > > percetage of equity (negative) or as a dollar amount (positive). Do the 
> > > > math and use a positive number to control the number of shares (e.g. 
> > > > number of shares desired multiplied by share price, remember to take 
> > > > into account commisions if you use them).
> > > > 
> > > >   You will not have bar by bar access to the trade list as you do with 
> > > > signals. Therefore, you must determine the bar index of the trade based 
> > > > on its entry date then use Foreign to reference the bar by bar data 
> > > > using the bar index for that date. An example of this approach can be 
> > > > seen in a similar post that I made a short while ago:
> > > > 
> > > >   http://finance.groups.yahoo.com/group/amibroker/message/139969
> > > > 
> > > >   As for your custom trade metrics. I don't see a need for showing the 
> > > > number of shares since this is already provided by AmiBroker in the 
> > > > backtest report. Also, since Signal.PosSize ultimately ends up being 
> > > > the same as Trade.Shares, this information is also already there. As 
> > > > for the cash position prior to the trade, that would be available as 
> > > > the Low in ~~~Equity for the bar prior to the bar of the trade as 
> > > > outlined in this message:
> > > > 
> > > >   http://finance.groups.yahoo.com/group/amibroker/message/139634
> > > > 
> > > >   Hope that helps.
> > > > 
> > > >   Mike
> > > > 
> > > >   --- In [email protected], "Markus Witzler" <funnybiz@> wrote:
> > > >   >
> > > >   > Hello Mike,
> > > >   > 
> > > >   > thanks from a newbie. I wasn´t aware of that.
> > > >   > 
> > > >   > I still have another problem:
> > > >   > 
> > > >   > Since I use low-level code (to be able to employ proprietary stops 
> > > > later on), I need to use the signal list to exit/enter trades.
> > > >   > 
> > > >   > Since I want to have a per-trade output of my metrics, I need to 
> > > > use trade.addcustommetric rather than bo.addcustommetric.
> > > >   > 
> > > >   > But when I use trade.addcustommetric in a signal list, I get an 
> > > > error (see code below).
> > > >   > 
> > > >   > I understand the problem but don´t find a way out.
> > > >   > 
> > > >   > The same is true for trader.shares (see code). I need it to 
> > > > calculate correct position value which is then subtracted from actual 
> > > > cash position to get the new cash position after a trade.
> > > >   > 
> > > >   > Maybe, you can jump in once again, if you don´t mind? This whole 
> > > > CBI thing is stilla little beyond me, to be homest>G<.
> > > >   > 
> > > >   > Thansk again
> > > >   > 
> > > >   > Markus
> > > >   > 
> > > >   > SetCustomBacktestProc("");
> > > >   > 
> > > >   > if (Status("action") == actionPortfolio)
> > > >   > 
> > > >   > {
> > > >   > 
> > > >   > bo = GetBacktesterObject(); // Get backtester object
> > > >   > 
> > > >   > 
> > > >   > 
> > > >   > bo.PreProcess(); // Do pre-processing
> > > >   > 
> > > >   > 
> > > >   > Initial_equity=bo.cash=1000000.00; 
> > > >   > 
> > > >   > My_total_equity=0; 
> > > >   > 
> > > >   > Value_open_positions=0;
> > > >   > 
> > > >   > Heat=0.1;
> > > >   > 
> > > >   > y=0;
> > > >   > 
> > > >   > ATRmultiplier=5; 
> > > >   > 
> > > >   > 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
> > > >   > 
> > > >   > // Long trades
> > > >   > 
> > > >   > if (sig.IsEntry() && sig.IsLong()) // Process long entries
> > > >   > 
> > > >   > 
> > > >   > {
> > > >   > 
> > > >   > ATRexRounded = Foreign("~ATRExpLagRounded_"+sig.Symbol, "V"); // 
> > > > Get symbol's AtrExpLagRounded array, which is simply an exp. MA of the 
> > > > Average True range of a given number of days. I used a proprietary code 
> > > > to set the first day´s value as seed value rather than zero, as AB´s 
> > > > ATR() function apparrently does. 
> > > >   > 
> > > >   > ATRex = ATRexRounded[i]; // Reference a value in the array
> > > >   > 
> > > >   > if (i=0) 
> > > >   > 
> > > >   > y=ATRexRounded[i];
> > > >   > 
> > > >   > else
> > > >   > 
> > > >   > 
> > > >   > if (i>0)
> > > >   > 
> > > >   > y=ATRexRounded[i-1];
> > > >   > 
> > > >   > 
> > > >   > }
> > > >   > 
> > > >   > trade.shares=round(((Heat*bo.cash)/(y*ATRmultiplier))/250)*250; // 
> > > > i.e. # of shares/contracts rounded to the nearest 250 lot and depending 
> > > > on the actual cash position
> > > >   > 
> > > >   > sig.possize=pos_size_shares*sig.price; // i.e. position value, 
> > > > expressed in USD
> > > >   > 
> > > >   > bo.EnterTrade(i, sig.Symbol, True, sig.Price, sig.PosSize);
> > > >   > 
> > > >   > trade.AddCustomMetric("initial equity", initial_equity); // to get 
> > > > per-trade statistics!
> > > >   > 
> > > >   > trade.AddCustomMetric("Cash position", bo.cash); 
> > > >   > 
> > > >   > trade.AddcustomMetric("Position size [shares]", trade.shares);
> > > >   > 
> > > >   > trade.AddCustomMetric("Position Value", sig.possize);
> > > >   > 
> > > >   > }
> > > >   > 
> > > >   > else
> > > >   > 
> > > >   > { if (sig.IsExit() && sig.IsLong()) // Process long exits (cover 
> > > > longs)
> > > >   > 
> > > >   > bo.ExitTrade(i, sig.Symbol, sig.Price);
> > > >   > 
> > > >   > }
> > > >   > 
> > > >   > // Short side
> > > >   > 
> > > >   > if (sig.IsEntry() && sig.IsLong()==False) // Process short entries
> > > >   > 
> > > >   > 
> > > >   > {
> > > >   > 
> > > >   > ATRexRounded = Foreign("~ATRExpLagRounded_"+sig.Symbol, "V"); // 
> > > > Get symbol's AtrExpLagRounded array
> > > >   > 
> > > >   > ATRex = ATRexRounded[i]; // Reference a value in the array
> > > >   > 
> > > >   > if (i=0)
> > > >   > 
> > > >   > {
> > > >   > 
> > > >   > y=ATRexRounded[i];
> > > >   > 
> > > >   > }
> > > >   > 
> > > >   > else
> > > >   > 
> > > >   > {
> > > >   > 
> > > >   > 
> > > >   > y=ATRexRounded[i-1];
> > > >   > 
> > > >   > }
> > > >   > 
> > > >   > trade.shares=round(((Heat*bo.cash)/(y*ATRmultiplier))/250)*250;
> > > >   > 
> > > >   > sig.possize=pos_size_shares*sig.price;
> > > >   > 
> > > >   > bo.EnterTrade(i, sig.Symbol, False, sig.Price, sig.PosSize);
> > > >   > 
> > > >   > }
> > > >   > 
> > > >   > else
> > > >   > 
> > > >   > {
> > > >   > 
> > > >   > if (sig.IsExit() && sig.IsLong()==False) // Process (cover) short 
> > > > exits
> > > >   > 
> > > >   > 
> > > >   > bo.ExitTrade(i, sig.Symbol, sig.Price);
> > > >   > 
> > > >   > }
> > > >   > 
> > > >   > bo.HandleStops(i); // Process programmed stops or applystop at this 
> > > > bar
> > > >   > 
> > > >   > } // End of for loop over signals at this bar
> > > >   > 
> > > >   > for (trade = bo.GetFirstOpenPos(); trade; trade = 
> > > > bo.GetNextOpenPos())
> > > >   > 
> > > >   > { // Loop through all open positions
> > > >   > 
> > > >   > 
> > > >   > Value_open_positions=Value_open_positions+ 
> > > > trade.getprice(i,"C")*trade.shares;
> > > >   > 
> > > >   > trade.addCustomMetric("Value of open positions", 
> > > > Value_open_positions);
> > > >   > 
> > > >   > My_total_equity=bo.cash+Value_open_positions;
> > > >   > 
> > > >   > trade.AddCustomMetric("My total equity", My_total_equity);
> > > >   > 
> > > >   > } // End of for loop over trades 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
> > > >   > 
> > > >   > AddToComposite( My_total_equity, "~~~My_total_equity", "X", 
> > > > atcFlagEnableInPortfolio | atcFlagDefaults ); // to plot an indicator
> > > >   > 
> > > >   > AddToComposite( trade.shares,"~~~Position size [shares]", "X", 
> > > > atcFlagEnableInPortfolio | atcFlagDefaults );
> > > >   > 
> > > >   > AddToComposite( sig.possize, "~~~Position Value", "X", 
> > > > atcFlagEnableInPortfolio | atcFlagDefaults );
> > > >   > 
> > > >   > AddToComposite( bo.cash, "~~~Cash position", "X", 
> > > > atcFlagEnableInPortfolio | atcFlagDefaults );
> > > >   > 
> > > >   > AddToComposite( Value_open_positions, "~~~Value of open positions", 
> > > > "X", atcFlagEnableInPortfolio | atcFlagDefaults );
> > > >   > 
> > > >   > }
> > > >   > 
> > > >   > 
> > > >   > 
> > > >   > ----- Original Message ----- 
> > > >   > From: Mike 
> > > >   > To: [email protected] 
> > > >   > Sent: Tuesday, July 14, 2009 8:14 PM
> > > >   > Subject: [amibroker] Re: Using CBI the first time
> > > >   > 
> > > >   > 
> > > >   > 
> > > >   > 
> > > >   > 
> > > >   > Hi,
> > > >   > 
> > > >   > I believe that your code says it all ;)
> > > >   > 
> > > >   > > } // End of for loop over trades at this bar
> > > >   > > 
> > > >   > > ...
> > > >   > > trade.AddCustomMetric("My total equity", My_total_equity);
> > > >   > 
> > > >   > "trade" is null after the loop.
> > > >   > 
> > > >   > Mike
> > > >   > 
> > > >   > --- In [email protected], "Markus Witzler" <funnybiz@> 
> > > > wrote:
> > > >   > >
> > > >   > > Hello all,
> > > >   > > 
> > > >   > > I intend to create a proprietary formula for "My_total_equity" to 
> > > > able to modify it later on to suit to my individual needs.
> > > >   > > 
> > > >   > > Here, I_ use "Value of cash position (bo.cash) + value (all open 
> > > > positions by their close)" as a start.
> > > >   > > 
> > > >   > > When I run backtest, I get the following message: 
> > > >   > > 
> > > >   > > "Com Variable not initialized or has invalid type" though I 
> > > > initialized "Value_open_positions=0" and also "My_total_equity=0;"
> > > >   > > 
> > > >   > > The loop to determine the aggregate value of all open positions 
> > > > goes like this:
> > > >   > > 
> > > >   > > for (trade = bo.GetFirstOpenPos(); trade; trade = 
> > > > bo.GetNextOpenPos())
> > > >   > > 
> > > >   > > { // Loop through all open positions
> > > >   > > 
> > > >   > > 
> > > >   > > Value_open_positions=Value_open_positions+ 
> > > > trade.getprice(i,"C")*trade.shares;
> > > >   > > 
> > > >   > > trade.addCustomMetric("Value of open positions", 
> > > > Value_open_positions);
> > > >   > > 
> > > >   > > } // End of for loop over trades at this bar
> > > >   > > 
> > > >   > > 
> > > >   > > My_total_equity=bo.cash+Value_open_positions;
> > > >   > > 
> > > >   > > trade.AddCustomMetric("My total equity", My_total_equity);
> > > >   > > 
> > > >   > > Where is the mistake? If the whole code is required, please let 
> > > > me know.
> > > >   > > 
> > > >   > > Thanks
> > > >   > > 
> > > >   > > Markus
> > > >   > >
> > > >   >
> > > >
> > >
> >
>


Reply via email to