Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Creating New HA bar type

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

    Creating New HA bar type

    Hello, I've been scratching my head because Heiken Ashi bars don't look the same as other platforms. I've tried the Heiken Ashi indicators in the ecosystem, but they don't work.

    Basically, what I want is the low of the bar be a minimum of 3 possible values. What formula can be used? Math.min only works with picking the low of two values, not 3

    #2
    Hello cfalevel2015,

    Thank you for your post.

    Finding the low of 3 possible values is more of a general C# question and not specific to NinjaTrader. You may need to use outside resources to find a solution that works for you. I was able to find the following publicly available page that has some potential solutions, such as creating a list of values and using list.Min(), or you could next additional Math.Min() statements within each other:
    I need to find the minimum of 5 integer values. i have used if else statement to compare. So its not looking good. i.e. code is very lengthy. I dont know how to reduce the code complexity. can anyone


    Please let us know if we may be of further assistance.
    Emily C.NinjaTrader Customer Service

    Comment


      #3
      Thank you Emily.

      I was able to resolve my math.min problem of picking minimum of 3 values.

      How do I know actually create the bar type so I can actually pick the bar type I created?

      Comment


        #4
        To be sure, I went to ninjascript editor, clicked on new bar type, made my code, clicked on compile, and I do see a .cs file in bin/custom/barstypes folder. But when I click on new chart, it doesn't show up in the type

        Comment


          #5
          Hello cfalevel2015,

          Thank you for your note.

          Have selected a unique enumeration value for BarsPeriodType?


          Here is a tip from the help guide page linked above:
          Tip: When creating custom BarsTypes, it is recommended to pick high, unique enumeration value to avoid conflict from other BarsTypes that may be used by a single installation.

          BarsPeriod = new BarsPeriod { BarsPeriodType = (BarsPeriodType)123456, BarsPeriodTypeName = "MyCustomBars", Value = 1 };
          If your BarsType script is using the same BarsPeriod.BarsPeriodType as another BarsType script, they're may be a conflict so that only one is displayed in the Type dropdown menu when opening a new chart. For an example of a custom barsType script where you can see how this value is set up, please see the UniRenko bars script that is publicly available on our NinjaTrader Ecosystem website:

          Here is a basic guideline of how to import NinjaScript add-ons in NinjaTrader 8:

          Note — To import NinjaScripts you will need the original .zip file.

          To Import:
          1. Download the NinjaScripts to your desktop, keep them in the compressed .zip file.
          2. From the Control Center window select the menu Tools > Import > NinjaScript Add-on...
          3. Select the downloaded .zip file
          4. NinjaTrader will then confirm if the import has been successful.

          Critical - Specifically for some NinjaScripts, it will prompt that you are running newer versions of @SMA, @EMA, etc. and ask if you want to replace, press 'No'

          Once installed, you may add the indicator to a chart by:
          • Right-click your chart > Indicators... > Select the Indicator from the 'Available' list on the left > Add > OK

          Here is a short video demonstration of the import process:
          Please let me know if I can be of further assistance.

          The NinjaTrader Ecosystem website is for educational and informational purposes only and should not be considered a solicitation to buy or sell a futures contract or make any other type of investment decision. The add-ons listed on this website are not to be considered a recommendation and it is the reader's responsibility to evaluate any product, service, or company. NinjaTrader Ecosystem LLC is not responsible for the accuracy or content of any product, service or company linked to on this website.
          Emily C.NinjaTrader Customer Service

          Comment


            #6
            Hi Emily, Thanks for your reply



            It looks like out of the box, candle high and close were not taking a maximum and minimum of 3 values, respectively. With the code below, I think it fixed the high issue (still questionable), but each candle's low is 0. So each candle has a wick that goes all the way down to 0 and it is not good.

            Here is how it is done in thinkorswim and many other platforms:
            haClose = (open+high+low+close)/4 Heikin Ashi Close: The arithmetic mean of the current high, low, open, and close prices.
            haOpen = [haOpen(Previous Bar) + haClose(Previous Bar)]/2 Heikin Ashi Open: The midpoint of the previous candle.
            haHigh = Max(high, haOpen, haClose) Heikin Ashi High: The highest of the following: the actual high, the Heikin Ashi Open, or the Heikin Ashi Close.
            haLow = Min(low, haOpen, haClose) Heikin Ashi Low: The lowest of the following: the actual low, the Heikin Ashi Open, or the Heikin Ashi Close.

            I took the native Hieken Ashi code and made a few changes. Could someone please help to get rid of the candle low issue?

            //
            // NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release.
            //
            region Using declarations
            using System;
            using System.ComponentModel;
            using NinjaTrader;
            using NinjaTrader.Cbi;
            using NinjaTrader.Data;
            using NinjaTrader.NinjaScript;
            using System.Diagnostics;
            using NinjaTrader.Core.FloatingPoint;

            #endregion

            namespace NinjaTrader.NinjaScript.BarsTypes
            {
            public class HABARSMINBarsType : BarsType
            {
            public override void ApplyDefaultValue(BarsPeriod period)
            {
            }

            public override void ApplyDefaultBasePeriodValue(BarsPeriod period)
            {
            switch (period.BaseBarsPeriodType)
            {
            case BarsPeriodType.Day : period.BaseBarsPeriodValue = 1; DaysToLoad = 365; break;
            case BarsPeriodType.Minute : period.BaseBarsPeriodValue = 1; DaysToLoad = 5; break;
            case BarsPeriodType.Month : period.BaseBarsPeriodValue = 1; DaysToLoad = 5475; break;
            case BarsPeriodType.Second : period.BaseBarsPeriodValue = 30; DaysToLoad = 3; break;
            case BarsPeriodType.Tick : period.BaseBarsPeriodValue = 150; DaysToLoad = 3; break;
            case BarsPeriodType.Volume : period.BaseBarsPeriodValue = 1000; DaysToLoad = 3; break;
            case BarsPeriodType.Week : period.BaseBarsPeriodValue = 1; DaysToLoad = 1825; break;
            case BarsPeriodType.Year : period.BaseBarsPeriodValue = 1; DaysToLoad = 15000; break;
            }
            }

            public override string ChartLabel(DateTime time)
            {
            switch (BarsPeriod.BaseBarsPeriodType)
            {
            case BarsPeriodType.Day : return BarsTypeDay.ChartLabel(time);
            case BarsPeriodType.Minute : return BarsTypeMinute.ChartLabel(time);
            case BarsPeriodType.Month : return BarsTypeMonth.ChartLabel(time);
            case BarsPeriodType.Second : return BarsTypeSecond.ChartLabel(time);
            case BarsPeriodType.Tick : return BarsTypeTick.ChartLabel(time);
            case BarsPeriodType.Volume : return BarsTypeTick.ChartLabel(time);
            case BarsPeriodType.Week : return BarsTypeDay.ChartLabel(time);
            case BarsPeriodType.Year : return BarsTypeYear.ChartLabel(time);
            default : return BarsTypeDay.ChartLabel(time);
            }
            }

            public override int GetInitialLookBackDays(BarsPeriod barsPeriod, TradingHours tradingHours, int barsBack)
            {
            switch (BarsPeriod.BaseBarsPeriodType)
            {
            case BarsPeriodType.Day : return (int) Math.Ceiling(barsPeriod.BaseBarsPeriodValue * barsBack * 7.0 / 4.5);
            case BarsPeriodType.Minute :
            int minutesPerWeek = 0;
            lock (tradingHours.Sessions)
            {
            foreach (Session session in tradingHours.Sessions)
            {
            int beginDay = (int)session.BeginDay;
            int endDay = (int)session.EndDay;
            if (beginDay > endDay)
            endDay += 7;

            minutesPerWeek += (endDay - beginDay) * 1440 + session.EndTime / 100 * 60 + session.EndTime % 100 - (session.BeginTime / 100 * 60 + session.BeginTime % 100);
            }
            }

            return (int)Math.Max(1, Math.Ceiling(barsBack / Math.Max(1, minutesPerWeek / 7.0 / barsPeriod.BaseBarsPeriodValue) * 1.05));
            case BarsPeriodType.Month : return barsPeriod.BaseBarsPeriodValue * barsBack * 31;
            case BarsPeriodType.Second : return (int) Math.Max(1, Math.Ceiling(barsBack / Math.Max(1, 8.0 * 60 * 60 / barsPeriod.BaseBarsPeriodValue)) * 7.0 / 5.0); // 8 hours
            case BarsPeriodType.Tick : return 1;
            case BarsPeriodType.Volume : return 1;
            case BarsPeriodType.Week : return barsPeriod.BaseBarsPeriodValue * barsBack * 7;
            case BarsPeriodType.Year : return barsPeriod.BaseBarsPeriodValue * barsBack * 365;
            default : return 1;
            }
            }

            public override double GetPercentComplete(Bars bars, DateTime now)
            {
            switch (BarsPeriod.BaseBarsPeriodType)
            {
            case BarsPeriodType.Day : return now.Date <= bars.LastBarTime.Date
            ? 1.0 - bars.LastBarTime.AddDays(1).Subtract(now).TotalDay s / bars.BarsPeriod.BaseBarsPeriodValue
            : 1;
            case BarsPeriodType.Minute : return now <= bars.LastBarTime ? 1.0 - bars.LastBarTime.Subtract(now).TotalMinutes / bars.BarsPeriod.BaseBarsPeriodValue : 1;
            case BarsPeriodType.Month :
            if (now.Date <= bars.LastBarTime.Date)
            {
            int month = now.Month;
            int daysInMonth = month == 2 ? (DateTime.IsLeapYear(now.Year) ? 29 : 28) : (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ? 31 : 30);
            return (daysInMonth - bars.LastBarTime.Date.AddDays(1).Subtract(now).Tot alDays / bars.BarsPeriod.BaseBarsPeriodValue) / daysInMonth;
            }
            return 1;
            case BarsPeriodType.Second : return now <= bars.LastBarTime ? 1.0 - bars.LastBarTime.Subtract(now).TotalSeconds / bars.BarsPeriod.BaseBarsPeriodValue : 1;
            case BarsPeriodType.Tick : return (double) bars.TickCount / bars.BarsPeriod.BaseBarsPeriodValue;
            case BarsPeriodType.Volume : return bars.Count == 0 ? 0 : (double) bars.GetVolume(bars.Count - 1) / bars.BarsPeriod.BaseBarsPeriodValue;
            case BarsPeriodType.Week : return now.Date <= bars.LastBarTime.Date ? (7 - bars.LastBarTime.AddDays(1).Subtract(now).TotalDay s / bars.BarsPeriod.BaseBarsPeriodValue) / 7 : 1;
            case BarsPeriodType.Year :
            if (now.Date <= bars.LastBarTime.Date)
            {
            double daysInYear = DateTime.IsLeapYear(now.Year) ? 366 : 365;
            return (daysInYear - bars.LastBarTime.Date.AddDays(1).Subtract(now).Tot alDays / bars.BarsPeriod.BaseBarsPeriodValue) / daysInYear;
            }
            return 1;
            default : return 1;
            }
            }

            protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask)
            {
            if (SessionIterator == null)
            SessionIterator = new SessionIterator(bars);

            double haClose = 0.0;
            double haHigh = 0.0;
            double haLow = 0.0;
            double haOpen = 0.0;

            switch (BarsPeriod.BaseBarsPeriodType)
            {
            case BarsPeriodType.Day:
            {
            if (bars.Count == 0)
            {
            if (isBar || bars.TradingHours.Sessions.Count == 0)
            AddBar(bars, open, high, low, close, time.Date, volume);
            else
            {
            SessionIterator.CalculateTradingDay(time, false);
            AddBar(bars, open, high, low, close, SessionIterator.ActualTradingDayExchange, volume);
            }
            }
            else
            {
            DateTime barTime;
            if (isBar)
            barTime = time.Date;
            else
            {
            if (bars.TradingHours.Sessions.Count > 0 && SessionIterator.IsNewSession(time, false))
            {
            SessionIterator.CalculateTradingDay(time, false);
            barTime = SessionIterator.ActualTradingDayExchange;
            if (barTime < bars.LastBarTime.Date)
            barTime = bars.LastBarTime.Date; // Make sure timestamps are ascending
            }
            else
            barTime = bars.LastBarTime.Date; // Make sure timestamps are ascending
            }

            if (bars.DayCount < bars.BarsPeriod.BaseBarsPeriodValue
            || isBar && bars.Count > 0 && barTime == bars.LastBarTime.Date
            || !isBar && bars.Count > 0 && barTime <= bars.LastBarTime.Date)
            {
            haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
            haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(high, bars.GetOpen(bars.Count - 1)));
            haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(low, bars.GetOpen(bars.Count - 1)));
            UpdateBar(bars, haHigh, haLow, haClose, barTime, volume);
            }
            else
            {
            haOpen = bars.Instrument.MasterInstrument.RoundToTickSize(( bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
            haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
            haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(Math.Max(high, haOpen),haClose));
            haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(Math.Min(low, haOpen),haClose));
            AddBar(bars, haOpen, haHigh, haLow, haClose, barTime, volume);
            }
            }
            Last edited by cfalevel2015; 06-06-2023, 02:20 PM.

            Comment


              #7
              break;
              }
              case BarsPeriodType.Minute:
              {
              if (bars.Count == 0)
              AddBar(bars, open, high, low, close, TimeToBarTimeMinute(bars, time, isBar), volume);
              else if (!isBar && time < bars.LastBarTime)
              {
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(high, bars.GetOpen(bars.Count - 1)));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(low, bars.GetOpen(bars.Count - 1)));
              UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume);
              }
              else if (isBar && time <= bars.LastBarTime)
              {
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(high, bars.GetOpen(bars.Count - 1)));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(low, bars.GetOpen(bars.Count - 1)));
              UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume);
              }
              else
              {
              haOpen = bars.Instrument.MasterInstrument.RoundToTickSize(( bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(Math.Max(high, haOpen),haClose));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(Math.Min(low, haOpen),haClose));
              time = TimeToBarTimeMinute(bars, time, isBar);
              AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume);
              }

              break;
              }
              case BarsPeriodType.Month:
              {
              if (bars.Count == 0)
              AddBar(bars, open, high, low, close, TimeToBarTimeMonth(time, bars.BarsPeriod.BaseBarsPeriodValue), volume);
              else if (time.Month <= bars.LastBarTime.Month && time.Year == bars.LastBarTime.Year || time.Year < bars.LastBarTime.Year)
              {
              if (high.ApproxCompare(bars.GetHigh(bars.Count - 1)) != 0 || low.ApproxCompare(bars.GetLow(bars.Count - 1)) != 0 || close.ApproxCompare(bars.GetClose(bars.Count - 1)) != 0 || volume > 0)
              {
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(high, bars.GetOpen(bars.Count - 1)));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(low, bars.GetOpen(bars.Count - 1)));
              UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume);
              }
              }
              else
              {
              haOpen = bars.Instrument.MasterInstrument.RoundToTickSize(( bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(Math.Max(high, haOpen),haClose));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(Math.Min(low, haOpen),haClose));
              AddBar(bars, haOpen, haHigh, haLow, haClose, TimeToBarTimeMonth(time, bars.BarsPeriod.BaseBarsPeriodValue), volume);
              }
              break;
              }
              case BarsPeriodType.Second:
              {
              if (bars.Count == 0)
              {
              DateTime barTime = TimeToBarTimeSecond(bars, time, isBar);
              AddBar(bars, open, high, low, close, barTime, volume);
              }
              else
              {
              if (bars.BarsPeriod.BaseBarsPeriodValue > 1 && time < bars.LastBarTime || bars.BarsPeriod.BaseBarsPeriodValue == 1 && time <= bars.LastBarTime)
              {
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(high, bars.GetOpen(bars.Count - 1)));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(low, bars.GetOpen(bars.Count - 1)));
              UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume);
              }
              else
              {
              haOpen = bars.Instrument.MasterInstrument.RoundToTickSize(( bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(Math.Max(high, haOpen),haClose));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(Math.Min(low, haOpen),haClose));
              time = TimeToBarTimeSecond(bars, time, isBar);
              AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume);
              }
              }
              break;
              }
              case BarsPeriodType.Tick:
              {
              bool isNewSession = SessionIterator.IsNewSession(time, isBar);
              if (isNewSession)
              SessionIterator.GetNextSession(time, isBar);

              if (bars.BarsPeriod.BaseBarsPeriodValue == 1)
              {
              haOpen = haOpen.ApproxCompare(0.0) == 0 ? open : (haOpen + haClose) / 2.0;
              haClose = haClose.ApproxCompare(0.0) == 0 ? close : bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(Math.Max(high, haOpen),haClose));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(Math.Min(low, haOpen),haClose));
              AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume);
              }
              else if (bars.Count == 0)
              AddBar(bars, open, high, low, close, time, volume);
              else if (bars.Count > 0 && (!isNewSession || !bars.IsResetOnNewTradingDay) && bars.BarsPeriod.BaseBarsPeriodValue > 1 && bars.TickCount < bars.BarsPeriod.BaseBarsPeriodValue)
              {
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(high, bars.GetOpen(bars.Count - 1)));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(low, bars.GetOpen(bars.Count - 1)));
              UpdateBar(bars, haHigh, haLow, haClose, time, volume);
              }
              else
              {
              haOpen = bars.Instrument.MasterInstrument.RoundToTickSize(( bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(Math.Max(high, haOpen),haClose));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(Math.Min(low, haOpen),haClose));
              AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume);
              }
              break;
              }
              case BarsPeriodType.Volume:
              {
              if (bars.Count == 0)
              {
              while (volume > bars.BarsPeriod.BaseBarsPeriodValue)
              {
              haOpen = haOpen.ApproxCompare(0.0) == 0 ? open : (haOpen + haClose) / 2.0;
              haClose = haClose.ApproxCompare(0) == 0 ? close : bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(high, haOpen));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(low, haOpen));
              AddBar(bars, haOpen, haHigh, haLow, haClose, time, bars.BarsPeriod.BaseBarsPeriodValue);
              volume -= bars.BarsPeriod.BaseBarsPeriodValue;
              }
              if (volume > 0)
              {
              haOpen = haOpen.ApproxCompare(0.0) == 0 ? open : bars.Instrument.MasterInstrument.RoundToTickSize(( haOpen + haClose) / 2.0);
              haClose = haClose.ApproxCompare(0.0) == 0 ? close : bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(high, haOpen));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(low, haOpen));
              AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume);
              }
              }
              else
              {
              long volumeTmp = 0;
              bool isNewSession = SessionIterator.IsNewSession(time, isBar);
              if (!bars.IsResetOnNewTradingDay || !isNewSession)
              {
              volumeTmp = Math.Min(bars.BarsPeriod.BaseBarsPeriodValue - bars.GetVolume(bars.Count - 1), volume);
              if (volumeTmp > 0)
              {
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(high, bars.GetOpen(bars.Count - 1)));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(low, bars.GetOpen(bars.Count - 1)));
              UpdateBar(bars, haHigh, haLow, haClose, time, volumeTmp);
              }
              }

              if (isNewSession)
              SessionIterator.GetNextSession(time, isBar);

              volumeTmp = volume - volumeTmp;
              while (volumeTmp > 0)
              {
              haOpen = bars.Instrument.MasterInstrument.RoundToTickSize(( bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(Math.Max(high, haOpen),haClose));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(Math.Min(low, haOpen),haClose));
              AddBar(bars, haOpen, haHigh, haLow, haClose, time, Math.Min(volumeTmp, bars.BarsPeriod.BaseBarsPeriodValue));
              volumeTmp -= bars.BarsPeriod.BaseBarsPeriodValue;
              }
              }

              break;
              }
              case BarsPeriodType.Week:
              {
              if (bars.Count == 0)
              {
              AddBar(bars, open, high, low, close, TimeToBarTimeWeek(time, time.AddDays(6 - ((int)time.DayOfWeek + 1) % 7 + (bars.BarsPeriod.BaseBarsPeriodValue - 1) * 7), bars.BarsPeriod.BaseBarsPeriodValue), volume);
              }
              else if (time.Date <= bars.LastBarTime.Date)
              {
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(high, bars.GetOpen(bars.Count - 1)));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(low, bars.GetOpen(bars.Count - 1)));
              UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume);
              }
              else
              {
              haOpen = bars.Instrument.MasterInstrument.RoundToTickSize(( bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
              haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
              haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(Math.Max(high, haOpen),haClose));
              haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(Math.Min(low, haOpen),haClose));
              AddBar(bars, haOpen, haHigh, haLow, haClose, TimeToBarTimeWeek(time.Date, bars.LastBarTime.Date, bars.BarsPeriod.BaseBarsPeriodValue), volume);
              }

              Comment


                #8
                break;
                }
                case BarsPeriodType.Year:
                {
                if (bars.Count == 0)
                {
                AddBar(bars, open, high, low, close, TimeToBarTimeYear(time, bars.BarsPeriod.BaseBarsPeriodValue), volume);
                }
                else
                {
                if (time.Year <= bars.LastBarTime.Year)
                {
                haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
                haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(high, bars.GetOpen(bars.Count - 1)));
                haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(low, bars.GetOpen(bars.Count - 1)));
                UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume);
                }
                else
                {
                haOpen = bars.Instrument.MasterInstrument.RoundToTickSize(( bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0);
                haClose = bars.Instrument.MasterInstrument.RoundToTickSize(( open + high + low + close) / 4.0);
                haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Max(Math.Max(high, haOpen),haClose));
                haLow = bars.Instrument.MasterInstrument.RoundToTickSize(M ath.Min(Math.Min(low, haOpen),haClose));
                AddBar(bars, haOpen, haHigh, haLow, haClose, TimeToBarTimeYear(time.Date, bars.BarsPeriod.BaseBarsPeriodValue), volume);
                }
                }

                break;
                }
                }

                bars.LastPrice = haClose;
                }

                protected override void OnStateChange()
                {
                if (State == State.SetDefaults)
                {
                Name = Custom.Resource.NinjaScriptBarsTypeHeikenAshi;
                BarsPeriod = new BarsPeriod { BarsPeriodType = (BarsPeriodType) 2023, BarsPeriodTypeName = "HABARSMIN(2023)", Value = 1 };
                DaysToLoad = 3;
                }
                else if (State == State.Configure)
                {
                switch (BarsPeriod.BaseBarsPeriodType)
                {
                case BarsPeriodType.Minute : BuiltFrom = BarsPeriodType.Minute; IsIntraday = true; IsTimeBased = true; break;
                case BarsPeriodType.Second : BuiltFrom = BarsPeriodType.Tick; IsIntraday = true; IsTimeBased = true; break;
                case BarsPeriodType.Tick :
                case BarsPeriodType.Volume : BuiltFrom = BarsPeriodType.Tick; IsIntraday = true; IsTimeBased = false; break;
                default : BuiltFrom = BarsPeriodType.Day; IsIntraday = false; IsTimeBased = true; break;
                }

                switch (BarsPeriod.BaseBarsPeriodType)
                {
                case BarsPeriodType.Day : Name = string.Format("{0} {1} Heiken-Ashi{2}", BarsPeriod.BaseBarsPeriodValue, BarsPeriod.BaseBarsPeriodValue == 1 ? Resource.GuiDaily : Resource.GuiDay, BarsPeriod.MarketDataType != MarketDataType.Last ? string.Format(" - {0}", BarsPeriod.MarketDataType) : string.Empty); break;
                case BarsPeriodType.Minute : Name = string.Format("{0} Min Heiken-Ashi{1}", BarsPeriod.BaseBarsPeriodValue, BarsPeriod.MarketDataType != MarketDataType.Last ? string.Format(" - {0}", BarsPeriod.MarketDataType) : string.Empty); break;
                case BarsPeriodType.Month : Name = string.Format("{0} {1} Heiken-Ashi{2}", BarsPeriod.BaseBarsPeriodValue, BarsPeriod.BaseBarsPeriodValue == 1 ? Resource.GuiMonthly : Resource.GuiMonth, BarsPeriod.MarketDataType != MarketDataType.Last ? string.Format(" - {0}", BarsPeriod.MarketDataType) : string.Empty); break;
                case BarsPeriodType.Second : Name = string.Format("{0} {1} Heiken-Ashi{2}", BarsPeriod.BaseBarsPeriodValue, BarsPeriod.BaseBarsPeriodValue == 1 ? Resource.GuiSecond : Resource.GuiSeconds, BarsPeriod.MarketDataType != MarketDataType.Last ? string.Format(" - {0}", BarsPeriod.MarketDataType) : string.Empty); break;
                case BarsPeriodType.Tick : Name = string.Format("{0} Tick Heiken-Ashi{1}", BarsPeriod.BaseBarsPeriodValue, BarsPeriod.MarketDataType != MarketDataType.Last ? string.Format(" - {0}", BarsPeriod.MarketDataType) : string.Empty); break;
                case BarsPeriodType.Volume : Name = string.Format("{0} Volume Heiken-Ashi{1}", BarsPeriod.BaseBarsPeriodValue, BarsPeriod.MarketDataType != MarketDataType.Last ? string.Format(" - {0}", BarsPeriod.MarketDataType) : string.Empty); break;
                case BarsPeriodType.Week : Name = string.Format("{0} {1} Heiken-Ashi{2}", BarsPeriod.BaseBarsPeriodValue, BarsPeriod.BaseBarsPeriodValue == 1 ? Resource.GuiWeekly : Resource.GuiWeeks, BarsPeriod.MarketDataType != MarketDataType.Last ? string.Format(" - {0}", BarsPeriod.MarketDataType) : string.Empty); break;
                case BarsPeriodType.Year : Name = string.Format("{0} {1} Heiken-Ashi{2}", BarsPeriod.BaseBarsPeriodValue, BarsPeriod.BaseBarsPeriodValue == 1 ? Resource.GuiYearly : Resource.GuiYears, BarsPeriod.MarketDataType != MarketDataType.Last ? string.Format(" - {0}", BarsPeriod.MarketDataType) : string.Empty); break;
                }

                Properties.Remove(Properties.Find("PointAndFigureP riceType", true));
                Properties.Remove(Properties.Find("ReversalType", true));
                Properties.Remove(Properties.Find("Value", true));
                Properties.Remove(Properties.Find("Value2", true));
                }
                }

                private DateTime TimeToBarTimeMinute(Bars bars, DateTime time, bool isBar)
                {
                if (SessionIterator.IsNewSession(time, isBar))
                SessionIterator.GetNextSession(time, isBar);

                if (bars.IsResetOnNewTradingDay || !bars.IsResetOnNewTradingDay && bars.Count == 0)
                {
                DateTime barTimeStamp = isBar
                ? SessionIterator.ActualSessionBegin.AddMinutes(Math .Ceiling(Math.Ceiling(Math.Max(0, time.Subtract(SessionIterator.ActualSessionBegin). TotalMinutes)) / bars.BarsPeriod.BaseBarsPeriodValue) * bars.BarsPeriod.BaseBarsPeriodValue)
                : SessionIterator.ActualSessionBegin.AddMinutes(bars .BarsPeriod.BaseBarsPeriodValue + Math.Floor(Math.Floor(Math.Max(0, time.Subtract(SessionIterator.ActualSessionBegin). TotalMinutes)) / bars.BarsPeriod.BaseBarsPeriodValue) * bars.BarsPeriod.BaseBarsPeriodValue);
                if (bars.TradingHours.Sessions.Count > 0 && barTimeStamp > SessionIterator.ActualSessionEnd) // Cut last bar in session down to session end on odd session end time
                barTimeStamp = SessionIterator.ActualSessionEnd;
                return barTimeStamp;
                }
                else
                {
                DateTime lastBarTime = bars.GetTime(bars.Count - 1);
                DateTime barTimeStamp = isBar
                ? lastBarTime.AddMinutes(Math.Ceiling(Math.Ceiling(M ath.Max(0, time.Subtract(lastBarTime).TotalMinutes)) / bars.BarsPeriod.BaseBarsPeriodValue) * bars.BarsPeriod.BaseBarsPeriodValue)
                : lastBarTime.AddMinutes(bars.BarsPeriod.BaseBarsPer iodValue + Math.Floor(Math.Floor(Math.Max(0, time.Subtract(lastBarTime).TotalMinutes)) / bars.BarsPeriod.BaseBarsPeriodValue) * bars.BarsPeriod.BaseBarsPeriodValue);
                if (bars.TradingHours.Sessions.Count > 0 && barTimeStamp > SessionIterator.ActualSessionEnd)
                {
                DateTime saveActualSessionEnd = SessionIterator.ActualSessionEnd;
                SessionIterator.GetNextSession(SessionIterator.Act ualSessionEnd.AddSeconds(1), isBar);
                barTimeStamp = SessionIterator.ActualSessionBegin.AddMinutes((int ) barTimeStamp.Subtract(saveActualSessionEnd).TotalM inutes);
                }
                return barTimeStamp;
                }
                }

                private static DateTime TimeToBarTimeMonth(DateTime time, int periodValue)
                {
                DateTime result = new DateTime(time.Year, time.Month, 1);
                for (int i = 0; i < periodValue; i++)
                result = result.AddMonths(1);

                return result.AddDays(-1);
                }

                private DateTime TimeToBarTimeSecond(Bars bars, DateTime time, bool isBar)
                {
                if (SessionIterator.IsNewSession(time, isBar))
                SessionIterator.GetNextSession(time, isBar);

                if (bars.IsResetOnNewTradingDay || !bars.IsResetOnNewTradingDay && bars.Count == 0)
                {
                DateTime barTimeStamp = isBar
                ? SessionIterator.ActualSessionBegin.AddSeconds(Math .Ceiling(Math.Ceiling(Math.Max(0, time.Subtract(SessionIterator.ActualSessionBegin). TotalSeconds)) / bars.BarsPeriod.BaseBarsPeriodValue) * bars.BarsPeriod.BaseBarsPeriodValue)
                : SessionIterator.ActualSessionBegin.AddSeconds(bars .BarsPeriod.BaseBarsPeriodValue + Math.Floor(Math.Floor(Math.Max(0, time.Subtract(SessionIterator.ActualSessionBegin). TotalSeconds)) / bars.BarsPeriod.BaseBarsPeriodValue) * bars.BarsPeriod.BaseBarsPeriodValue);
                if (bars.TradingHours.Sessions.Count > 0 && barTimeStamp > SessionIterator.ActualSessionEnd) // Cut last bar in session down to session end on odd session end time
                barTimeStamp = SessionIterator.ActualSessionEnd;
                return barTimeStamp;
                }
                else
                {
                DateTime lastBarTime = bars.GetTime(bars.Count - 1);
                DateTime barTimeStamp = isBar
                ? lastBarTime.AddSeconds(Math.Ceiling(Math.Ceiling(M ath.Max(0, time.Subtract(lastBarTime).TotalSeconds)) / bars.BarsPeriod.BaseBarsPeriodValue) * bars.BarsPeriod.BaseBarsPeriodValue)
                : lastBarTime.AddSeconds(bars.BarsPeriod.BaseBarsPer iodValue + Math.Floor(Math.Floor(Math.Max(0, time.Subtract(lastBarTime).TotalSeconds)) / bars.BarsPeriod.BaseBarsPeriodValue) * bars.BarsPeriod.BaseBarsPeriodValue);
                if (bars.TradingHours.Sessions.Count > 0 && barTimeStamp > SessionIterator.ActualSessionEnd)
                {
                DateTime saveActualSessionEnd = SessionIterator.ActualSessionEnd;
                SessionIterator.GetNextSession(SessionIterator.Act ualSessionEnd.AddSeconds(1), isBar);
                barTimeStamp = SessionIterator.ActualSessionBegin.AddSeconds((int ) barTimeStamp.Subtract(saveActualSessionEnd).TotalS econds);
                }
                return barTimeStamp;
                }
                }

                private static DateTime TimeToBarTimeWeek(DateTime time, DateTime periodStart, int periodValue)
                {
                return periodStart.Date.AddDays(Math.Ceiling(Math.Ceiling (time.Date.Subtract(periodStart.Date).TotalDays) / (periodValue * 7)) * (periodValue * 7)).Date;
                }

                private static DateTime TimeToBarTimeYear(DateTime time, int periodValue)
                {
                DateTime result = new DateTime(time.Year, 1, 1);
                for (int i = 0; i < periodValue; i++)
                result = result.AddYears(1);

                return result.AddDays(-1);
                }
                }
                }
                ​​

                Comment


                  #9
                  Hello cfalevel2015,

                  Thank you for your reply.

                  Unfortunately, in the support department at NinjaTrader it is against our policy to create, debug, or modify, code or logic for our clients. Further, we do not provide C# programming education services or one on one educational support in our NinjaScript Support department. This is so that we can maintain a high level of service for all of our clients as well as our associates. We can leave this thread open for members of the forum community to assist you with your script or help to convert the ThinkOrSwim code to NinjaScript.

                  That said, through email or on the forum we are happy to answer any specific questions you may have about NinjaScript if you decide to code this yourself. We are also happy to assist with finding resources in our help guide as well as simple examples, and we are happy to assist with guiding you through the debugging process to assist you with understanding unexpected behavior. You mentioned a candle low issue; please describe what you are expecting to see out of the script vs. the actual behavior and then we would be able to better assist you with tools to debug your script.

                  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 to 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.

                  Please let us know if we may be of further assistance.​
                  Emily C.NinjaTrader Customer Service

                  Comment

                  Latest Posts

                  Collapse

                  Topics Statistics Last Post
                  Started by judysamnt7, 03-13-2023, 09:11 AM
                  4 responses
                  57 views
                  0 likes
                  Last Post DynamicTest  
                  Started by ScottWalsh, Today, 06:52 PM
                  4 responses
                  36 views
                  0 likes
                  Last Post ScottWalsh  
                  Started by olisav57, Today, 07:39 PM
                  0 responses
                  7 views
                  0 likes
                  Last Post olisav57  
                  Started by trilliantrader, Today, 03:01 PM
                  2 responses
                  19 views
                  0 likes
                  Last Post helpwanted  
                  Started by cre8able, Today, 07:24 PM
                  0 responses
                  9 views
                  0 likes
                  Last Post cre8able  
                  Working...
                  X