You are on page 1of 3

// Short RSI Thrust

// inspired by Laurens Bensdorp's book "Automated Stock Trading System"


// Please read the book to get the full picture.

using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using finantic.Indicators;

// Universe: NYSE, NASDAQ and AMEX


// Position Sizing: 2% risk, 10% size, max 10 positions

namespace WealthScript10
{
public class MyStrategy : UserStrategyBase
{
public MyStrategy() : base()
{
// Book: 4.0 WS: 4.8
AddParameter("Entry Limit %", ParameterType.Double, 4.8, 1.0,
4.0, 0.1); // 0
// Book: 90.0 WS: 77
AddParameter("RSI Limit", ParameterType.Double, 77, 50.0, 90.0,
1.0); // 1
// Book: 4.0 WS:3.0
AddParameter("Profit %", ParameterType.Double, 3.0, 1.0, 4.5,
0.1); // 2
}

public override void Initialize(BarHistory bars)


{
entryLimitPct = Parameters[0].AsDouble;
rsiLimit = Parameters[1].AsDouble;
profitPct = Parameters[2].AsDouble;

//--- Indicators ---


avgTurnover = new AvgTurnover(bars, 20);
atr10 = new ATR(bars, 10);
rsi3 = new RSI(bars.Close, 3);
adx7 = new ADX(bars, 7);
StartIndex = 20;

//--- Graphics ---


PlotIndicator(rsi3, WLColor.Cyan, paneTag: "RSI");
DrawHorzLine(rsiLimit, WLColor.Red, paneTag: "RSI");
PlotStopsAndLimits(dotSize: 3);
}

public override void Execute(BarHistory bars, int idx)


{
//=== Exit ===
Position p = LastOpenPosition;
if (p != null)
{
// Stop Loss
double stop = p.EntryPrice + 3.0 * atr10[p.EntryBar];
ClosePosition(p, OrderType.Stop, stop, "Stop Loss@" +
stop.ToString("f2"));
if (p.IsOpen)
{
// Profit taking: 4%
Double prPct = p.ProfitPctAsOf(idx);
if(prPct > profitPct) // 4.0
{
ClosePosition(p, OrderType.MarketClose, 0.0,
"Take Profit, ProfitPct=" +
prPct.ToString("f2"));
}
}
if (p.IsOpen)
{
// Time based exit: two days
if (idx - p.EntryBar >= 2)
{
ClosePosition(p, OrderType.MarketClose, 0.0,
"Timeout");
}
}
}

//=== Entry ===


// One position per symbol
if (p != null && p.IsOpen) return;

// check data
if(Double.IsNaN(atr10[idx]) || Double.IsNaN(rsi3[idx]) ||
Double.IsNaN(adx7[idx]) ||
Double.IsNaN(avgTurnover[idx])) return;

//--- Filter ---


// Minimum Price
if(bars.Close[idx] < 5.0) return;
// Average daily dollar volume
if(avgTurnover[idx] < 25e6) return;
// sufficient volatility
if(atr10[idx] < bars.Close[idx] * 0.03) return;

//-- Differentiator DO NOT OPTIMIZE


// RSI above ninety
if(rsi3[idx] <= rsiLimit) return; // 90.0

//--- Setup ---


// The last two days the close was higher than the previous day
if(bars.Close[idx] <= bars.Close[idx-1]) return;
if(bars.Close[idx-1] <= bars.Close[idx-2]) return;

// sell short four percent above previous close


Double limit = bars.Close[idx] * (1.0 + entryLimitPct / 100.0);
// 4
Transaction t = PlaceTrade(bars, TransactionType.Short,
OrderType.Limit, limit,
"Short Limit@" + limit.ToString("f2"));
//--- Ranking ---
//t.Weight = adx7[idx];
}

public override double GetMaxRiskStopLevel(BarHistory bars,


PositionType pt, int idx)
{
Double limit = bars.Close[idx] * (1.0 + entryLimitPct / 100.0);
double stop = limit + 3.0 * atr10[idx];
return stop;
}

// private variables
Double profitPct, entryLimitPct, rsiLimit;
IndicatorBase avgTurnover, atr10, rsi3, adx7;
}
}

You might also like