Traders' Tip text
Wealth-Lab’s strategy code includes Mr. Vervoort’s indicator plotting template and has success at producing similar performance results using only the trading rules employing the SVE_Stoch_IFT indicator, which now lives comfortably in Wealth-Lab’s TASCIndicator Library.  In addition, the money management rule for not sharing profit or loss between symbols inspired a new MS123.PosSizer to be created for that purpose.  The Equity Curve for the Portfolio Simulation with $100,000 starting equity is shown in Figure 1.  As a reminder, Wealth-Lab users should install the CBOE Provider extension from Wealth-Lab.com to easily access and update Put/Call Ratio data directly from the CBOE website. 
Figure 1. The strategy was able to avoid Buy & Hold’s large drawdown in 2008 (blue) by trading from the short side (red), which compensated the drawdown in long positions (black). 
Note: The indicator was added to the TASCIndicators library, version 2011.11.0.0
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using TASCIndicators;
namespace WealthLab.Strategies
{
   public class PutCallRatioIndicator : WealthScript
   {
      StrategyParameter _rsiPeriod;
      StrategyParameter _wmaPeriod;
      StrategyParameter _devs;
      StrategyParameter _slowRainbowPeriod;
      StrategyParameter _wmaSlow;
      StrategyParameter _rsiPer;
      StrategyParameter _stoPer;
      StrategyParameter _stoSmooth;
      
      public PutCallRatioIndicator()
      {
         _rsiPeriod = CreateParameter("Fast RSI Period", 5, 2, 30, 1);
         _wmaPeriod = CreateParameter("Fast WMA Period", 5, 2, 10, 1);
         _devs = CreateParameter("SD Multiple", 1.3, 1, 2, 0.1);
         _slowRainbowPeriod = CreateParameter("Slow Rbw Period", 4, 1, 10, 1);
         _wmaSlow = CreateParameter("Slow Smooth Period", 2, 1, 10, 1);
         _rsiPer = CreateParameter("Slow IF RSI Period", 8, 1, 20, 1);
         _stoPer = CreateParameter("Stoch Period", 30, 5, 500, 1);
         _stoSmooth = CreateParameter("Sto Smooth Perio", 5, 2, 10, 1);
      }   
      
      
      // Transforms a series for unscaled plotting (translated from WL4 Code Library, Dexter Brunet)
      public DataSeries TransformSeries( DataSeries ds, double a1, double a2, double b1, double b2)
      {
         string sName = ds.Description + "(No Scale)";
         if (Math.Abs(a1 - a2) > 0.00001)
         {
            double a = (b1 - b2)/(a1 - a2);
            double b = (b2 * a1 - a2 * b1)/(a1 - a2);
            DataSeries s = ds * a;
            s += b;            
            s.Description = sName;
            return s;
         }
         else
            return ds;
      }
      
      protected override void Execute()
      {                  
         // Access the raw P/C Ratio data
         DataSeries pcrEQ = GetExternalSymbol("CBOE", "EQUITYPC", true).Close;
         
         /* Create and plot indicators */
         HideVolume();   
         
         // Moving Averages
         DataSeries ma50 = SMA.Series(Close, 50);
         DataSeries ma100 = SMA.Series(Close, 100);
         DataSeries ma200 = SMA.Series(Close, 200);
         DataSeries ma20 = SMA.Series(Close, 20);
         DataSeries bbU = BBandUpper.Series(Close, 20, 2);
         DataSeries bbL = BBandLower.Series(Close, 20, 2);         
         PlotSeries(PricePane, ma50, Color.Blue, LineStyle.Solid, 1);
         PlotSeries(PricePane, ma100, Color.Red, LineStyle.Dashed, 1);
         PlotSeries(PricePane, ma200, Color.Red, LineStyle.Solid, 1);
         PlotSeries(PricePane, ma20, Color.Green, LineStyle.Solid, 1);
         PlotSeriesFillBand(PricePane, bbU, bbL, Color.Transparent, Color.FromArgb(30, Color.Green), LineStyle.Solid, 1);
         
         DataSeries fastPCRI = PCRiFast.Series(pcrEQ, _rsiPeriod.ValueInt, _wmaPeriod.ValueInt);
         DataSeries uBand = BBandUpper.Series(fastPCRI, 200, _devs.Value);
         DataSeries lBand = BBandLower.Series(fastPCRI, 200, _devs.Value);
         DataSeries slowPCRI = PCRiSlow.Series(pcrEQ, _slowRainbowPeriod.ValueInt, _wmaSlow.ValueInt);
         
         ChartPane rsiPane = CreatePane(40, false, true);
         PlotSeries(rsiPane, fastPCRI, Color.Black, LineStyle.Solid, 2);
         PlotSeries(rsiPane, uBand, Color.Blue, LineStyle.Dashed, 1);
         PlotSeries(rsiPane, lBand, Color.Blue, LineStyle.Dashed, 1);
                  
         // Transform slowPCRI for plotting in same pane as fastPCRI
         int n = Bars.Count - 1;
         DataSeries slowT = TransformSeries(slowPCRI, Lowest.Value(n, slowPCRI, n - 30), Highest.Value(n, slowPCRI, n - 30), 0, 100);
         ChartPane sloPane = CreatePane(40, false, true);
         PlotSeries(sloPane, slowT, Color.Red, LineStyle.Solid, 2);
         
         DataSeries pcri_IF = PCRiSlowIFT.Series(pcrEQ, _slowRainbowPeriod.ValueInt, _wmaSlow.ValueInt, _rsiPer.ValueInt);
         PlotSeries(sloPane, pcri_IF, Color.Blue, LineStyle.Solid, 2);
         
         DataSeries iftSto = InverseFisherStoch.Series(Close, _stoPer.ValueInt, _stoSmooth.ValueInt);
         DataSeries stoD = StochD.Series(Bars, _stoPer.ValueInt, _stoSmooth.ValueInt);
         ChartPane stoPane = CreatePane(40, false, true);
         PlotSeries(stoPane, iftSto, Color.Red, LineStyle.Solid, 2);
         PlotSeries(stoPane, stoD, Color.Blue, LineStyle.Solid, 1);
         
         for (int bar = GetTradingLoopStartBar(165); bar < Bars.Count; bar++)
         {
            if (IsLastPositionActive)
            {
               Position p = LastPosition;
               if (p.PositionType == PositionType.Long)
               {
                  if (CrossUnder(bar, iftSto, 60))
                     ExitAtMarket(bar + 1, p);
               }
               else if (CrossOver(bar, iftSto, 30))
                  ExitAtMarket(bar + 1, p);
            }
            else
            {   
               if (CrossOver(bar, iftSto, 30))
                  BuyAtMarket(bar + 1);   
               else if (CrossUnder(bar, iftSto, 60) && Closebar < SMA.Series(Close, 165)bar)
                  ShortAtMarket(bar + 1);
            }
         }
      }
   }
}