The code works about 90 percent of time. The issue is that it shorts when it is above RSI threshold, when it suppose to be either flat or short.
Your help is greatly appreciated!
------------
private EMA EMA1;
private RSI RSI1;
private bool OnePerBar = false;
private double TickValue;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Custom Strategy with USD-based Take Profit and Stop Loss.";
Name = "OrodorotStrategyV2";
Calculate = Calculate.OnEachTick;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
OrderFillResolution = OrderFillResolution.Standard;
Slippage = 0;
StartBehavior = StartBehavior.WaitUntilFlat;
TimeInForce = TimeInForce.Gtc;
TraceOrders = false;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.PerEntryExecution;
BarsRequiredToTrade = 20;
IsInstantiatedOnEachOptimizationIteration = true;
Contracts = 1;
Long = true;
Short = true;
TakeProfitUSD = 155;
StopLossUSD = 47;
EMALength = 3;
RSILength = 14;
RSIThresholdLong = 60;
RSIThresholdShort = 40;
}
else if (State == State.Configure)
{
}
else if (State == State.DataLoaded)
{
EMA1 = EMA(Close, EMALength);
RSI1 = RSI(Close, RSILength, 3);
EMA1.Plots[0].Brush = Brushes.Blue;
RSI1.Plots[0].Brush = Brushes.Gray;
RSI1.Plots[1].Brush = Brushes.Transparent;
AddChartIndicator(EMA1);
AddChartIndicator(RSI1);
// Calculate Tick Value
TickValue = Instrument.MasterInstrument.PointValue / TickSize;
// Stops & Targets
SetProfitTarget(@"Long", CalculationMode.Ticks, (int)(TakeProfitUSD / TickValue));
SetStopLoss(@"Long", CalculationMode.Ticks, (int)(StopLossUSD / TickValue), false);
SetProfitTarget(@"Short", CalculationMode.Ticks, (int)(TakeProfitUSD / TickValue));
SetStopLoss(@"Short", CalculationMode.Ticks, (int)(StopLossUSD / TickValue), false);
}
}
protected override void OnBarUpdate()
{
if (BarsInProgress != 0)
return;
if (CurrentBars[0] < EMALength + 1 || CurrentBars[0] < RSILength + 1 || CurrentBars[0] < BarsRequiredToTrade + 1)
return;
// Reset bool
if (IsFirstTickOfBar)
{
OnePerBar = false;
}
// Entry
if (Position.MarketPosition == MarketPosition.Flat && !OnePerBar)
{
// Long
if (Long && Close[1] > EMA1[1] && RSI1.Default[1] > RSIThresholdLong && Close[1] > Open[1] && Close[0] > Close[1])
{
EnterLong(Convert.ToInt32(Contracts), @"LONG");
OnePerBar = true;
}
// Short
if (Short && Close[1] < EMA1[1] && RSI1.Default[1] < RSIThresholdShort && Close[1] < Open[1] && Close[0] < Close[1])
{
EnterShort(Convert.ToInt32(Contracts), @"SHORT");
OnePerBar = true;
}
}
// Exits
if (Position.MarketPosition == MarketPosition.Long)
{
// Exit Long
if (Close[1] < EMA1[1] || Close[0] < Low[1] || Close[1] < Open[1])
{
ExitLong(Convert.ToInt32(Contracts), @"ExitLong", @"LONG");
}
}
if (Position.MarketPosition == MarketPosition.Short)
{
// Exit Short
if (Close[1] > EMA1[1] || Close[0] > High[1] || Close[1] > Open[1])
{
ExitShort(Convert.ToInt32(Contracts), @"ExitShort", @"SHORT");
}
}
}
region Properties
[NinjaScriptProperty]
[Range(1, int.MaxValue)]
[Display(Name = "Contracts", Order = 1, GroupName = "Parameters")]
public int Contracts
{ get; set; }
[NinjaScriptProperty]
[Display(Name = "Long", Order = 2, GroupName = "Parameters")]
public bool Long
{ get; set; }
[NinjaScriptProperty]
[Display(Name = "Short", Order = 3, GroupName = "Parameters")]
public bool Short
{ get; set; }
[NinjaScriptProperty]
[Range(1, double.MaxValue)]
[Display(Name = "Take Profit (USD)", Order = 4, GroupName = "Parameters")]
public double TakeProfitUSD
{ get; set; }
[NinjaScriptProperty]
[Range(1, double.MaxValue)]
[Display(Name = "Stop Loss (USD)", Order = 5, GroupName = "Parameters")]
public double StopLossUSD
{ get; set; }
[NinjaScriptProperty]
[Range(1, int.MaxValue)]
[Display(Name = "EMA Length", Order = 6, GroupName = "Parameters")]
public int EMALength
{ get; set; }
[NinjaScriptProperty]
[Range(1, int.MaxValue)]
[Display(Name = "RSI Length", Order = 7, GroupName = "Parameters")]
public int RSILength
{ get; set; }
[NinjaScriptProperty]
[Range(0, 100)]
[Display(Name = "RSI Threshold Long <", Order = 8, GroupName = "Parameters")]
public int RSIThresholdLong
{ get; set; }
[NinjaScriptProperty]
[Range(0, 100)]
[Display(Name = "RSI Threshold Short >", Order = 9, GroupName = "Parameters")]
public int RSIThresholdShort
{ get; set; }
#endregion
}
}
