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 a strategy triggered by a specific entry criteria

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

    Creating a strategy triggered by a specific entry criteria

    I am attempting to write a strategy that will initiate orders based on specific entry criteria, but it doesn't look quite right when I try to test it using Strategy Analyzer. I require assistance checking the 'logic' of my criteria, to confirm the code says what I think it does.

    My criteria is as such -
    Long entry:
    1. 20SMA is above the 200SMA
    2. Price is above the 20SMA
    3. A red bar opens above the 20SMA, within a certain distance from the 20SMA in ticks
    4. The current bar passes the immediately preceding red bar to the upside, triggering the entry. In other words, a green bar overtakes a red bar above the 20SMA.
    Short entry (exact opposite):
    1. 20SMA is below the 200SMA
    2. Price is below the 20SMA
    3. A green bar closes below the 20SMA, within a certain distance from the 20SMA in ticks
    4. The current bar passes the immediately preceding green bar to the downside, triggering the entry. In other words, a red bar overtakes a green bar below the 20SMA.
    Here is my current code, please let me know if it reads according to my criteria and/or if you have any suggested changes:
    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.Data;
    using NinjaTrader.NinjaScript;
    using NinjaTrader.Core.FloatingPoint;
    using NinjaTrader.NinjaScript.Indicators;
    using NinjaTrader.NinjaScript.DrawingTools;
    #endregion
    
    namespace NinjaTrader.NinjaScript.Strategies {
    // Define the Johnstrat strategy class
    public class Johnstrat : Strategy {
     private SMA fastSma;
     private SMA slowSma;
      [ Range(1, int.MaxValue), NinjaScriptProperty ] public int FastPeriod { get; set; }
    
      [ Range(1, int.MaxValue), NinjaScriptProperty ] public int SlowPeriod { get; set; }
    
      [ Range(1, int.MaxValue), NinjaScriptProperty ] public int TicksProximity { get; set; }
    
      [ Range(1, int.MaxValue), NinjaScriptProperty ] public int StopLossTicks { get; set; }
    
      [ Range(1, int.MaxValue), NinjaScriptProperty ] public int ProfitTargetTicks { get; set; }
    
     protected override void OnStateChange() {
        if (State == State.SetDefaults) {
          Description = "Johnstrat";
          Name = "Johnstrat";
          Calculate = Calculate.OnEachTick;  // Strategy calculation on each tick
                                             // for real-time decision making
    
          // Setting default values
          FastPeriod = 20;
          SlowPeriod = 200;
          TicksProximity = 100;
          StopLossTicks = 40;      // 10 points below entry for stop loss
          ProfitTargetTicks = 80;  // 20 points for profit target
    
        } else if (State == State.Configure) {
          // Add Fast and Slow SMA indicators
          fastSma = SMA(FastPeriod);
          slowSma = SMA(SlowPeriod);
    
          fastSma.Plots[0].Brush = Brushes.DodgerBlue;
          slowSma.Plots[0].Brush = Brushes.Orchid;
    
          AddChartIndicator(fastSma);
          AddChartIndicator(slowSma);
        }
      }
    
     protected
      override void OnBarUpdate() {
        if (CurrentBar < SlowPeriod) return;
    
        // Checking Long and Short Entry Criteria
        if (IsLongEntry())
          EnterLong("LongEntry");  // Use a signal name for the entry
        else if (IsShortEntry())
          EnterShort("ShortEntry");  // Use a signal name for the entry
      }
    
      // Long Entry Criteria
     private bool IsLongEntry() {
        double currentPrice =
            Instrument.MarketData.Ask.Price;  // Real-time ask price for long entry
    
        return fastSma[0] > slowSma[0] &&
               Math.Abs(currentPrice - fastSma[0]) <= TicksProximity &&
               Close[1] < Open[1] &&    // Previous bar is red
               High[1] > fastSma[1] &&  // High of previous bar is above Fast SMA
               Close[1] >= fastSma[1] &&
               currentPrice > High[1];  // Real-time price is above the high of the
                                        // previous red bar
      }
    
     private bool IsShortEntry() {
        double currentPrice =
            Instrument.MarketData.Bid.Price;  // Real-time bid price for short entry
    
        return fastSma[0] < slowSma[0] &&
               Math.Abs(currentPrice - fastSma[0]) <= TicksProximity &&
               Close[1] > Open[1] &&   // Previous bar is green
               Low[1] < fastSma[1] &&  // Low of previous bar is below Fast SMA
               Close[1] <= fastSma[1] &&
               currentPrice < Low[1];  // Real-time price is below the low of the
                                       // previous green bar
      }
    
     protected override void OnOrderUpdate(Cbi.Order order, double limitPrice,
                                  double stopPrice, int quantity, int filled,
                                  double averageFillPrice,
                                  Cbi.OrderState orderState, DateTime time,
                                  Cbi.ErrorCode error, string comment) {
        if (order.Name == "LongEntry" && order.OrderState == OrderState.Filled) {
          // Set the stop loss and profit target for long positions
          SetStopLoss("LongEntry", CalculationMode.Ticks, StopLossTicks, false);
          SetProfitTarget("LongEntry", CalculationMode.Ticks, ProfitTargetTicks);
        } else if (order.Name == "ShortEntry" &&
                   order.OrderState == OrderState.Filled) {
          // Set the stop loss and profit target for short positions
          SetStopLoss("ShortEntry", CalculationMode.Ticks, StopLossTicks, false);
          SetProfitTarget("ShortEntry", CalculationMode.Ticks, ProfitTargetTicks);
        }
      }
    }
    }
    ​
    When I try to test this strategy using the analyzer, nothing happens at all. When I run the strategy on my real-time chart, the historical entries look wrong.. they're often late and following the wrong type of bar. Something is clearly wrong with my logic but I'm not sure what.
    Last edited by lorem; 01-18-2024, 09:01 PM.

    #2
    Hello lorem,

    Thank you for your post.

    While our support team does not provide hands-on debugging assistance, we are still glad to offer debugging assistance and guide you through the process of understanding unexpected behavior. One helpful debugging tool is adding Print statements to understand all of the values used in your conditions and when they are evaluated to be true or not. For more information on using prints for debugging unexpected behavior:


    You can also enable TraceOrders to get helpful output regarding when orders are submitted, canceled, changed, ignored, or rejected. For more details on TraceOrders:


    Another thing to keep in mind in this case is the potential discrepancies between backtest/historical results and real-time strategy results:


    To get a better understanding of why nothing happens when you test in the Strategy Analyzer, please answer all of the following questions:
    • What version of NinjaTrader are you using? Please provide the entire version number. This can be found under Help -> About (Example: 8.?.?.?)
    • Do you see similar results when running the same test on the SampleMaCrossOver strategy in NinjaTrader with the same settings as your strategy?
    • Who are you connected to? This is displayed in green in the lower-left corner of the Control Center window.
    • Are you connected to your data feed provider when running this test?
    • What instrument(s) (and expiry if applicable) have you selected?
    • What Data Series Type have you selected? Example: Tick, Minute, Day
    • What From and To date is selected?
    • If you open a chart for the same instrument(s) and the same date range, then right-click the chart and select 'Reload all historical data' is the historical data showing on the chart?
    • Is your strategy a multi-instrument or multi-time frame strategy?
    • Do you receive an error on the screen? Are there errors on the Log tab of the Control Center? If so, what do these errors report?

    Thanks in advance; I look forward to assisting you further.​
    Emily C.NinjaTrader Customer Service

    Comment


      #3
      Hello Emily,
      Thank you for your response!
      • What version of NinjaTrader are you using? Please provide the entire version number. This can be found under Help -> About (Example: 8.?.?.?)
        • 8.1.1.7 64-bit
      • Do you see similar results when running the same test on the SampleMaCrossOver strategy in NinjaTrader with the same settings as your strategy?
        • No, it seems to take the entries right as MAs cross over each other.
      • Who are you connected to? This is displayed in green in the lower-left corner of the Control Center window.
        • Rithmic / TopStep, I'll test this on Playback when I get a chance later today.
      • Are you connected to your data feed provider when running this test?
        • Yep!
      • What instrument(s) (and expiry if applicable) have you selected?
        • NQMAR24
      • What Data Series Type have you selected? Example: Tick, Minute, Day
        • 2min
      • What From and To date is selected?
        • 1/19/2024 - 1/19/2024
      • If you open a chart for the same instrument(s) and the same date range, then right-click the chart and select 'Reload all historical data' is the historical data showing on the chart?
        • Yes it is, I will provide a screenshot of the historical data I see. I have also marked in Green where the entries *should* have occurred. Click image for larger version

Name:	Capture.png
Views:	73
Size:	212.2 KB
ID:	1287202
      • Is your strategy a multi-instrument or multi-time frame strategy?
        • Nope, one instrument and one time frame.
      • Do you receive an error on the screen? Are there errors on the Log tab of the Control Center? If so, what do these errors report?
        • Nope, no errors in the log. It seems to initiate the strategy without any issues.
      I am attaching another screenshot of an order the strategy initiated today when I tested it on the live chart, while connected to Rithmic. You can see it takes the order on the right bar, but it waits for the bar to close and takes the order at that price instead of where the "trigger" is occurring.
      Sidenote - You can ignore the close/Synchronize to the right, that was me trying to determine if swapping to "Immediately submit" would fix the issue (it did not, all it did with submit an order as soon as it was applied instead of waiting to be triggered. That at least seems to be working as intended.)
      Click image for larger version

Name:	live.png
Views:	38
Size:	29.6 KB
ID:	1287203

      Comment


        #4
        Hello lorem,

        Thank you for your reply.

        For your backtest, I see you have selected today for the start and end date:
        • 1/19/2024 - 1/19/2024
        ​What are the results if you select a different date range, such as 1/15/2024-1/18/2024? Do you see results from your strategy after extending the range and excluding today? If not, are there any errors on the Log then or any information after enabling TraceOrders regarding ignored orders?

        When you tested the strategy live on the chart, was the Calculate property set to On Bar Close, On Price Change, or On Each Tick? It seems as though it may be have been set to On Bar Close - if you would like your strategy to process OnBarUpdate() more frequently and take intrabar actions, you must set it to calculate On Price Change or On Each Tick. For more info on the Calculate property:


        Additionally, when it comes to backtests and historical processing, order fills are based on OHLC prices by default. To get more granular fill prices, you could use the High order fill resolution or program your strategy to submit orders to a single tick data series. For more information:



        The order fill resolution is an option both in Strategy Analyzer settings as well as in the strategy settings when adding a strategy to the Strategies tab of the Control Center or a chart. For an even more detailed explanation of historical strategy results vs. real-time strategy results, please see the following post:


        Thanks for your time and patience.
        Emily C.NinjaTrader Customer Service

        Comment


          #5
          Okay, so I did some more testing on my end in Playback Connection mode and it looks like things are working properly now! I made a few additional changes that seem to have rectified the behavior I was seeing. It is taking the entries as it should at this point.

          Moving on, can you assist me with the second half of this strategy? I'd like to have it take these same entries with a particular ATM strategy that I have already saved as a template.

          Essentially, I want to add a breakeven trigger and a trailing stop loss to each order.
          Last edited by lorem; 01-19-2024, 03:46 PM.

          Comment


            #6
            Ahh, figured it out on my end Thanks again for everything, you can close this.

            Comment

            Latest Posts

            Collapse

            Topics Statistics Last Post
            Started by rhyminkevin, Today, 04:58 PM
            3 responses
            48 views
            0 likes
            Last Post Anfedport  
            Started by iceman2018, Today, 05:07 PM
            0 responses
            5 views
            0 likes
            Last Post iceman2018  
            Started by lightsun47, Today, 03:51 PM
            0 responses
            7 views
            0 likes
            Last Post lightsun47  
            Started by 00nevest, Today, 02:27 PM
            1 response
            14 views
            0 likes
            Last Post 00nevest  
            Started by futtrader, 04-21-2024, 01:50 AM
            4 responses
            50 views
            0 likes
            Last Post futtrader  
            Working...
            X