Skip to main content

FullStochastic with Filters - Buy&Sell for Amibroker (AFL)

RBuck over 13 years ago Amibroker (AFL)

  • Rating:
    5 / 5 (Votes 1)
  • Tags:
    amibroker, optimize, trading ystem, walk forward

Full Stochastic with Filters . . . The Walk-Forward, train 2 months then apply next 2 months, over the 2011 – 2012 period performed acceptably using the IBD Top Fifty from 2/1/2013 and holding a max of 3 positions. The summary report for this out-of-sample approach showed an annualized return of over 30% with 43/75 trades profitable and a max portfolio draw-down of 9%.

The Full Stochastic approach, thanks to StockCharts library, is an attempt to “buy low and sell higher”. In this time-frame I often experience difficult performance in the August – October 2011 period with our fiscal cliff uncertainties.

It is recognized that running against a watch-list developed the end of January 2013 has a certain forward looking aspect that would be unallowable in a pure test performance. Somewhere down the road we may be able to refresh the watch-list at specified time intervals in a more honest mechanical approach.

A work in progress . . . by grace, RBuck

Screenshots

Indicator / Formula

Copy & Paste Friendly


//  Full Stochastic 3 Position 30 - 50 Top fifty 02/01/2013  2 months training    

//   Optimize over CAR 

//  Added Time Series Forecast 3 days out

//  Setup for Last Three Months on 02/04/2013

      
   SetCustomBacktestProc("");                   //  Set up some added metrics
   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); 

   Positions = 3;  // Optimize("Positions",1,1,5,1);
   PosQty = Positions;
   PositionSize = -100 / PosQty;

   //  Full Stochastic 

   pds = Optimize("pds",52,2,80,1);
   slw = Optimize("slw",31,1,38,1);
   slwD = Optimize("slwD",16,1,21,1);
   OB   = Optimize("OB",76,5,88,1);
   OSsub   = Optimize("OSSUB",7,5,70,1);
   OS = OB - OSsub;
   MaxFLSK = Optimize("MaxFLSK",21,2,44,1);
  
   FSK = 100*(C-LLV(L,pds))/(HHV(H,pds) - LLV(L,pds));  //  FastStockK
   FLSK = EMA( FSK, slw);                              //  FullStochK
   FLSD = EMA( FLSK, Slwd);                            //  FullStochD

    WhenGoUp = FLSD < OS AND Cross(FSK,OS) AND FLSK >= Ref(FLSK,-1) AND FLSD >= Ref(FLSD,-1) OR
                             Cross(FLSD,OS) AND FSK >= Ref(FSK,-1) AND  FLSK >= Ref(FLSK,-1) AND FLSK < MaxFLSK;  

    WhenGoDown = IIf(BarsSince(Cross(OS,FSK)) == 1 AND FLSK < OS,1,0) OR
                 Cross(OS,FSK) AND FLSK < Ref(FLSK,-1) OR
                 FLSK < OB AND FLSK > OS AND FLSK <= Ref(FLSK,-1) OR
                 FSK > OB AND FLSK > OB AND FLSD > OB AND FSK < Ref(FSK,-1) AND FLSK < Ref(FLSK,-1) AND FLSD <= Ref(FLSD,-1) OR
                 FSK > OB AND FLSK > OB AND FLSD > OB AND Cross(OB,FLSK);   

   ExRem(WhenGoUP,WhenGoDOwn);
   ExRem(WhenGoDown,WhenGoUp);
   Turn = BarsSince(WhenGoUp);
   TTurn = Turn + 1 - 1;
   Tgo = TTurn;
   Five = Optimize("Five",2,2,5,1);
    UpFive = (NOT WhenGoDown) AND (TTurn > 0) AND (Tgo > Five);

  //  Set up Stochastic 0 to 1 with Times Series Forecast;
   NormStoch = 0;
   NormStoch =  (Close - LLV(Low,pds))/ (HHV(High,pds) - LLV(Low,pds)); //  changed
   NormStoch = IIf(NormStoch < 0.001,0.001,NormStoch);
   ForeNmSth3 = TSF(NormStoch,3);
   Enough = Optimize("Enough",1.042,1.004,1.200,0.001);
   MaxForecast = Optimize("MaxForecast",0.33,0.05,0.35,0.01);
   ForeNmSth3  = IIf(ForeNmSth3 > MaxForecast,MaxForecast,ForeNmSth3);
   PlusForecast = ForeNmSth3 > NormStoch * Enough;

    //   62 - 20 Percent Deviation Ranking

    M1 = Optimize("M1",30,5,50,1);
    M2 = Optimize("M2",44,5,80,1);
    M3 = Optimize("M3",27,2,50,1);
    D1 = Optimize("D1",34,3,50,1);
    D2 = Optimize("D2",18,2,50,1);
    D3 = Optimize("D3",11,5,50,1);
   
    Rank1 = M1 * ROC(NormStoch,D1);
    Rank2 = M2 * ROC(NormStoch,D2);
    Rank3 = M3 * StDev(Close,D3)*100/EMA(Close,D3);  //  There is a question as to whither this metric should be plus or minus

   PositionScore = Rank1 + Rank2 + Rank3;

   MFIdays = Optimize("MFIdays",3,2,23,1);
   MFIconfirm = MFI(MFIdays) > 0;

    BuyDay = Optimize("BuyDay",9,3,31,1);

  Thirty = Optimize("Thirty",41,20,60,1);

    Buy =  Close > Open AND PlusForecast AND UpFive AND MFIconfirm AND FLSK < Thirty AND Day() > BuyDay;  // AND TurningUp;   
     
    Held = BarsSince(Buy);
    MinHold = Optimize("MinHold",14,2,15,1);
    TestTime = Optimize("TestTime",19,MinHold,20,1);
    Perform = Optimize("Perform",2,1,25,1);  // Eliminate lazy performing positions

     SellP = IIf(Held > MinHold AND ROC(C,TestTime) < Perform,1,0);

    Fifty = Optimize("Fifty",48,40,80,1);

   SellPoint = Optimize("SellPoint",6400,-1500,25000,10);
   Sell = ((Held > 3 AND PositionScore < SellPoint AND Ref(PositionScore,-1) > SellPoint) AND FLSK > Fifty) OR SellP OR WhenGoDown;  
     

     ExRem(Buy, Sell);
     ExRem(Sell,Buy);

	Short = 0;  
	Cover = 0;  

      ProfitN =  Optimize("ProfitN",199,15,390,1);
   HoldOut       = Optimize("HoldOut",2,     0,    33,     1);
   ApplyStop( 1,3,ProfitN,2,True, HoldOut );

	StopLoss   = Optimize("StopLoss",  7,     2,     8,     1);
	ApplyStop( 0, 1, StopLoss, 0, True, HoldOut );

	TrailStop  = Optimize("TrailStop",  20,     5,    25,     1);
	ApplyStop( 2, 1, TrailStop, 0, True, HoldOut );
	
 //   HoldStop   =  Optimize("HoldStop", 293,     3,    293,     1);
 //  ApplyStop( 3, 1, HoldStop, 0, True, HoldOut );
	//OldEquity = Foreign("~~~EQUITY","C");

   Filter = (PlusForecast > 0 AND Buy) OR (PlusForecast < 0 AND 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(FLSK,"FLSK",1.2);
   AddColumn(WhenGoUp,"WhenGoUp",1.0);
   AddColumn(Turn,"Turn",1.0);
   AddColumn(TTurn,"TTurn",1.0);
   AddColumn(MFIconfirm,"MFIcmf",1.0);

   AddColumn(WhenGoDown,"GoDown",1.0);
   AddColumn(NormStoch,"NStch",1.3);
   AddColumn(ForeNmSth3,"FStch3",1.3);
   AddColumn(PlusForecast,"PlsFre",1.3);

5 comments

over 13 years ago

Hello:
I applaud your attempt at a sophisticated trading system, which may produce some good results, as it appears to be based on sound trading principles.
However, (by my count) there are 30 variables in your code that can be optimized. This can very easily fall into the trap of being “curve fitted”. In general, the more variable that you have being optimized, the greater the opportunity for “curve fitting”.
Therefore, I recommend simplifying your approach and formulas, to the point of having less than 5 variables (at most!).

2. RBuck
over 13 years ago

JackTheMan18

I appreciate your comment and analysis. In my enthusiasm for the plus 30% annualized return on the Walk-Forward run I should have included the plot of that run rather than the fully back-fitted 3 month run I used to validate the approach.

I’ll send a plot of the Out-Of-Sample results over 2011 – 2012 and see if it man be replace the 3 month back-fitted plot.

Pour it on ! by grace . . . RBuck

over 13 years ago

dear RBuck can you explain me what is your routine of apply stop? i don’t understand if results is in % or in nBars? Thanks

Leave Comment

Please login here to leave a comment.