Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Overnight values vs RTH

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

    Overnight values vs RTH

    Ninjatrader support,

    Searched for it, but seems impossible having a RTH chart but with the Overnight High Low in place.
    I can add a 2nd barseries using a different template and hide the values using transparency, but that will show empty space on my RTH chart.

    What is a good way to get the overnight levels but only show the RTH chart visible without even knowing that the ETH is set as 2nd dataseries or any other good idea to solve this?


    #2
    Hello Creamers,

    Thank you for your post.

    Unfortunately, I am not aware of any way to remove the gaps when using a transparent data series with a different Trading Hours template applied.
    While there are two data series, the time axis will still show the longer trading hours template despite the transparent bars.

    You may need custom NinjaScript or a third-party add-on to display the 'Overnight High Low' indicator without the hidden data series.

    Please let me know if I may be of any further assistance.
    Eduardo R.NinjaTrader Customer Service

    Comment


      #3
      I did found a suggestion on the forum creating an indicator using a session template.

      I created a new sessiontemplate where is shows a break between the rth and overnight time, see attachment.

      I copied the PriorDayOHLC and added a dataseries:

      Code:
      AddDataSeries("MES 06-24", new BarsPeriod { BarsPeriodType = BarsPeriodType.Minute, Value = 5 }, "CME US Index Futures ovn rth");
      I replaced:

      Code:
         if (currentDate != sessionIterator.GetTradingDay(Time[0]) || currentOpen == 0)
      with:

      if (Bars.IsFirstBarOfSession)

      Now, when I use this indicator on a ETH chart it works, but when I set the chart to RTH the indicator doesnt show the previous session values from the AddDataSeries, but the normal RTH previous sesion of the chart itself.

      Can it be that the IsFirstBarOfSession needs to use the added dataseries , but how ?

      Code:
      // This namespace holds indicators in this folder and is required. Do not change it.
      namespace NinjaTrader.NinjaScript.Indicators
      {
          /// <summary>
          /// Plots the open, high, low and close values from the session starting on the prior day.
          /// </summary>
          public class PriorDayOHLC : Indicator
          {
              private DateTime                 currentDate         =    Core.Globals.MinDate;
              private double                    currentClose        =    0;
              private double                    currentHigh            =    0;
              private double                    currentLow            =    0;
              private double                    currentOpen            =    0;
              private double                    priorDayClose        =    0;
              private double                    priorDayHigh        =    0;
              private double                    priorDayLow            =    0;
              private double                    priorDayOpen        =    0;
              private    Data.SessionIterator    sessionIterator;
      
              protected override void OnStateChange()
              {
                  if (State == State.SetDefaults)
                  {
                      Description                                    = @"PriorDayOHLC";
                      Name                                        = "PriorDayOHLC";
                      IsAutoScale                    = false;
                      IsOverlay                    = true;
                      IsSuspendedWhileInactive    = true;
                      DrawOnPricePanel            = false;
                      ShowClose                    = true;
                      ShowLow                        = true;
                      ShowHigh                    = true;
                      ShowOpen                    = true;
      
                      AddPlot(new Stroke(Brushes.SteelBlue,    DashStyleHelper.Dash,    2),    PlotStyle.Hash, NinjaTrader.Custom.Resource.PriorDayOHLCOpen);
                      AddPlot(new Stroke(Brushes.DarkCyan,                            2),    PlotStyle.Hash, NinjaTrader.Custom.Resource.PriorDayOHLCHigh);
                      AddPlot(new Stroke(Brushes.Crimson,                                2),    PlotStyle.Hash, NinjaTrader.Custom.Resource.PriorDayOHLCLow);
                      AddPlot(new Stroke(Brushes.SlateBlue,    DashStyleHelper.Dash,    2),    PlotStyle.Hash, NinjaTrader.Custom.Resource.PriorDayOHLCClose);
                  }
                  else if (State == State.Configure)
                  {
                      currentDate         = Core.Globals.MinDate;
                      currentClose        = 0;
                      currentHigh            = 0;
                      currentLow            = 0;
                      currentOpen            = 0;
                      priorDayClose        = 0;
                      priorDayHigh        = 0;
                      priorDayLow            = 0;
                      priorDayOpen        = 0;
                      sessionIterator        = null;
                      AddDataSeries("MES 06-24", new BarsPeriod { BarsPeriodType = BarsPeriodType.Minute, Value = 5 }, "CME US Index Futures (Custom)");
                  }
                  else if (State == State.DataLoaded)
                  {
      
                  }
                  else if (State == State.Historical)
                  {
                      if (!Bars.BarsType.IsIntraday)
                      {
                          Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.PriorDayOHLCIntradayError, TextPosition.BottomRight);
                          Log(NinjaTrader.Custom.Resource.PriorDayOHLCIntradayError, LogLevel.Error);
                      }
                  }
              }
      
              protected override void OnBarUpdate()
              {
                  if (!Bars.BarsType.IsIntraday)
                      return;
                  if (BarsInProgress == 1 || BarsInProgress == 2)
                      return;
                  
                  if (Bars.IsFirstBarOfSession)
                  {
                      Print("New session per day or session is the question");
                      // The current day OHLC values are now the prior days value so set
                      // them to their respect indicator series for plotting
                      priorDayOpen    = currentOpen;
                      priorDayHigh    = currentHigh;
                      priorDayLow        = currentLow;
                      priorDayClose    = currentClose;
      
                      Print("priorDayHigh: " + priorDayHigh);
                      Print("priorDayLow: " + priorDayLow);
                      
                      if (ShowOpen)    PriorOpen[0]    = priorDayOpen;
                      if (ShowHigh)    PriorHigh[0]    = priorDayHigh;
                      if (ShowLow)    PriorLow[0]        = priorDayLow;
                      if (ShowClose)    PriorClose[0]    = priorDayClose;
                      
                      currentOpen     =    Opens[1][0];
                      currentHigh     =    Highs[1][0];
                      currentLow        =    Lows[1][0];
                      currentClose    =    Closes[1][0];
      
                      currentDate     =    sessionIterator.GetTradingDay(Time[0]);
                  }
                  else // The current day is the same day
                  {
                      // Set the current day OHLC values
                      currentHigh     =    Math.Max(currentHigh, Highs[1][0]);
                      currentLow        =    Math.Min(currentLow, Lows[1][0]);
                      currentClose    =    Closes[1][0];
                      Print("currentHigh during day: " + currentHigh);
                      Print("currentLow during day: " + currentLow);
                      
                      if (ShowOpen)    PriorOpen[0] = priorDayOpen;
                      if (ShowHigh)    PriorHigh[0] = priorDayHigh;
                      if (ShowLow)    PriorLow[0] = priorDayLow;
                      if (ShowClose)    PriorClose[0] = priorDayClose;
                  }
              }
      
              #region Properties
              [Browsable(false)]    // this line prevents the data series from being displayed in the indicator properties dialog, do not remove
              [XmlIgnore()]        // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
              public Series<double> PriorOpen
              {
                  get { return Values[0]; }
              }
      
              [Browsable(false)]
              [XmlIgnore()]
              public Series<double> PriorHigh
              {
                  get { return Values[1]; }
              }
      
              [Browsable(false)]
              [XmlIgnore()]
              public Series<double> PriorLow
              {
                  get { return Values[2]; }
              }
      
              [Browsable(false)]
              [XmlIgnore()]
              public Series<double> PriorClose
              {
                  get { return Values[3]; }
              }
      
              [Display(ResourceType = typeof(Custom.Resource), Name = "ShowClose", GroupName = "NinjaScriptParameters", Order = 0)]
              public bool ShowClose
              { get; set; }
      
              [Display(ResourceType = typeof(Custom.Resource), Name = "ShowHigh", GroupName = "NinjaScriptParameters", Order = 1)]
              public bool ShowHigh
              { get; set; }
      
              [Display(ResourceType = typeof(Custom.Resource), Name = "ShowLow", GroupName = "NinjaScriptParameters", Order = 2)]
              public bool ShowLow
              { get; set; }
      
              [Display(ResourceType = typeof(Custom.Resource), Name = "ShowOpen", GroupName = "NinjaScriptParameters", Order = 3)]
              public bool ShowOpen
              { get; set; }
              #endregion
              
              public override string FormatPriceMarker(double price)
              {
                  return Instrument.MasterInstrument.FormatPrice(price);
              }
          }
      }​
      Attached Files
      Last edited by Creamers; 05-01-2024, 08:09 AM.

      Comment


        #4
        Btw, just tried if (Bars.IsFirstBarOfSession) , works when I load the chart with my custom template, but it seems that the indicator doesnt see the new sessions using the 2nd barseries with the custom template.

        Think IsFirstBarOfSession need to use the added barseries but how ?

        Just tried: if (BarsArray[1].IsFirstBarOfSession)

        That doesnt seem to work.
        Last edited by Creamers; 05-01-2024, 08:26 AM.

        Comment


          #5
          Hello Creamers,

          Where you have:

          if (BarsInProgress == 1 || BarsInProgress == 2)
          return;

          This is making sure that the script is not updating for the added series and is only updating for the primary series.

          Possibly you want to run on the added series:

          if (BarsInProgress == 0) return;​

          Also, it would probably be easier to just call the PriorDayOLHC() indicator and supply BarsArray[1] as the input series.

          if (BarsInProgress == 1)
          {
          Print("PriorDayOHLC(BarsArray[1]).PriorClose[0: " + PriorDayOHLC(BarsArray[1]).PriorClose[0]);
          }
          Chelsea B.NinjaTrader Customer Service

          Comment


            #6
            Originally posted by NinjaTrader_ChelseaB View Post
            Hello Creamers,

            Where you have:

            if (BarsInProgress == 1 || BarsInProgress == 2)
            return;

            This is making sure that the script is not updating for the added series and is only updating for the primary series.

            Possibly you want to run on the added series:

            if (BarsInProgress == 0) return;​

            Also, it would probably be easier to just call the PriorDayOLHC() indicator and supply BarsArray[1] as the input series.

            if (BarsInProgress == 1)
            {
            Print("PriorDayOHLC(BarsArray[1]).PriorClose[0: " + PriorDayOHLC(BarsArray[1]).PriorClose[0]);
            }
            Hi Chelsea,

            Tried both your advice/examples, but both don't seem to use the extra template but just take the primary bar session and not the one I added.
            Code:
            AddDataSeries("MES 06-24", new BarsPeriod { BarsPeriodType = BarsPeriodType.Minute, Value = 5 }, "CME US Index Futures (Custom)");
            When I set this session template on the chart and use the indicator it works fine, but I only want to see the RTH session therefor I want this as extra dataserie in the indicator incl custom sessiontemplate like in the attachment.
            Last edited by Creamers; 05-01-2024, 11:55 AM.

            Comment


              #7
              Hello Creamers,

              You haven't provided any proof that you have created a custom Trading hours template with the name 'CME US Index Futures (Custom)' and what the high is on a chart with that template applied.

              So, below is a link to a short video showing this does work.
              Chelsea B.NinjaTrader Customer Service

              Comment


                #8
                Originally posted by NinjaTrader_ChelseaB View Post
                Hello Creamers,

                You haven't provided any proof that you have created a custom Trading hours template with the name 'CME US Index Futures (Custom)' and what the high is on a chart with that template applied.

                So, below is a link to a short video showing this does work.
                https://drive.google.com/file/d/1Bp5...w?usp=drivesdk
                I think your example works as RTH or ETH session are full days.

                Mine is a divided session, so 1 day with two sessions.

                Here is my 'proof', hope it helps. Thanks for taking the time , appreciate it!



                btw, if you download the movie and use VLC player it much more visible then in a browser I noticed.
                Last edited by Creamers; 05-01-2024, 02:15 PM.

                Comment


                  #9
                  Hello Creamers,

                  In the video you are showing a print of 5051,25.

                  Why is this incorrect?
                  What are you comparing this to?
                  How do you even know what bar this value is for? (there is no date or time in the print)
                  I'm not seeing in your video what the high was for the previous trading day (including all sessions).

                  All I can see is that 5051,25 was printed. I don't see why this is wrong or even what this is being compared to.

                  If you watch the video I provided you, you can see I am showing the value on the chart that we are comparing with, and showing that value in the print along with a date and time stamp to show what bar the value is for.

                  Having multiple sessions in a trading day will still be seen as one trading day.
                  Chelsea B.NinjaTrader Customer Service

                  Comment


                    #10
                    Hi Chelsea,

                    Yes, using the RTH or ETH session template it takes the previous session low as expected as it's a previous day (so it seems in my eyes)
                    So when I adjust the added barseries template to RTH it will get the correct value as I show on the end of the video.
                    But using the custom template in the indicator it only retrieves previous day low and not previous session (overnight on the same day) low.

                    Also added timestamp.


                    Please let me know if you are not convinced, I dont mind to put some work in to solve this.

                    Thanks for your time.

                    Comment


                      #11
                      Hello Creamers,

                      It would be expected PriorDayOHLC().PriorLow[0] would be the low of the previous trading day.

                      If there are multiple trading sessions in a single trading day, these are all considered one trading day.

                      The values for this indicator are reset at the start of a new trading day, not a new session within a multi-session trading day.

                      if (currentDate != sessionIterator.GetTradingDay(Time[0]) || currentOpen == 0)

                      If you wanted the previous session from a multi-session trading day, you would need to design your own custom indicator with custom logic.

                      You could check Bars.IsFirstBarOfSession to know if a bar is the first bar of a new session (and not just a new trading day).
                      Chelsea B.NinjaTrader Customer Service

                      Comment


                        #12
                        Originally posted by NinjaTrader_ChelseaB View Post
                        Hello Creamers,

                        It would be expected PriorDayOHLC().PriorLow[0] would be the low of the previous trading day.

                        If there are multiple trading sessions in a single trading day, these are all considered one trading day.

                        The values for this indicator are reset at the start of a new trading day, not a new session within a multi-session trading day.

                        if (currentDate != sessionIterator.GetTradingDay(Time[0]) || currentOpen == 0)

                        If you wanted the previous session from a multi-session trading day, you would need to design your own custom indicator with custom logic.

                        You could check Bars.IsFirstBarOfSession to know if a bar is the first bar of a new session (and not just a new trading day).
                        Hi Chelsea,

                        Anyways, using some of these works when I create my own custom indicator as copy of the original priordayohlc indicator.

                        Code:
                        if (CurrentBars[0] < 0 || CurrentBars[1] < 0)
                        return;​
                        if (BarsInProgress == 0) return;
                        Code:
                        if (BarsArray[1].IsFirstBarOfSession)
                        Last question then:

                        Code:
                        AddDataSeries("MES 06-24", new BarsPeriod { BarsPeriodType = BarsPeriodType.Minute, Value = 5 }, "CME US Index Futures RTH (Custom)");
                        Could you help me or do you have an example how I can make this more as a variable so I can add a template name in the parameters instead hardcoded in the code?
                        Is this even possible as the AddDataSeries line is defined in the onStateChange section ?

                        Comment


                          #13
                          Chelsea, found it:!

                          For everyone that wants to (only) have the RTH chart up but still wants to show the overnight levels.
                          Set up a new custom template that divides the day into two session.
                          Click image for larger version

Name:	custom session template.png
Views:	24
Size:	24.4 KB
ID:	1302125

                          Replace the symbol name with null and define a variable templateName using NinjaScriptProperty.
                          Code:
                          AddDataSeries(null, new BarsPeriod { BarsPeriodType = BarsPeriodType.Minute, Value = 5 }, sessionTemplateName);

                          Code:
                          // Define a string input parameter for the session template name
                          private string sessionTemplateName = "CME US Index Futures RTH (Custom)";
                          
                          [NinjaScriptProperty]
                          public string SessionTemplateName
                          {
                          get { return sessionTemplateName; }
                          set { sessionTemplateName = value; }
                          }
                          The complete code for anyone who wants to create it on their own.

                          Code:
                          namespace NinjaTrader.NinjaScript.Indicators
                          {
                              /// <summary>
                              /// Plots the open, high, low and close values from the session starting on the prior day.
                              /// </summary>
                              public class NinjaPriorDayOHLC : Indicator
                              {
                                  private DateTime                 currentDate         =    Core.Globals.MinDate;
                                  private double                    currentClose        =    0;
                                  private double                    currentHigh            =    0;
                                  private double                    currentLow            =    0;
                                  private double                    currentOpen            =    0;
                                  private double                    priorDayClose        =    0;
                                  private double                    priorDayHigh        =    0;
                                  private double                    priorDayLow            =    0;
                                  private double                    priorDayOpen        =    0;
                          
                                  protected override void OnStateChange()
                                  {
                                      if (State == State.SetDefaults)
                                      {
                                          Description                                    = @"NinjaPriorDayOHLC will show previous session OHLC using a custom session template";
                                          Name                                        = "NinjaPriorDayOHLC";
                                          IsAutoScale                    = false;
                                          IsOverlay                    = true;
                                          IsSuspendedWhileInactive    = true;
                                          DrawOnPricePanel            = false;
                                          ShowClose                    = true;
                                          ShowLow                        = true;
                                          ShowHigh                    = true;
                                          ShowOpen                    = true;
                          
                                          AddPlot(new Stroke(Brushes.SteelBlue,    DashStyleHelper.Dash,    2),    PlotStyle.Hash, NinjaTrader.Custom.Resource.PriorDayOHLCOpen);
                                          AddPlot(new Stroke(Brushes.DarkCyan,                            2),    PlotStyle.Hash, NinjaTrader.Custom.Resource.PriorDayOHLCHigh);
                                          AddPlot(new Stroke(Brushes.Crimson,                                2),    PlotStyle.Hash, NinjaTrader.Custom.Resource.PriorDayOHLCLow);
                                          AddPlot(new Stroke(Brushes.SlateBlue,    DashStyleHelper.Dash,    2),    PlotStyle.Hash, NinjaTrader.Custom.Resource.PriorDayOHLCClose);
                                      }
                                      else if (State == State.Configure)
                                      {
                                          currentDate         = Core.Globals.MinDate;
                                          currentClose        = 0;
                                          currentHigh            = 0;
                                          currentLow            = 0;
                                          currentOpen            = 0;
                                          priorDayClose        = 0;
                                          priorDayHigh        = 0;
                                          priorDayLow            = 0;
                                          priorDayOpen        = 0;
                                          AddDataSeries(null, new BarsPeriod { BarsPeriodType = BarsPeriodType.Minute, Value = 5 }, sessionTemplateName);
                                      }
                                      else if (State == State.DataLoaded)
                                      {
                                      }
                                      else if (State == State.Historical)
                                      {
                                          if (!Bars.BarsType.IsIntraday)
                                          {
                                              Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.PriorDayOHLCIntradayError, TextPosition.BottomRight);
                                              Log(NinjaTrader.Custom.Resource.PriorDayOHLCIntradayError, LogLevel.Error);
                                          }
                                      }
                                  }
                          
                                  protected override void OnBarUpdate()
                                  {
                                      if (CurrentBars[0] < 0 || CurrentBars[1] < 0)
                                       return;
                                      if (!Bars.BarsType.IsIntraday)
                                          return;
                                      if (BarsInProgress == 0) return;
                          
                                      if (BarsArray[1].IsFirstBarOfSession)
                                      {
                                          Print("New session per day or session is the question");
                                          // The current day OHLC values are now the prior days value so set
                                          // them to their respect indicator series for plotting
                                          priorDayOpen    = currentOpen;
                                          priorDayHigh    = currentHigh;
                                          priorDayLow        = currentLow;
                                          priorDayClose    = currentClose;
                          
                                          Print("priorDayHigh: " + priorDayHigh);
                                          Print("priorDayLow: " + priorDayLow);
                                          
                                          if (ShowOpen)    PriorOpen[0]    = priorDayOpen;
                                          if (ShowHigh)    PriorHigh[0]    = priorDayHigh;
                                          if (ShowLow)    PriorLow[0]        = priorDayLow;
                                          if (ShowClose)    PriorClose[0]    = priorDayClose;
                          
                                          // Initilize the current day settings to the new days data        
                                          currentOpen     =    Opens[1][0];
                                          currentHigh     =    Highs[1][0];
                                          currentLow        =    Lows[1][0];
                                          currentClose    =    Closes[1][0];
                          
                                      }
                                      else // The current day is the same day
                                      {
                                          // Set the current day OHLC values
                                          currentHigh     =    Math.Max(currentHigh, Highs[1][0]);
                                          currentLow        =    Math.Min(currentLow, Lows[1][0]);
                                          currentClose    =    Closes[1][0];
                                          Print("currentHigh during day: " + currentHigh);
                                          Print("currentLow during day: " + currentLow);
                                          
                                          if (ShowOpen)    PriorOpen[0] = priorDayOpen;
                                          if (ShowHigh)    PriorHigh[0] = priorDayHigh;
                                          if (ShowLow)    PriorLow[0] = priorDayLow;
                                          if (ShowClose)    PriorClose[0] = priorDayClose;
                                      }
                                  }
                          
                                  #region Properties
                                  // Define a string input parameter for the session template name
                                  private string sessionTemplateName = "CME US Index Futures RTH (Custom)";
                                  
                                  [NinjaScriptProperty]
                                  public string SessionTemplateName
                                  {
                                      get { return sessionTemplateName; }
                                      set { sessionTemplateName = value; }
                                  }
                                  [Browsable(false)]    // this line prevents the data series from being displayed in the indicator properties dialog, do not remove
                                  [XmlIgnore()]        // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
                                  public Series<double> PriorOpen
                                  {
                                      get { return Values[0]; }
                                  }
                          
                                  [Browsable(false)]
                                  [XmlIgnore()]
                                  public Series<double> PriorHigh
                                  {
                                      get { return Values[1]; }
                                  }
                          
                                  [Browsable(false)]
                                  [XmlIgnore()]
                                  public Series<double> PriorLow
                                  {
                                      get { return Values[2]; }
                                  }
                          
                                  [Browsable(false)]
                                  [XmlIgnore()]
                                  public Series<double> PriorClose
                                  {
                                      get { return Values[3]; }
                                  }
                          
                                  [Display(ResourceType = typeof(Custom.Resource), Name = "ShowClose", GroupName = "NinjaScriptParameters", Order = 0)]
                                  public bool ShowClose
                                  { get; set; }
                          
                                  [Display(ResourceType = typeof(Custom.Resource), Name = "ShowHigh", GroupName = "NinjaScriptParameters", Order = 1)]
                                  public bool ShowHigh
                                  { get; set; }
                          
                                  [Display(ResourceType = typeof(Custom.Resource), Name = "ShowLow", GroupName = "NinjaScriptParameters", Order = 2)]
                                  public bool ShowLow
                                  { get; set; }
                          
                                  [Display(ResourceType = typeof(Custom.Resource), Name = "ShowOpen", GroupName = "NinjaScriptParameters", Order = 3)]
                                  public bool ShowOpen
                                  { get; set; }
                                  #endregion
                                  
                                  public override string FormatPriceMarker(double price)
                                  {
                                      return Instrument.MasterInstrument.FormatPrice(price);
                                  }
                              }
                          }​

                          Comment


                            #14
                            Hello Creamers,

                            "Could you help me or do you have an example how I can make this more as a variable so I can add a template name in the parameters instead hardcoded in the code?"

                            Using variables in AddDataSeries() is not supported. (This will break in the Strategy Analyzer if you try to optimize the strategy)

                            From the help guide:
                            "Arguments supplied to AddDataSeries() should be hardcoded and NOT dependent on run-time variables which cannot be reliably obtained during State.Configure (e.g., Instrument, Bars, or user input). Attempting to add a data series dynamically is NOT guaranteed and therefore should be avoided. Trying to load bars dynamically may result in an error similar to: Unable to load bars series. Your NinjaScript may be trying to use an additional data series dynamically in an unsupported manner."
                            Chelsea B.NinjaTrader Customer Service

                            Comment

                            Latest Posts

                            Collapse

                            Topics Statistics Last Post
                            Started by patrickmlee007, Today, 09:33 AM
                            2 responses
                            17 views
                            0 likes
                            Last Post patrickmlee007  
                            Started by magnatauren, 08-15-2020, 02:12 PM
                            5 responses
                            206 views
                            0 likes
                            Last Post RaddiFX
                            by RaddiFX
                             
                            Started by rene69851, 05-02-2024, 03:25 PM
                            1 response
                            22 views
                            0 likes
                            Last Post rene69851  
                            Started by ETFVoyageur, Yesterday, 07:05 PM
                            5 responses
                            45 views
                            0 likes
                            Last Post ETFVoyageur  
                            Started by jpeep, 08-16-2020, 08:31 AM
                            13 responses
                            487 views
                            0 likes
                            Last Post notenufftime  
                            Working...
                            X