TASC 2011-12 | Stoch IFT Strategy (Vervoort)

Modified on 2011/11/09 22:17 by Administrator — Categorized as: TASC Traders Tips

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.


Image
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) && Close[bar] < SMA.Series(Close, 165)[bar]) ShortAtMarket(bar + 1); } } } } }