Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

MA Crossover help

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

    MA Crossover help

    I am working on a strategy that uses a fast EMA(12) and a slow SMA(27) Crossover as trade signals

    the 1st goal is this:
    When the EMA(12) Crosses above the SMA(27) : if the close of the bar during the crossing of MA's is above the SMA(27) EnterLong.
    When the EMA(12) Crosses below the SMA(27) : if the close of the bar during the crossing of MA's is below the SMA(27) EnterShort.

    the 2nd goal is this:
    If I am long a position and the SMA(27) is closer in ticks to my buy price than my 48 tick stop loss, I want my stop to be either
    A) if price hits the current SMA(27) price it will stop me out for less of a loss than my 48 tick stop loss.
    or
    B) if price hits the SMA(27) price at the time of purchase it will stop me out again for less of a loss than the 48 tick stop loss
    Shorting will be the same just reversed


    Edit 2************************************************* ********** with newly edited code
    I have edited the code and worked out a lot of the problems. my only problems now are that my long trades aren't working. they buy and then sell flat on the same candle.

    im also looking for a way to change the colors of the text when it plots the text for each order execution on the chart. i have the draw.line working for entries but i dont know how to get them for exits. these would also be unnecessary if i could change the default plot text for each order fill and add a "+" or a "-" but theyre not changeable in the data Series.


    EDITED CODE********************************************** ************************************************

    region Using declarations
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Xml.Serialization;
    using NinjaTrader.Cbi;
    using NinjaTrader.Gui;
    using NinjaTrader.Gui.Chart;
    using NinjaTrader.Gui.SuperDom;
    using NinjaTrader.Gui.Tools;
    using NinjaTrader.Data;
    using NinjaTrader.NinjaScript;
    using NinjaTrader.Core.FloatingPoint;
    using NinjaTrader.NinjaScript.Indicators;
    using NinjaTrader.NinjaScript.DrawingTools;
    #endregion

    //This namespace holds Strategies in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Strategies
    {
    public class EMACodeTester : Strategy
    {
    private EMA EMA1;
    private SMA SMA1;

    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"Enter the description for your new custom Strategy here.";
    Name = "EMACodeTester";
    Calculate = Calculate.OnBarClose;
    EntriesPerDirection = 1;
    EntryHandling = EntryHandling.AllEntries;
    IsExitOnSessionCloseStrategy = true;
    ExitOnSessionCloseSeconds = 30;
    IsFillLimitOnTouch = false;
    MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
    OrderFillResolution = OrderFillResolution.Standard;
    Slippage = 0;
    StartBehavior = StartBehavior.WaitUntilFlat;
    TimeInForce = TimeInForce.Gtc;
    TraceOrders = false;
    RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
    StopTargetHandling = StopTargetHandling.PerEntryExecution;
    BarsRequiredToTrade = 20;
    // Disable this property for performance gains in Strategy Analyzer optimizations
    // See the Help Guide for additional information
    IsInstantiatedOnEachOptimizationIteration = true;
    FastEMA = 12;
    SlowSMA = 27;
    ProfitTrigger = 48;
    StopLoss = 24;
    MarketStart = 063000;
    MarketEnd = 130000;
    }
    else if (State == State.Configure)
    {
    }
    else if (State == State.DataLoaded)
    {
    EMA1 = EMA(FastEMA);
    SMA1 = SMA(SlowSMA);
    SetProfitTarget(@"EMACodeTester", CalculationMode.Ticks, ProfitTrigger);
    SetStopLoss(@"EMACodeTester", CalculationMode.Ticks, StopLoss, true);
    }
    }

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

    if (CurrentBars[0] < 5)
    return;


    double SMAPrice = SMA1[0];
    double EntryPrice = Position.AveragePrice;
    double SMALongDistance = (EntryPrice - SMAPrice) / 4;
    double SMAShortDistance = (SMAPrice - EntryPrice) / 4;
    double PositionSize = Position.Quantity;

    bool mar****pen = ToTime(Time[0]) >= MarketStart && ToTime(Time[0]) <= MarketEnd;
    bool ActiveLong = Position.MarketPosition == MarketPosition.Long;
    bool ActiveShort = Position.MarketPosition == MarketPosition.Short;
    bool PriceAboveSMA = Close[0] >= SMAPrice;
    bool PriceBelowSMA = Close[0] <= SMAPrice;

    if(mar****pen)
    {
    // Long********************************************** ***********************************************
    if (CrossAbove(EMA1, SMA1, 1) && !ActiveLong && !ActiveShort && PriceAboveSMA)
    {
    EnterLong(Convert.ToInt32(DefaultQuantity), @"EMACodeTester");
    }
    if (ActiveLong)
    {
    if(BarsSinceEntryExecution() == 0)
    {
    Draw.Text(this, "EntryPrice" + CurrentBar, "+" + PositionSize + "@" + EntryPrice , 0, EntryPrice + 33, Brushes.Cyan);
    }
    if (SMALongDistance < StopLoss)
    {
    SetStopLoss(@"EMACodeTester", CalculationMode.Price, SMAPrice, true);
    }
    }
    // Short********************************************* ************************************************
    if (CrossBelow(EMA1, SMA1, 1) && !ActiveLong && !ActiveShort && PriceBelowSMA)
    {
    EnterShort(Convert.ToInt32(DefaultQuantity), @"EMACodeTester");
    }
    if (ActiveShort)
    {
    if(BarsSinceEntryExecution() == 1)
    {
    Draw.Text(this, "EntryPrice" + CurrentBar, "-" + PositionSize + "@" + EntryPrice , 0, EntryPrice + 33, Brushes.Magenta);
    }
    if (SMAShortDistance < StopLoss)
    {
    SetStopLoss(@"EMACodeTester", CalculationMode.Price, SMAPrice, true);
    }
    }
    }
    if(!mar****pen)
    {
    ExitLong();
    ExitShort();
    }
    }



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

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

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

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

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

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name="MarketEnd", Description="Trading Hours End", Order=1, GroupName="Parameters")]
    public int MarketEnd
    { get; set; }
    #endregion
    }
    }
    Last edited by ccagle; 09-15-2024, 03:39 PM.

    #2
    Hello ccagle,

    Thank you for your post.

    If the strategy isn't taking trades as expected you will need to debug the script using Prints and TraceOrders.

    Two things of note when looking at your script. It looks like there is a possibility that the script could call an entry and an exit on the same bar. If you are trying to reverse the position, call the entry in the opposite direction without calling an exit order. Calling an entry and an exit on the same bar can lead to unintended behavior, like doubling your position in the opposite direction.

    Additionally, Set methods cannot be unset. This means it is important to call the Set method with CalculationMode.Ticks to reset this before calling an entry method (not after).​

    If you want to dynamically change/modify the price of the stop loss and profit target, the method should be called from within OnBarUpdate() and the price should always be reset when the strategy becomes flat again. This information is noted in the "Tips" section on the following help guide pages:
    To understand why the script is behaving as it is, such as placing orders or not placing orders when expected, it is necessary to add prints to the script that print the values used for the logic of the script to understand how the script is evaluating.

    In the strategy add prints (outside of any conditions) that print the date time of the bar and all values compared in every condition that places an order.

    The prints should include the time of the bar and should print all values from all variables and all hard coded values in all conditions that must evaluate as true for this action to be triggered. It is very important to include a text label for each value and for each comparison operator in the print to understand what is being compared in the condition sets.

    The debugging print output should clearly show what the condition is, what time the conditions are being compared, all values being compared, and how they are being compared.

    Prints will appear in the NinjaScript Output window (New > NinjaScript Output window).

    Further, enable TraceOrders which will let us know if any orders are being ignored and not being submitted when the condition to place the orders is evaluating as true.

    After enabling TraceOrders remove the instance of the strategy from the Configured list in the Strategies window and add a new instance of the strategy from the Available list.

    I am happy to assist you with analyzing the output from the output window.

    Run or backtest the script and when the output from the output window appears save this by right-clicking the output window and selecting Save As... -> give the output file a name and save -> then attach the output text file to your reply.

    Below is a link to a support article that demonstrates using informative prints to understand behavior and includes a link to a video recorded using the Strategy Builder to add prints.

    https://support.ninjatrader.com/s/ar...nd-TraceOrders

    Comment

    Latest Posts

    Collapse

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