Algorithmic Trading with NinjaTrader
Hello,
I have a EMA cross strategy that for some reason only takes the first trade on the chart. I've tried to debug so many times. Anyone else see why?
#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;
using NinjaTrader.CQG.ProtoBuf;
#endregion
//This namespace holds Strategies in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Strategies
{
public class LongEMACrossoverStrategy : Strategy
{
private EMA _fast;
private EMA _slow;
private bool _inPosition;
private Cbi.Order _longOrder;
private Cbi.Order _stopTrailOrder;
private bool _isOnBreakEven = false;
private bool _isOnTrail = false;
private string _longSignal = "Long";
private string _stopTrailSignal = "Trail Stop";
private int _trailTicks;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Enter the description for your new custom Strategy here.";
Name = "Long EMA CrossoverStrategy";
Calculate = Calculate.OnEachTick;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 240;
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 = 10;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
IsUnmanaged = true;
DaysToLoad = 10;
BreakevenTiks = 20;
EnableTrailTicks = 30;
_inPosition = false;
TrailStep = 2;
Fast = 20;
Slow = 60;
_trailTicks = 0;
}
else if (State == State.Configure)
{
}
else if ( State == State.DataLoaded)
{
_fast = EMA(Convert.ToInt32(Fast));
_slow = EMA(Convert.ToInt32(Slow));
_fast.Plots[0].Brush = Brushes.LimeGreen;
_slow.Plots[0].Brush = Brushes.DarkViolet;
AddChartIndicator(_fast);
AddChartIndicator(_slow);
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < BarsRequiredToTrade)
return;
Log("Fast: " + EMA(Fast)[1], LogLevel.Information);
Log("Slow: " + EMA(Slow)[1], LogLevel.Information);
if (CrossAbove(EMA(Fast), EMA(Slow), 1) && !_inPosition)
{
SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.Market, 1, 0, 0, "", _longSignal);
_inPosition = true;
}
if(_inPosition)
{
Log("Tiks: " + Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]), LogLevel.Information);
if (Position.GetUnrealizedProfitLoss(PerformanceUnit.Currency, Close[0]) <= -300)
{
Cancel();
_inPosition =false;
}
if (Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]) >= BreakevenTiks && !_isOnBreakEven)
{
SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.MIT, 1, 0, Position.AveragePrice, "", _stopTrailSignal);
_isOnBreakEven = true;
}
if (Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]) >= EnableTrailTicks + _trailTicks)
{
_trailTicks += TrailStep;
ChangeOrder(_stopTrailOrder, 1, 0, _stopTrailOrder.StopPrice + TrailStep * Instrument.MasterInstrument.TickSize);
_isOnTrail = true;
}
}
}
private void Cancel()
{
_isOnTrail = false;
_isOnBreakEven = false;
_inPosition = false;
_trailTicks = 0;
if (_longOrder != null)
{
CancelOrder(_longOrder);
}
if(_stopTrailOrder != null)
{
CancelOrder(_stopTrailOrder);
}
}
protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string comment)
{
if (order.Name.Equals(_longSignal) && orderState == OrderState.Filled)
{
_longOrder = order;
}
if (order.Name.Equals(_longSignal) && orderState == OrderState.Cancelled)
{
Cancel();
_longOrder = null;
}
if (order.Name.Equals(_stopTrailSignal) && orderState == OrderState.Submitted)
{
_stopTrailOrder = order;
}
if (order.Name.Equals(_stopTrailOrder) && orderState == OrderState.Filled)
{
Cancel();
_stopTrailOrder = null;
}
}
#region Properties
[Range(1, int.MaxValue), NinjaScriptProperty]
[Display(ResourceType = typeof(Custom.Resource), Name = "Fast", GroupName = "NinjaScriptStrategyParameters", Order = 0)]
public int Fast
{ get; set; }
[Range(1, int.MaxValue), NinjaScriptProperty]
[Display(ResourceType = typeof(Custom.Resource), Name = "Slow", GroupName = "NinjaScriptStrategyParameters", Order = 1)]
public int Slow
{ get; set; }
[DefaultValue(2)]
[Range(1, int.MaxValue), NinjaScriptProperty]
[Display(ResourceType = typeof(Custom.Resource), Name = "TrailStep", GroupName = "NinjaScriptStrategyParameters", Order = 2)]
public int TrailStep
{ get; set; }
[DefaultValue(OrderAction.Buy)]
[Display(ResourceType = typeof(Custom.Resource), Name = "Initiali order type", GroupName = "NinjaScriptStrategyParameters", Order = 3)]
public OrderAction Action { get; set; }
[DefaultValue(true)]
[Display(ResourceType = typeof(Custom.Resource), Name = "Enable Trail Tick", GroupName = "NinjaScriptStrategyParameters", Order = 4)]
public int EnableTrailTicks { get; set; }
[DefaultValue(20)]
[Range(1, int.MaxValue), NinjaScriptProperty]
[Display(ResourceType = typeof(Custom.Resource), Name = "Breakeven Tiks", GroupName = "NinjaScriptStrategyParameters", Order = 5)]
public int BreakevenTiks { get; set; }
#endregion
}
public class ShortEMACrossoverStrategy : Strategy
{
private EMA _fast;
private EMA _slow;
private bool _inPosition;
private Cbi.Order _longOrder;
private Cbi.Order _stopTrailOrder;
private bool _isOnBreakEven = false;
private bool _isOnTrail = false;
private string _longSignal = "Long";
private string _stopTrailSignal = "Trail Stop";
private int _trailTicks;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Enter the description for your new custom Strategy here.";
Name = "Short EMA CrossoverStrategy";
Calculate = Calculate.OnEachTick;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 240;
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 = 10;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
IsUnmanaged = true;
DaysToLoad = 1;
BreakevenTiks = 20;
EnableTrailTicks = 30;
_inPosition = false;
TrailStep = 2;
Fast = 20;
Slow = 60;
_trailTicks = 0;
}
else if (State == State.Configure)
{
}
else if (State == State.DataLoaded)
{
_fast = EMA(Convert.ToInt32(Fast));
_slow = EMA(Convert.ToInt32(Slow));
_fast.Plots[0].Brush = Brushes.LimeGreen;
_slow.Plots[0].Brush = Brushes.DarkViolet;
AddChartIndicator(_fast);
AddChartIndicator(_slow);
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < BarsRequiredToTrade)
return;
if (CrossBelow(EMA(Fast), EMA(Slow), 1) && !_inPosition)
{
Log("Cross Below: " + CrossBelow(EMA(Fast), EMA(Slow), 1), LogLevel.Information);
SubmitOrderUnmanaged(0, OrderAction.Sell, OrderType.Market, 1, 0, 0, "", _longSignal);
Log("Enter position", LogLevel.Information);
_inPosition = true;
}
if (_inPosition)
{
Log("Tiks: " + Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]), LogLevel.Information);
if (Position.GetUnrealizedProfitLoss(PerformanceUnit.Currency, Close[0]) <= -300 && Position.MarketPosition != MarketPosition.Flat)
{
Cancel();
_inPosition = false;
}
if (Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]) >= BreakevenTiks && !_isOnBreakEven && Position.MarketPosition != MarketPosition.Flat)
{
SubmitOrderUnmanaged(0, OrderAction.BuyToCover, OrderType.MIT, 1, 0, Position.AveragePrice, "", _stopTrailSignal);
_isOnBreakEven = true;
}
if (Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]) >= EnableTrailTicks + _trailTicks && Position.MarketPosition != MarketPosition.Flat)
{
_trailTicks += TrailStep;
Log("Trail " + _stopTrailOrder.StopPrice + TrailStep * Instrument.MasterInstrument.TickSize, LogLevel.Information);
ChangeOrder(_stopTrailOrder, 1, 0, _stopTrailOrder.StopPrice + TrailStep * Instrument.MasterInstrument.TickSize);
_isOnTrail = true;
}
}
}
private void Cancel()
{
_isOnTrail = false;
_isOnBreakEven = false;
_inPosition = false;
_trailTicks = 0;
if (_longOrder != null)
{
CancelOrder(_longOrder);
}
if (_stopTrailOrder != null)
{
CancelOrder(_stopTrailOrder);
}
}
protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string comment)
{
if (order.Name.Equals(_longSignal) && orderState == OrderState.Filled)
{
_longOrder = order;
}
if (order.Name.Equals(_longSignal) && orderState == OrderState.Cancelled)
{
Cancel();
_longOrder = null;
}
if (order.Name.Equals(_stopTrailSignal) && orderState == OrderState.Submitted)
{
_stopTrailOrder = order;
}
if(order.Name.Equals(_stopTrailOrder) && orderState == OrderState.Filled)
{
Cancel();
_stopTrailOrder = null;
}
}
#region Properties
[Range(1, int.MaxValue), NinjaScriptProperty]
[Display(ResourceType = typeof(Custom.Resource), Name = "Fast", GroupName = "NinjaScriptStrategyParameters", Order = 0)]
public int Fast
{ get; set; }
[Range(1, int.MaxValue), NinjaScriptProperty]
[Display(ResourceType = typeof(Custom.Resource), Name = "Slow", GroupName = "NinjaScriptStrategyParameters", Order = 1)]
public int Slow
{ get; set; }
[DefaultValue(2)]
[Range(1, int.MaxValue), NinjaScriptProperty]
[Display(ResourceType = typeof(Custom.Resource), Name = "TrailStep", GroupName = "NinjaScriptStrategyParameters", Order = 2)]
public int TrailStep
{ get; set; }
[DefaultValue(OrderAction.Buy)]
[Display(ResourceType = typeof(Custom.Resource), Name = "Initiali order type", GroupName = "NinjaScriptStrategyParameters", Order = 3)]
public OrderAction Action { get; set; }
[DefaultValue(true)]
[Display(ResourceType = typeof(Custom.Resource), Name = "Enable Trail Tick", GroupName = "NinjaScriptStrategyParameters", Order = 4)]
public int EnableTrailTicks { get; set; }
[DefaultValue(20)]
[Range(1, int.MaxValue), NinjaScriptProperty]
[Display(ResourceType = typeof(Custom.Resource), Name = "Breakeven Tiks", GroupName = "NinjaScriptStrategyParameters", Order = 5)]
public int BreakevenTiks { get; set; }
#endregion
}
}