I've tryied to set up the SL and TP. I was able to set up the SL, but when i try to place the TP I'm getting some errors as value 0 or values without sense. Also as you can see on the screenshot, I've tryied to make a backtest on the strategy, and when and order is being placed, it tries to place it several times with different TP values (thing that I don't understand).
Note: I'm trying to place the TP on a 1:1 ratio, same distance to the entryPrice as the SL
Here I provide the code that I'm using.
namespace NinjaTrader.NinjaScript.Strategies
{
public class Zone {
public double Max { get; set; }
public double Min { get; set; }
public double long_or_short { get; set; } // 1 long and 0 short
public DateTime timestamp { get; set; }
public double middleCandleMax { get; set; }
public double middleCandleMin { get; set; }
}
public class FVGStrategy : Strategy
{
private double stopLossTicks = 2; // Default value, should be dynamically calculated
private double takeProfitFactor = 1.5; // Default R:R ratio;
private double riskPercentage = 1.0; // Default risk percentage
double candleCounter = 0;
double SL;
double entryPrice;
List<Zone> zones = new List<Zone>();
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Enter the description for your new custom Strategy here.";
Name = "FVGStrategy";
Calculate = Calculate.OnBarClose;
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 = 4;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
}
else if (State == State.Configure)
{
}
}
protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string comment){
Print("----------------------------------------------");
Print(Time[0]);
Print("Entry --> " + entryPrice);
Print("SL --> "+ SL);
SetStopLoss(CalculationMode.Price, SL);
if (order.IsLong){
double distance = (entryPrice - stopPrice) * 1; // ratio 1:1
double takeProfitPrice = entryPrice + distance;
SetProfitTarget(CalculationMode.Price, takeProfitPrice);
Print("TP --> "+ takeProfitPrice);
}
else if (order.IsShort){
double distance = (entryPrice - stopPrice) * 1; // ratio 1:1
double takeProfitPrice = entryPrice - distance;
SetProfitTarget(CalculationMode.Price, takeProfitPrice);
Print("TP --> "+ takeProfitPrice);
}
}
// Called on each bar update event
protected override void OnBarUpdate()
{
// Ensure that at least 5 candles have occurred
if (CurrentBar < 4)
{
return; // Skip the rest of the code if fewer than 5 bars have formed
}
// CLEAR ZONES IF END OF DAY
if (Time[0].TimeOfDay == new TimeSpan(00, 00, 00)){
for(int i = 0; i < zones.Count; i++){
Print(zones[i].timestamp + " --> ZONA" + zones[i].long_or_short);
}
zones.Clear();
return;
}
// DEFINING THE ZONES
full_FVG();
reversal_FVG();
opposite_Reversal_SVG();
hesitant_FVG();
// CHECKING IF THERE'S AN ENTRY
for (int i = 0; i < zones.Count; i++){
if((High[0] > zones[i].Min) || (Low[0] < zones[i].Max)){
if(zones[i].long_or_short == 0){
EnterTrade(0, zones[i]);
}
else if(zones[i].long_or_short == 1){
EnterTrade(1, zones[i]);
}
// we remove the zone
zones.RemoveAt(i);
}
}
}
// Logic for entering a trade
private void EnterTrade(int BuyOrSell, Zone zones)
{
// Determine trade size based on risk and stop loss
double tradeSize = CalculateTradeSize();
entryPrice = Close[0];
// long
if(BuyOrSell == 1){
SL = zones.middleCandleMin - (2*TickSize);
EnterLong(1);
}
// short
if(BuyOrSell == 0){
SL = zones.middleCandleMax + (2*TickSize);
EnterShort(1);
}
}
// Calculate trade size based on risk management
private double CalculateTradeSize()
{
// Calculate the size of the trade based on the risk percentage and account size
//double accountRisk = AccountSize * riskPercentage / 100;
double accountRisk = 10000 * riskPercentage / 100;
double tradeRisk = stopLossTicks * TickSize;
return accountRisk / tradeRisk;
}
}
}
Any idea on how can I solve the issue?
Thanks in advance for your time.

Comment