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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | // 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