Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Rounding down not working (math.truncate, math.floor)

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

    Rounding down not working (math.truncate, math.floor)

    I have a Ninja script for a strategy. The strategy places orders automatically when criteria is met. However, it is not fully respecting the math.truncate or math.floor functions to round down the position size. Position size is calculated almost accurately but whenever the position size calculation results in a decimal answer like 9.33, it will place order with 10. I also noticed that a position size calculation was 12.5 and it placed order with 12 which was correct. But more often than not, it is not rounding down, especially when the stop distance is small. Can somebody help?

    The calculations are for $MNQ symbol where one tick is 0.25 and value for one tick is $0.50.

    Search for "// Calculate the position size based on the dollar risk​" code section.

    Code:
    #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
    
    namespace NinjaTrader.NinjaScript.Strategies
    {
        public class orderblockshort : Strategy
        {
            private int merkbar = 0;
            private bool signal = true;
            private bool exitsignal = false;
            private bool positionClosedOnBar = false; // New flag to track if a position was closed on the current bar
            private double entryprice = 0.0;
            private double stopprice = 0.0;
            private double profitTarget = 0.0;
            private bool entrybedingung = false;
            private Order entryOrder = null;
    
            [NinjaScriptProperty]
            [Range(0, double.MaxValue)]
            [Display(Name="Dollar Risk", Description="The dollar risk per trade", Order=1)]
            public double DollarRisk { get; set; }
    
            [NinjaScriptProperty]
            [Range(0, double.MaxValue)]
            [Display(Name="Entry Offset", Description="Offset in ticks for limit entry price", Order=2)]
            public int EntryOffset { get; set; }
    
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description = @"Enter the description for your new custom Strategy here.";
                    Name = "orderblockshort";
                    Calculate = Calculate.OnEachTick;
                    EntriesPerDirection = 3;
                    EntryHandling = EntryHandling.UniqueEntries;
                    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;
                    IsInstantiatedOnEachOptimizationIteration = true;
                    signal = true;
                    exitsignal = false;
                    entrybedingung = false;
                    entryprice = 0.0;
                    stopprice = 0.0;
                    profitTarget = 0.0;
                    positionClosedOnBar = false; // Initialize the new flag
                    EntryOffset = 1; // Default to 1 tick
                    DollarRisk = 100; // Default dollar risk
                }
                else if (State == State.Configure)
                {
                }
                else if (State == State.DataLoaded)
                {                
                    SetProfitTarget("short1", CalculationMode.Ticks, 160);
                }
            }
    
            protected override void OnBarUpdate()
            {
                if (BarsInProgress != 0)
                    return;
    
                if (CurrentBars[0] < 1)
                    return;
                
                // Cancel order if condition for cancellation occurs
                if ((State == State.Realtime) && Open[1] < Close[1])
                {
                    exitsignal = false;
                    entrybedingung = false;
                    return;
                }
    
                if (signal == false)
                    return;
    
                // Reset the flag on each new bar
                if (CurrentBar != merkbar)
                {
                    positionClosedOnBar = false;
                    merkbar = CurrentBar;
                }
                
                if ((State == State.Realtime)
                    && (Position.MarketPosition == MarketPosition.Flat)
                    && Open[2] < Close[2]
                    && entrybedingung == false)
                {
                    entrybedingung = true;
                    entryprice = Low[2];
                    stopprice = High[2];
                }
                
                if (entrybedingung == true && High[ 1] > stopprice) stopprice = High[1];
    
                if ((State == State.Realtime)
                    && (Position.MarketPosition == MarketPosition.Flat)
                    && signal == true
                    && entrybedingung == true
                    && Close[1] < entryprice
                    && positionClosedOnBar == false)
                {
                    double stopLossDistance = stopprice - entryprice; // Distance to stop loss in price
                    int stopLossTicks = (int)(stopLossDistance / TickSize); // Convert to ticks
                    profitTarget = entryprice - (1.5 * stopLossDistance);
    
                  [B]  // Calculate the position size based on the dollar risk
                    double tickValue = 0.50; // Value of one tick
                    double riskPerContract = stopLossTicks * tickValue; // Total risk per contract
                    double positionSize = DollarRisk / riskPerContract; // Calculate position size
                    int roundedPositionSize = (int)Math.Floor(positionSize); // Round to nearest whole number[/B]
    
                    // Apply entry offset to limit order price
                    double offsetEntryPrice = entryprice - (TickSize * EntryOffset);
    
                    entryOrder = EnterShortLimit(0, true, roundedPositionSize, offsetEntryPrice, "short1");
                    SetStopLoss("short1", CalculationMode.Price, stopprice, false);  // Set stop loss
                    
                    signal = false;
                    exitsignal = true;
                    merkbar = CurrentBar;
                }
    
                // If the entry order is still pending and the current bar's high is above the stop loss
                if (entryOrder != null && entryOrder.OrderState == OrderState.Working)
                {
                    if (High[0] > stopprice)
                    {
                        stopprice = High[0];  // Adjust stop loss to the new high
                        SetStopLoss("short1", CalculationMode.Price, stopprice, false);  // Update the stop loss
                    }
                }
    
                // Check if the position has been closed and mark the flag
                if (Position.MarketPosition != MarketPosition.Flat)
                {
                    positionClosedOnBar = true; // Set the flag to prevent new position on the same bar
                }
            }
        }
    }​

    #2
    Hello jas0992,

    Welcome to the NinjaTrader forums!

    May I have print output saved to a text file showing the value of positionSize before Math.Floor() is called and the roundedPositionSize after Math.Floor() is called?
    The prints should include the time of the bar and a label for the value.

    If you are not familiar with using prints to understand behavior please see the support article linked below.

    Chelsea B.NinjaTrader Customer Service

    Comment

    Latest Posts

    Collapse

    Topics Statistics Last Post
    Started by NullPointStrategies, Today, 05:17 AM
    0 responses
    24 views
    0 likes
    Last Post NullPointStrategies  
    Started by argusthome, 03-08-2026, 10:06 AM
    0 responses
    120 views
    0 likes
    Last Post argusthome  
    Started by NabilKhattabi, 03-06-2026, 11:18 AM
    0 responses
    63 views
    0 likes
    Last Post NabilKhattabi  
    Started by Deep42, 03-06-2026, 12:28 AM
    0 responses
    41 views
    0 likes
    Last Post Deep42
    by Deep42
     
    Started by TheRealMorford, 03-05-2026, 06:15 PM
    0 responses
    45 views
    0 likes
    Last Post TheRealMorford  
    Working...
    X