the following is very basic code, if open is greater tahn close, it would be long with oco orders of stoploss and profitlimit
region Using declarations
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using NinjaTrader.Cbi;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.Strategies;
#endregion
namespace NinjaTrader.NinjaScript.Strategies
{
public class OpenCloseLongOnlyStrategy : Strategy
{
private Order entryOrder = null;
private Order stopOrder = null;
private Order targetOrder = null;
private double stopPrice;
private double targetPrice;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = "Enters a long position based on Open vs Close price comparison.";
Name = "OpenCloseLongOnlyStrategy";
Calculate = Calculate.OnBarClose;
IsOverlay = true;
BarsRequiredToTrade = 20;
PositionSize = 1; // Default position size
}
}
[NinjaScriptProperty]
[Range(1, int.MaxValue)]
[Display(Name = "Position Size", Description = "Number of contracts/shares per trade", Order = 1, GroupName = "Parameters")]
public int PositionSize { get; set; }
protected override void OnBarUpdate()
{
if (CurrentBar < BarsRequiredToTrade) return; // Wait for enough bars
if (Position.MarketPosition == MarketPosition.Flat)
{
// Check the condition to enter a long position
if (Open[0] < Close[0]) // Current bar where open is less than close
{
// Long setup
Print($"Long Setup - Open: {Open[0]}, Close: {Close[0]}");
stopPrice = Low[1] - 3 * TickSize; // Stop is 3 ticks below previous bar's low
targetPrice = Close[0] + 20 * TickSize; // Target is 20 ticks above the entry price
// Enter long position with limit order at close price of the current bar
entryOrder = EnterLongLimit(PositionSize, Close[0], "Entry");
// Set OCO group for stop and target
stopOrder = ExitLongStopMarket(PositionSize, stopPrice, "StopLoss", "Entry");
targetOrder = ExitLongLimit(PositionSize, targetPrice, "Target", "Entry");
Print($"Long Entry Price: {Close[0]}, Stop: {stopPrice}, Target: {targetPrice}");
}
}
}
protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice,
int quantity, int filled, double averageFillPrice,
OrderState orderState, DateTime time, ErrorCode error, string nativeError)
{
if (orderState == OrderState.Filled)
{
Print($"Order {order.Name} Filled: {order.OrderAction} {quantity} at {averageFillPrice}");
// Reset entry order reference on fill to allow new order entry
if (order == entryOrder)
{
entryOrder = null;
}
}
}
protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity,
MarketPosition marketPosition, string orderId, DateTime time)
{
if (marketPosition == MarketPosition.Flat)
{
// When position is closed, clear the order references
entryOrder = null;
stopOrder = null;
targetOrder = null;
Print($"Position closed at {price} on {time}");
}
}
}
}

Comment