I am trying to create a range base grid strategy and I receive the error message "'Exceeded entry signals limit based on EntryHandling and EntriesPerDirection properties" in the output frequently.
The concept I'm trying to program is to have the fill of a buy or sell limit order create new buy and sell limits above and below in discrete intervals. This creates a grid of buys and sells as the price moves in the range of the grid. The issue I'm having is that eventually new limit orders will not be created and instead give the error message above. Also depending on the EntriesPerDirection quantity my initial entry order quantity will be a variety of factors larger than what is set in the strategy. Ideally the strategy maintains a position until the position is manually closed, having various position quantities depending on the prices location in the grid.
Here is my script for reference, I appreciate any help offered.
Erik
#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 GridStrategy : Strategy
{
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Enter the description for your new custom Strategy here.";
Name = "GridStrategy";
Calculate = Calculate.OnBarClose;
EntriesPerDirection = 5;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = false;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
OrderFillResolution = OrderFillResolution.Standard;
Slippage = 0;
StartBehavior = StartBehavior.WaitUntilFlat;
TimeInForce = TimeInForce.Gtc;
TraceOrders = true;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.ByStrategyPosition;
BarsRequiredToTrade = 20;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
GridSize = 50;
EntryPrice = 16200;
}
}
protected override void OnBarUpdate()
{
if (State == State.Historical)
return;
if (BarsInProgress != 0)
return;
if (CurrentBars[0] < 1)
return;
if (Position.MarketPosition == MarketPosition.Flat)
{
EnterLongLimit(1, EntryPrice, "Level0");
}
}
protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError)
{
Print(order.Name);
Print(order.OrderState);
}
protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
{
Print(execution);
Print(execution.Name);
Print(Position.Quantity);
if(execution.Name == "LevelM2")
{
{
ExitLongLimit(0, true, 1, EntryPrice - GridSize * TickSize, "LevelM1", "LevelM2");
}
}
if (execution.Name == "LevelM1")
{
{
EnterLongLimit(0, true, 1, EntryPrice - GridSize * 2 * TickSize, "LevelM2");
ExitLongLimit(0, true, 1, EntryPrice, "Level0", "LevelM1");
}
}
if (execution.Name == "Level0")
{
{
ExitLongLimit(0, true, 1, EntryPrice + GridSize * TickSize, "Level1", "Level0");
EnterLongLimit(0, true, 1, EntryPrice - GridSize * TickSize, "LevelM1");
}
}
if (execution.Name == "Level1")
{
{
ExitLongLimit(0, true, 1, EntryPrice + GridSize * 2 * TickSize, "Level2", "Level1");
EnterLongLimit(0, true, 1, EntryPrice, "Level0");
}
}
if (execution.Name == "Level2");
{
{
EnterLongLimit(0, true, 1, EntryPrice + GridSize * TickSize, "Level1");
}
}
}
#region Properties
[NinjaScriptProperty]
[Range(0, int.MaxValue)]
[Display(Name="GridSize", Order=1, GroupName="Parameters")]
public int GridSize
{ get; set; }
[NinjaScriptProperty]
[Range(0, int.MaxValue)]
[Display(Name="EntryPrice", Order=1, GroupName="Parameters")]
public int EntryPrice
{ get; set; }
#endregion
}
}
Comment