You would do that by defining your own "fitness function" and exposing its value, for each backtest results row, as a named custom metric.
You would then use that named metric as the optimization target from the walk forward settings dialog. From that point on, your fitness result becomes the value which gets optimized.
In your case, your fitness function would be the value of CAR multiplied by a (possibly sliding) scale factor taking into account the number of trades.
You can see the idea in the code snippet below (which is using Ulcer Performance Index rather than CAR). The code is just a snippet taken from a larger implementation that included additional weights and had custom position sizing on a bar by bar basis. So, the snippet you see is not the most efficient in the context of this reply, but should give you the idea. You may need to use a multiplier (e.g. 100 in example) to raise values to larger numbers for display purposes only.
A few words of caution:
- This will help guide the optimizer, so it will give less weight to lesser values of your fitness function. But, it comes at the cost of custom backtest calculations which are not free. It may end up taking longer than without the guidance. But, it will result in values that better suit your wants.
- Keep in mind that you probably need a ratio of trades for the period under study, as opposed to a fixed one size fits all number of trades regardless of period duration.
- The Optimizers (e.g. CMAE) are designed to work against continuous fitness values. A simple on/off, high value/zero fitness will not work well and can lead to very long optimizations (in my experience). Even using the sliding scale of the example below, it would be better to have a more continuous scale for when there are too few trades rather than the sudden drop off factor of 0.001.
- Be sure to type in the exact name of your custom metric, including uppercase/lowercase as the target in the walk forward settings.
- CAR is a notoriously poor estimator of fitness.
Mike
SetCustomBacktestProc("");
inRange = Status("barinrange"); barsInRange = 0;
if (Status("action") == actionPortfolio) { bo = GetBacktesterObject(); bo.Backtest();
for (bar = 0; bar < BarCount; bar++) { if (inRange[bar]) { barsInRange++; }
stats = bo.getPerformanceStats(0); trades = stats.getValue("AllQty")/(barsInRange/252); // 252 bars per year
if (trades <= 252) { tMult = .001; // Penalize low trade volume } else if (trades >= 504) { tMult = 1; // 2 or more trades/day ideal } else { tMult = (trades - 252)/252; // Ratio of ideal }
upi = stats.getValue("UlcerPerformanceIndex"); optimal = upi * 100 * tMult;
bo.addCustomMetric("Optimal", optimal); bo.addCustomMetric("tMult", tMult); }
--- In amibroker@xxxxxxxxxxxxxxx, Richard <Richard.M.Ferri@xxx> wrote: > > Is it possibile optimize with a target like CAR excluding results with a > number of trades to low? > On this way the time required for optimization can be saved? >
__._,_.___
**** IMPORTANT PLEASE READ ****
This group is for the discussion between users only.
This is *NOT* technical support channel.
TO GET TECHNICAL SUPPORT send an e-mail directly to
SUPPORT {at} amibroker.com
TO SUBMIT SUGGESTIONS please use FEEDBACK CENTER at
http://www.amibroker.com/feedback/
(submissions sent via other channels won't be considered)
For NEW RELEASE ANNOUNCEMENTS and other news always check DEVLOG:
http://www.amibroker.com/devlog/
__,_._,___
|