Stock Portfolio Organizer
The ultimate porfolio management solution.
WiseTrader Toolbox
#1 Selling Amibroker Plugin featuring:
HaConnorsRSI for Amibroker (AFL)
This is a combination of a number of approaches. I was particularly interested in Heikin-Ashi and ConnorsRSI.
It includes the regular AmiBroker optimization routine that optimizes the parameters, especially the ranking system.
Recently it Walk Forward tested well, 2 months training, 2 months application, overver the last two years against
the recent IBD Top Fifty stocks with a 3 position portfolio. Annualized out-of-sample was better than 30% but it also suffered a 20% max system draw-down.
Obviously, room for improvement.
Screenshots
Similar Indicators / Formulas
Indicator / Formula
// HaConnorsRSI 3 Pos AMin IBD Top Fifty 2011 - 2013 // Uses optimization to match ranking system with stock selection list // and combination buy and sell rules // Combined Systemms SetCustomBacktestProc(""); if ( Status( "action" ) == actionPortfolio ) { bo = GetBacktesterObject(); bo.Backtest(); // run default backtest procedure st = bo.GetPerformanceStats( 0 ); // get stats for all trades myMetric = st.GetValue( "CAR" ) + 3 * st.GetValue( "MaxSystemDrawdownPercent" ); expectancy = st.GetValue("WinnersAvgProfit")*st.GetValue("WinnersPercent")/100 + st.GetValue("LosersAvgLoss")*st.GetValue("LosersPercent")/100; UPI = st.GetValue("UlcerPerformanceIndex"); UPIexp = UPI * expectancy; // Here we add custom metric to backtest report bo.AddCustomMetric( "My metric", myMetric ); bo.AddCustomMetric( "Ulcer Performance", UPI ); bo.AddCustomMetric( "Expectancy ($)", expectancy ); bo.AddCustomMetric( "UPIexpect", UPIexp ); } OptimizerSetEngine("cmae"); // OptimizerSetOption("MaxEval",7000); OptimizerSetOption("Runs",3); // Hold 3 Positions = 3; //Optimize("Positions",5,1,10,1); PosQty = Positions; PositionSize = -100 / PosQty; // Screen Major Market using IJK - Remove comment slashes to include // IJK = Foreign("IJK","CLOSE"); // Over = Optimize("Over",35,3,35,1); // IJKema = EMA(IJK,Over); // IJKmin = Optimize("IJKmin",5,5,220,1); IJKok = 1; //ROC(IJKema,Over) > IJKmin; // Replace to activate // End of Screen // Heikin - Ashi Technique HaClose = (O + H + L + C) / 4; HaOpen = AMA( Ref( HaClose, -1 ), 0.5 ); HaHigh = Max( H, Max( HaClose, HaOpen ) ); HaLow = Min( L, Min(HaClose, HaOpen) ); // DeMark Pivot Points with HAT X = IIf( HaClose < HaOpen,HaHigh + 2 * HaLow + HaClose,0) ; X = IIf( HaClose > HaOpen, 2 * HaHigh + HaLow + HaClose, X); X = IIf( HaClose == HaOpen, HaHigh + HaLow + 2 * HaClose, X); HaPivot = X/4; HaSupport1 = X/2 - HaHigh; HaResist1 = X/2 - HaLow; OldResist = Ref(HaResist1,-1); Below = HaSupport1; Upper = HaClose > OldResist; PctAbove = (HaClose - OldResist)*100 / OldResist; // Percent above OldResist // Determination of Ranking Parameters using WMA AM3 = Optimize("Am3",2,2,21,1); Add3 = Optimize("Add3",2,2,21,1); Add4 = Optimize("Add4",13,2,21,1); Am5 = Am3 + Add3; Am8 = Am5 + Add4; Vol3 = WMA(Volume,Am3); Vol5 = WMA(Volume,Am5); Vol8 = WMA(Volume,Am8); // Price Stochastic Aprice = ( HaOpen + HaHigh + HaLow + HaClose) / 4; WSK3 = 100*(Aprice-LLV(Aprice,Am3))/(HHV(Aprice,Am3) - LLV(Aprice,Am3)); WLSK3 = WMA( WSK3, Am3); WLSD3 = WMA( WLSK3, Am3); WSK5 = 100*(Aprice-LLV(Aprice,Am5))/(HHV(Aprice,Am5) - LLV(Aprice,Am5)); WLSK5 = WMA( WSK5, Am5); WLSD5 = WMA( WLSK5, Am5); WSK8 = 100*(Aprice-LLV(Aprice,Am8))/(HHV(Aprice,Am8) - LLV(Aprice,Am8)); WLSK8 = WMA( WSK8, Am8); WLSD8 = WMA( WLSK8, Am8); Wvolume3 = WMA(Volume,Am3); WVSK3 = 100*(Wvolume3-LLV(Wvolume3,Am3))/(HHV(Wvolume3,Am3) - LLV(Wvolume3,Am3)); WVLSK3 = WMA( WVSK3, Am3); WVLSD3 = WMA( WVLSK3, Am3); WVSK5 = 100*(Wvolume3-LLV(Wvolume3,Am5))/(HHV(Wvolume3,Am5) - LLV(Wvolume3,Am5)); WVLSK5 = WMA( WVSK5, Am5); WVLSD5 = WMA( WVLSK5, Am5); WVSK8 = 100*(Wvolume3-LLV(Wvolume3,Am8))/(HHV(Wvolume3,Am8) - LLV(Wvolume3,Am8)); WVLSK8 = WMA( WVSK8, Am8); WVLSD8 = WMA( WVLSK8, Am8); MP3 = Optimize("MP3",8.2,0,10,0.1); MP5 = Optimize("MP5",6.9,0,10,0.1); MP8 = Optimize("MP8",5.7,0,10,0.1); MV3 = Optimize("MV3",2.7,0,10,0.1); MV5 = Optimize("MV5",0.2,0,10,0.1); MV8 = Optimize("MV8",4.9,0,10,0.1); RankP = MP3 * ROC(WLSD3,Am3) + MP5 * ROC(WLSD5,Am5) + MP8 * ROC(WLSD8,Am8); RankV = MV3 * ROC(WVLSD3,Am3) + MV5 * ROC(WVLSD5,Am5) + MV8 * ROC(WVLSD8,Am8); DeltaPrice = ROC(RankP,1); DeltaVolume = ROC(RankV,1); Mprice = IIf(DeltaPrice > 0,1 + DeltaPrice ,1); Mprice = IIf(Upper,Mprice + PctAbove,Mprice); MVolume = IIf(DeltaVolume > 0,1 + DeltaVolume,1); PctPct = Mprice * MVolume; PositionScore = PctPct; MinPctPct = Optimize("MinPctPct",41200,1000,100000,100); AddPctPct = Optimize("AddpctPct",24000,500,95000,100); BuyPctPct = MinPctPct + AddPctpct; // Connors RSI **************** LenRSI = Optimize("RSI Closes Length", 67, 2, 100, 1); LenUD = Optimize("RSI UpClose Length", 37, 2, 100, 1); LenROC = Optimize("PerecentRank Length", 110, 10, 200, 1); function ConnorsRSI(lenRSI, lenUD, lenROC) { upDays = BarsSince(HaClose <= Ref(HaClose,-1)); downDays = BarsSince(HaClose >= Ref(HaClose,-1)); updownDays = IIf(upDays > 0, upDays, IIf(downDays > 0, -downDays, 0)); crsi = ( PercentRank(ROC(HaClose,1), lenROC) + RSIa(updownDays,lenUD) + RSI(lenRSI))/3; return crsi; } /* Plot( ConnorsRSI(LenRSI,LenUD,LenRank) , "ConnorsRSI("+LenRSI+","+LenUD+","+LenRank+")" , colorBlue, styleLine, 0, 100); */ FromBelow = Optimize("FromBelow",8,5,50,1); FromAbove = Optimize("FromAbove",80,51,95,1); Buy = IJKok AND PctPct > BuypctPct AND (ConnorsRSI(lenRSI, lenUD, lenROC) > FromBelow);// AND Ref(ConnorsRSI(lenRSI, lenUD, lenROC),-1) < Ref(FromBelow,-1)); // Sell = ConnorsRSI(lenRSI, lenUD, lenROC) < FromAbove AND Ref(ConnorsRSI(lenRSI, lenUD, lenROC),-1) > Ref(FromAbove,-1); // HaDelta Optimized HaDays = Optimize("HaDays",19,2,21,1); HaAdd = Optimize("HaAdd",7,0,21,1); HaSignalDays = HaDays + HaAdd; HADelta_Line = MA( HaClose - HaOpen, HaDays); HADelta_Signal = MA( HaDelta_Line, HaSignalDays); HaDelta_Histogram = HaDelta_Line - HaDelta_Signal; Sell1 = HaDelta_Line < HaDelta_Signal; Sell2 = PctPct < MinPctPct; INone = Optimize("InOne",0,0,1,1); InOther = Optimize("InOther",0,0,1,1); Sell1 = Sell1 * InOne; Sell2 = Sell2 * InOther; Sell = Sell1 OR Sell2; Short = 0; Cover = 0; ExRem(Buy,Sell); ExRem(Sell,Buy); // ProfitN = Optimize("ProfitN",17,15,390,1); HoldOut = Optimize("HoldOut",7, 0, 8, 1); // ApplyStop( 1,3,ProfitN,2,True, HoldOut ); StopLoss = Optimize("StopLoss", 10, 5, 10, 1); ApplyStop( 0, 1, StopLoss, 0, True, HoldOut ); TrailStop = Optimize("TrailStop", 29, 3, 30, 1); ApplyStop( 2, 1, TrailStop, 0, True, HoldOut ); HoldStop = Optimize("HoldStop", 20, 3, 23, 1); ApplyStop( 3, 1, HoldStop, 0, True, HoldOut ); //OldEquity = Foreign("~~~EQUITY","C"); Filter = Buy OR Sell; AddColumn(Close,"Close",1.2); AddColumn(Buy,"Buy",1.0); AddColumn(Sell,"Sell",1.0); AddColumn(Open,"Open",1.2); AddColumn(High,"High",1.2); AddColumn(Low,"Low",1.2); AddColumn(Close,"Close",1.2); AddColumn(HaClose,"HaClose",1.2); AddColumn(PositionScore,"PctPct",1.0);
8 comments
Leave Comment
Please login here to leave a comment.
Back
no definition of function percentRank()
not working amibroker 5.5
not working in amibroker 5.5
tanks
very thanks, i want to communicate whit you about this indicator, i’ve noticed that parameter “holdstop” impact positively or negatively in drawdown
Tradermind . . .
Comment on HoldStop . . .
I wanted to limit the back fitting so that the parameters would be “comfortable” with a Walk-Forward that may be one or two months. When I allow a longer possible HoldStop, the optimization would select a large value, essentially not applicable to one, two month time frames.
Does that help? rbuck
So, in few words, from my study I can tell you the holdstop value for multiday is incorrect, the holdstop need to anchor it to a moving average 50/100/200 classical periods, that’s all, but at that point a simple moving average would beat you. that’s why I asked you to get in touch because I’m editing your system but I would need collaboration. Even the management of the short does not seem correct, I can not make coexist and indeed you did not manage it. Optimal results seem to have in interday periods with your setting.
Cmae engine don’t help to correct setting any value, because a random analysis, so or you limite the hlodstop value between 195-205 or must change the optimization engine or exclude momentarily other variables in testing,for example, I limited the number of shares to 1 instead of 3
Thanks Tradermind . . .
I usually measure the robustness of an approach by a Walk-Forward run that has an annualized return of 20% or greater in out-of-sample data – currently using two month steps. Through 2011 and 2012 this approach did satisfy that desire.
The optimization over the whole period is just to make certain I didn’t restrict any variables unintentionally. I’m still not quite satisfied with the integration of price and volume used in the ranking. Perhaps the square of some terms may tighten it up.
rbuck