Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Max Daily Loss code not working properly

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Max Daily Loss code not working properly

    I used this code https://ninjatrader.com/support/foru...etch?id=910301 That I found here on the forum. I've tried several times to implement the logic contained within it but once I backtest it there a still plenty of days where the loss is way over the set limit.

    Here Is the code, any help will be greatly appreciated because I plan on implementing a max daily loss into many strategies in the future!

    #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 LSMA5 : Strategy
    {
    private NinjaTrader.NinjaScript.Indicators.LizardIndicator s.amaAdaptiveLaguerreFilter amaAdaptiveLaguerreFilter1;
    private SMA SMA1;
    private RSI RSI1;
    private BollingerModified BollingerModified1;
    private RSI RSI2;
    private double currentPnL;

    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"Enter the description for your new custom Strategy here.";
    Name = "LSMA5";
    Calculate = Calculate.OnPriceChange;
    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 = 20;
    // Disable this property for performance gains in Strategy Analyzer optimizations
    // See the Help Guide for additional information
    IsInstantiatedOnEachOptimizationIteration = true;
    BBLength = 20;
    BBDev = 1;
    TrailStop = 50;
    SlowLag = 26;
    SMALength = 100;
    RSILength = 30;
    BuyRSI = 50;
    ShortRSI = 50;
    RSI2Length = 30;
    BuyExit = 80;
    ShortExit = 20;
    LossLimit = 40;
    }
    else if (State == State.Configure)
    {
    }
    else if (State == State.DataLoaded)
    {
    amaAdaptiveLaguerreFilter1 = amaAdaptiveLaguerreFilter(Close, Convert.ToInt32(SlowLag));
    SMA1 = SMA(Close, Convert.ToInt32(SMALength));
    RSI1 = RSI(Close, Convert.ToInt32(RSILength), 3);
    BollingerModified1 = BollingerModified(Close, BBDev, Convert.ToInt32(BBLength), TypeBBMA.SMA, false);
    RSI2 = RSI(Close, Convert.ToInt32(RSI2Length), 3);
    amaAdaptiveLaguerreFilter1.Plots[0].Brush = Brushes.MediumBlue;
    SMA1.Plots[0].Brush = Brushes.Goldenrod;
    RSI1.Plots[0].Brush = Brushes.DodgerBlue;
    RSI1.Plots[1].Brush = Brushes.Goldenrod;
    RSI2.Plots[0].Brush = Brushes.DodgerBlue;
    RSI2.Plots[1].Brush = Brushes.Goldenrod;
    AddChartIndicator(amaAdaptiveLaguerreFilter1);
    AddChartIndicator(SMA1);
    AddChartIndicator(RSI1);
    AddChartIndicator(RSI2);
    SetTrailStop("", CalculationMode.Ticks, TrailStop, false);
    }
    }

    protected override void OnBarUpdate()
    {
    if (BarsInProgress != 0)
    return;

    if (CurrentBars[0] < 1)
    return;
    if (Bars.IsFirstBarOfSession)
    currentPnL = 0;

    // Set 1
    if ((amaAdaptiveLaguerreFilter1[0] > SMA1[0])
    && (IsFirstTickOfBar == true)
    && (Times[0][0].TimeOfDay >= new TimeSpan(8, 30, 0))
    &&(Position.MarketPosition == MarketPosition.Flat && currentPnL > -LossLimit)
    && (Times[0][0].TimeOfDay <= new TimeSpan(15, 30, 0))
    && (CrossAbove(RSI1.Avg, BuyRSI, 1)))
    {
    EnterLong(Convert.ToInt32(DefaultQuantity), "long1");
    }

    // Set 2
    if ((Times[0][0].TimeOfDay >= new TimeSpan(8, 30, 0))
    && (IsFirstTickOfBar == true)
    && (Times[0][0].TimeOfDay <= new TimeSpan(15, 30, 0))
    &&(Position.MarketPosition == MarketPosition.Flat && currentPnL > -LossLimit)
    && (amaAdaptiveLaguerreFilter1[0] < SMA1[0])
    && (CrossBelow(RSI1.Avg, ShortRSI, 1)))
    {
    EnterShort(Convert.ToInt32(DefaultQuantity), "short1");
    }

    // Set 3
    if ((CrossBelow(Close, BollingerModified1.LowerBand, 1))
    || (CrossAbove(RSI2.Avg, BuyExit, 1)))
    {
    ExitLong(Convert.ToInt32(DefaultQuantity), "LTP", "");
    }

    // Set 4
    if ((CrossAbove(Close, BollingerModified1.LowerBand, 1))
    || (CrossBelow(RSI2.Avg, ShortExit, 1)))
    {
    ExitShort(Convert.ToInt32(DefaultQuantity), "STP", "");
    }







    // if in a position and the realized day's PnL plus the position PnL is greater than the loss limit then exit the order
    if (Position.MarketPosition == MarketPosition.Long
    && (currentPnL + Position.GetUnrealizedProfitLoss(PerformanceUnit.C urrency, Close[0])) <= -LossLimit)
    {
    //Print((currentPnL+Position.GetProfitLoss(Close[0], PerformanceUnit.Currency)) + " - " + -LossLimit);
    // print to the output window if the daily limit is hit in the middle of a trade
    Print("daily limit hit, exiting order " + Time[0].ToString());
    ExitLong("Daily Limit Exit", "long1");
    }


    if (Position.MarketPosition == MarketPosition.Long
    && (currentPnL + Position.GetUnrealizedProfitLoss(PerformanceUnit.C urrency, Close[0])) <= -LossLimit)
    {
    //Print((currentPnL+Position.GetProfitLoss(Close[0], PerformanceUnit.Currency)) + " - " + -LossLimit);
    // print to the output window if the daily limit is hit in the middle of a trade
    Print("daily limit hit, exiting order " + Time[0].ToString());
    ExitShort("Daily Limit Exit", "short1");
    }
    }

    protected override void OnPositionUpdate(Position position, double averagePrice, int quantity, MarketPosition marketPosition)
    {
    if (Position.MarketPosition == MarketPosition.Flat && SystemPerformance.AllTrades.Count > 0)
    {
    // when a position is closed, add the last trade's Profit to the currentPnL
    currentPnL += SystemPerformance.AllTrades[SystemPerformance.AllTrades.Count - 1].ProfitCurrency;

    // print to output window if the daily limit is hit
    if (currentPnL <= -LossLimit)
    {
    Print("daily limit hit, no new orders" + Time[0].ToString());
    }
    }
    }

    #region Properties

    [NinjaScriptProperty]
    [Range(0, double.MaxValue)]
    [Display(ResourceType = typeof(Custom.Resource), Name="LossLimit", Description="Amount of dollars of acceptable loss", Order=1, GroupName="NinjaScriptStrategyParameters")]
    public double LossLimit
    { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name="BBLength", Order=1, GroupName="Parameters")]
    public int BBLength
    { get; set; }


    [NinjaScriptProperty]
    [Range(1, double.MaxValue)]
    [Display(Name="BBDev", Order=2, GroupName="Parameters")]
    public double BBDev
    { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name="TrailStop", Order=3, GroupName="Parameters")]
    public int TrailStop
    { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name="SlowLag", Order=4, GroupName="Parameters")]
    public int SlowLag
    { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name="SMALength", Order=5, GroupName="Parameters")]
    public int SMALength
    { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name="RSILength", Order=6, GroupName="Parameters")]
    public int RSILength
    { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name="BuyRSI", Order=7, GroupName="Parameters")]
    public int BuyRSI
    { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name="ShortRSI", Order=8, GroupName="Parameters")]
    public int ShortRSI
    { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name="RSI2Length", Order=9, GroupName="Parameters")]
    public int RSI2Length
    { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name="BuyExit", Order=10, GroupName="Parameters")]
    public int BuyExit
    { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name="ShortExit", Order=11, GroupName="Parameters")]
    public int ShortExit
    { get; set; }
    #endregion

    }
    }

    #2
    Hello Akotic,

    Welcome to the NinjaTrader forums!

    Print currentPnL and LossLimit to the output window and enable TraceOrders.


    Are you seeing new orders after currentPnL is equal to or greater than LossLimit?

    Please include the output saved to a text file.
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      I'm just curious if you figured out the issue and got this to work. I'm looking for pretty much the same thing but having trouble finding it.

      Comment


        #4
        No I still haven’t figured it out. I was hoping that someone experienced in C# would basically be able to look at the code and see if it’s correct or where the coding errors are at.

        Comment


          #5
          Hello Akotic,

          This thread will remain open for any community members that would like to debug your code as a convience to you.

          I am happy to assist you with walking you through the debugging process so that you can understand and correct the code.

          You can also contact a professional NinjaScript Consultant who would be eager to create or modify this script at your request or assist you with your script. The NinjaTrader Ecosystem has affiliate contacts who provide educational as well as consulting services. Please let me know if you would like our NinjaTrader Ecosystem team follow up with you with a list of affiliate consultants who would be happy to create this script or any others at your request or provide one on one educational services.
          Chelsea B.NinjaTrader Customer Service

          Comment

          Latest Posts

          Collapse

          Topics Statistics Last Post
          Started by NullPointStrategies, Today, 05:17 AM
          0 responses
          50 views
          0 likes
          Last Post NullPointStrategies  
          Started by argusthome, 03-08-2026, 10:06 AM
          0 responses
          126 views
          0 likes
          Last Post argusthome  
          Started by NabilKhattabi, 03-06-2026, 11:18 AM
          0 responses
          69 views
          0 likes
          Last Post NabilKhattabi  
          Started by Deep42, 03-06-2026, 12:28 AM
          0 responses
          42 views
          0 likes
          Last Post Deep42
          by Deep42
           
          Started by TheRealMorford, 03-05-2026, 06:15 PM
          0 responses
          46 views
          0 likes
          Last Post TheRealMorford  
          Working...
          X