Hope all is well.
I am getting an error (Error on calling 'OnStateChange' method 'SetStopLoss' cannot be set from this state). However, I am not calling that method from that state at all. Below is my code:
#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion
//This namespace holds Strategies in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Strategies
{
public class InbotRSICrossover : Strategy
{
private ATR _atr;
private int _fastEMA = 10;
private int _mediumEMA = 50;
private int _fastRSI = 6;
private int _slowRSI = 20;
private int _smoothing = 3;
private double _stopLossMultipler = 1;
private double _targetMultipler = 1.4;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"RSI Crossover Strategy with Moving Average Confluence";
Name = "InbotRSICrossover";
Calculate = Calculate.OnBarClose;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
OrderFillResolution = OrderFillResolution.Standard;
Slippage = 0;
StartBehavior = StartBehavior.WaitUntilFlat;
TimeInForce = TimeInForce.Gtc;
TraceOrders = false;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.PerEntryExecution;
BarsRequiredToTrade = 20;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
}
else if (State == State.Configure)
{
AddDataSeries(Data.BarsPeriodType.Minute, 1);
}
else if (State == State.DataLoaded)
{
_atr = ATR(Close, 14);
}
}
protected override void OnBarUpdate()
{
if (CurrentBar > 14)
{
//Add your custom strategy logic here.
if (RSICrossoverShort() && PriceCrossoverShort() && !IsSMABull() && CheckTime() && Position.MarketPosition == MarketPosition.Flat)
EnterShort(1, "entryOrder");
else if (RSICrossoverLong() && PriceCrossoverLong() && IsSMABull() && CheckTime() && Position.MarketPosition == MarketPosition.Flat)
EnterLong(1, "entryOrder");
}
}
protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)
{
// check if the current order matches the orderName passed in "EnterLong"()
// Assign entryOrder in OnOrderUpdate() to ensure the assignment occurs when expected.
// This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not guaranteed to be complete if it is referenced immediately after submitting
if (order.Name == "entryOrder")
{
// if entry order exists
if (order != null && orderState == OrderState.Filled)
{
Print(order.ToString());
// Do something here
//Sets levels
double TakeProfit = 0;
double StopLoss = 0;
if (order.OrderAction == OrderAction.Buy)
{
TakeProfit = Position.AveragePrice + (_targetMultipler * _atr[0]);
StopLoss = Position.AveragePrice - (_atr[0] * _stopLossMultipler);
//StopLoss = MIN(Low,2)[0];
//TakeProfit = Position.AveragePrice + ((Position.AveragePrice - StopLoss) * 1.4);
}
else if (order.OrderAction == OrderAction.SellShort)
{
TakeProfit = Position.AveragePrice - (_targetMultipler * _atr[0]);
StopLoss = Position.AveragePrice + (_atr[0] * _stopLossMultipler);
// StopLoss = MAX(High,2)[0];
//TakeProfit = Position.AveragePrice - ((StopLoss - Position.AveragePrice) * 1.4);
}
else
Print ("ERROR - Order " + order.OrderAction.ToString());
Print(DateTime.Now.ToLongTimeString() + " Entered " + order.OrderAction.ToString() + " position!");
Print("Set Target and Stop Loss Order " + order.OrderAction.ToString() + " Price: " + Position.AveragePrice + " - Target: " + TakeProfit + " - " + " Stop Loss: " + StopLoss + " ATR:" + _atr[0].ToString());
SetProfitTarget(CalculationMode.Price, TakeProfit,true);
SetStopLoss(CalculationMode.Price, StopLoss);
}
}
}
#region Functions
private bool RSICrossoverLong()
{
if (CrossAbove(RSI(_fastEMA,_smoothing), RSI(_slowRSI,_smoothing), 0))
{
return true;
}
else
{
return false;
}
}
private bool RSICrossoverShort()
{
if (CrossBelow(RSI(_fastEMA,_smoothing), RSI(_slowRSI,_smoothing), 0))
{
return true;
}
else
{
return false;
}
}
private bool PriceCrossoverLong()
{
if (CrossAbove(Close, SMA(20), 3))
{
return true;
}
else
{
return false;
}
}
private bool PriceCrossoverShort()
{
if (CrossBelow(Close, SMA(20), 3))
{
return true;
}
else
{
return false;
}
}
private bool CheckTime()
{
/* Checks to see if the time is during the busier hours (format is HHMMSS or HMMSS). Only allow trading if current time is during a busy period.
The timezone used here is (GMT-05:00) EST. */
//if ((ToTime(Time[0]) >= 94500 && ToTime(Time[0]) < 120000) || (ToTime(Time[0]) >= 140000 && ToTime(Time[0]) < 154500))
if ((ToTime(Time[0]) >= 94500 && ToTime(Time[0]) <= 154500))
{
return true;
}
else
return false;
}
public bool IsSMABull()
{
try
{
var ema100 = SMA(100);
double currentPrice = Close[0];
if (currentPrice >= ema100[0])
{
return true;
}
else
{
return false;
}
}
catch(Exception ex)
{
return false;
}
}
#endregion
#region Properties
[NinjaScriptProperty]
[Description("Fast RSI Value")]
[Display(Name="FastRSI", Description="Fast RSI Property", Order=1, GroupName="Parameters")]
public int FastRSI
{
get
{
return _fastRSI;
}
set
{
_fastRSI = value;
}
}
[NinjaScriptProperty]
[Description("Slow RSI Value")]
[Display(Name="SlowRSI", Description="Slow RSI Property", Order=2, GroupName="Parameters")]
public int SlowRSI
{
get
{
return _slowRSI;
}
set
{
_slowRSI = value;
}
}
[NinjaScriptProperty]
[Description("Smoothing Value")]
[Display(Name="SmoothingRSI", Description="Smoothing RSI Property", Order=3, GroupName="Parameters")]
public int SmoothingRSI
{
get
{
return _smoothing;
}
set
{
_smoothing = value;
}
}
[NinjaScriptProperty]
[Description("Stop Loss Multipler")]
[Display(Name="StopLossMultiplerValue", Description="Stop Loss Multipler Property", Order=4, GroupName="Parameters")]
public double StopLossMultipler
{
get
{
return _stopLossMultipler;
}
set
{
_stopLossMultipler = value;
}
}
[NinjaScriptProperty]
[Description("Target Multipler")]
[Display(Name="TargetMultiplerValue", Description="Target Multipler Property", Order=5, GroupName="Parameters")]
public double TargetMultipler
{
get
{
return _targetMultipler;
}
set
{
_targetMultipler = value;
}
}
#endregion
}
}

Comment