Traders' Tip text
We created and plotted the 350 Swing indicator per the specifications of the article, though the details of applying it in a strategy required a bit of artistic license. Concentrating on the swing indicator during upward trends determined by a 3-pole 50-Period Gaussian (more responsive than an EMA), we used the 350 Alerts as a setup for both the entries and exits. An entry is triggered when price reaches the highest high of the previous 2 bars after an SMARSI(3) below 20, whereas the exit occurs at the close of the bar on which the low reaches the lowest low of the previous 2 bars. This trigger strategy often entered and exited a prospective trade 1 bar earlier than waiting for the indicator to cross the 20/80 levels in the opposite direction. To protect against unforeseen disasters, we implemented a 5% stop loss. While the Donchian channels weren’t used in the trading strategy, they’re plotted for reference.
Figure 1. This swing strategy works well to capture the meaty part of swings, but can leave you out of the most profitable trades in strong trends.
WealthScript Code (C#)
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using TASCIndicators;
namespace WealthLab.Strategies
{
public class Swing350 : WealthScript
{
private StrategyParameter rsiPer;
private StrategyParameter smaPer;
private StrategyParameter donchPer;
private StrategyParameter gaussPer;
public Swing350()
{
gaussPer = CreateParameter("Gaussian Period",50,10,100,5);
donchPer = CreateParameter("Donchian Period",13,8,21,1);
rsiPer = CreateParameter("RSI Period",3,2,21,1);
smaPer = CreateParameter("SMA(RSI)Period",3,2,21,1);
}
protected override void Execute()
{
bool longSetup = false;
bool sellSetup = false;
Font font = new Font("Wingdings", 8, FontStyle.Bold);
string diamond = Convert.ToChar(0x0077).ToString();
// Create and Plot Indicators
DataSeries gauss = Gaussian.Series(Close, gaussPer.ValueInt, 3); // 3 poles
DataSeries rsi = RSI.Series(Close, rsiPer.ValueInt);
DataSeries smaRsi = SMA.Series(rsi, smaPer.ValueInt);
DataSeries upper = Highest.Series(High, donchPer.ValueInt);
DataSeries lower = Lowest.Series(Low,donchPer.ValueInt);
DataSeries mid = (upper + lower) / 2d;
mid.Description = "Mid Donchian";
ChartPane paneRSI = CreatePane(40,true,true);
PlotSeries(paneRSI, rsi,Color.FromArgb(128,0,128,0), LineStyle.Solid, 1);
PlotSeriesOscillator(paneRSI, smaRsi,80,20,Color.FromArgb(63,0,0,255),Color.FromArgb(63,255,0,0),Color.FromArgb(255,0,0,128),LineStyle.Solid, 1);
DrawHorzLine(paneRSI, 50, Color.Pink, WealthLab.LineStyle.Dashed, 2);
PlotSeries(PricePane,gauss,Color.Gray,LineStyle.Solid,1);
PlotSeries(PricePane,upper,Color.Red,LineStyle.Dashed,1);
PlotSeries(PricePane,lower,Color.Green,LineStyle.Dashed,1);
PlotSeries(PricePane,mid,Color.Blue,LineStyle.Solid,1);
PlotStops();
for(int bar = GetTradingLoopStartBar(1); bar < Bars.Count; bar++)
{
bool trendBullish = gauss[bar] - gauss[bar - gaussPer.ValueInt / 2] > 0
&& gauss[bar] > gauss[bar - 2];
if (trendBullish) SetBackgroundColor(bar, Color.Azure);
// Color bars. OHLC Bar chart recommended!
if (smaRsi[bar] < 50)
SetBarColor(bar, Color.Red);
else if (smaRsi[bar] >= 50)
SetBarColor(bar, Color.Green);
// Draw the Alert diamonds
if (smaRsi[bar] > 80)
{
AnnotateBar(diamond, bar, true, Color.Red, Color.Transparent, font);
sellSetup = true;
}
else if (smaRsi[bar] < 20)
{
AnnotateBar(diamond, bar, false, Color.Green, Color.Transparent, font);
longSetup = true;
}
if (IsLastPositionActive)
{
longSetup = false;
Position p = LastPosition;
if (Close[bar] < p.RiskStopLevel)
SellAtClose(bar, p, "Stop");
else if (sellSetup)
{
if (Low[bar] < Lowest.Series(Low, 2)[bar - 1])
SellAtClose(bar, p, "Swing");
}
}
else if (trendBullish)
{
sellSetup = false;
RiskStopLevel = Highest.Series(High, 2)[bar - 1] * 0.95;
if (longSetup ) BuyAtStop(bar + 1, Highest.Series(High, 2)[bar - 1]);
}
}
}
}
}