I was working on an indicator that would draw text on my chart whenever conditions of my EMA strategy are met. Now I have this specific situation, where the crossing of the various EMAs are VALID or INVALD. According to the respective condition the indicator shoudl draw a different text.
The idea is as follows:
I need to extend two conditions where 50-period EMA crosses above the 200-period EMA and the 20-period EMA is above the 50-period EMA,
OR when the 50-period EMA crosses below the 200-period EMA and the 20-period EMA is below the 50-period EMA.
Letīs name these crossings "X2" and letīs name the first variant of that condition "ABOVE200" and the second variant "BELOW200".
First I discribe the whole situation on the ABOVE200 variant. Before the EMA 50 crosses above the EMA 200, the EMA 20 had to cross above the EMA 200 earlier, but more importantly at a certain point in the past the EMA 20 had to cross above the EMA 50 when they were both below the EMA 200. Letīs call this crossing "X1". Now we have a certain period of time or numbers of bars on the chart where the market price is moving up and down and if the price development is rising long enough it causes first the EMA 20 to cross above the EMA 200 and when also EMA 50 crosses above EMA 200 we got the X2.
BUT in my strategy I am using this indivator for, there is one condition that invalidates the X2 and that is when: the market price between the X1 and X2 hits the EMA 20 value, or in other words if market price is equal or lower than ema20 between X1 and X2. If that happens the X2 is not valid anymore. Letīs call this situation "invalidX2".
Now I would need my code to tak this into account so when the discribed situation happens (invalidX2), it triggers the Draw.Text with a different text. Of course that should be applied for the ABOVE200 variant and in the opposite also for the BELOW200 variant.
If the condition is valid, meaning invaldX2 doesnīt happen the code for the ABOVE200 and BELOW200 conditions should print the VALID text in the NinjaScript Output and the Draw.Text shall show the valid versions "AV-X2" and "BV-X2".
And here is another thing: applying the invalidX2 situation should work on the whole chart, for every situation where the ABOVE200 and BELOW200 conditions are met, not only from the current bar.
Here is my current version of the 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.DrawingTools;
#endregion
//This namespace holds Indicators in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Indicators
{
public class EMAX2SymbolWithN : Indicator
{
private EMA ema20;
private EMA ema50;
private EMA ema200;
bool validX2;
bool invalidX2;
[Range(1, int.MaxValue), NinjaScriptProperty]
public int EMAPeriod1 { get; set; }
[Range(1, int.MaxValue), NinjaScriptProperty]
public int EMAPeriod2 { get; set; }
[Range(1, int.MaxValue), NinjaScriptProperty]
public int EMAPeriod3 { get; set; }
[Range(1, int.MaxValue), NinjaScriptProperty]
public int TextOffset { get; set; }
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "EMA X2 Symbol wN";
EMAPeriod1 = 20;
EMAPeriod2 = 50;
EMAPeriod3 = 200;
TextOffset = 30;
}
}
protected override void OnBarUpdate()
{
ema20 = EMA(EMAPeriod1);
ema50 = EMA(EMAPeriod2);
ema200 = EMA(EMAPeriod3);
//ABOVE200 condition
if(CrossAbove(ema50, ema200, 1) && ema20[0] > ema50[0])
{
validX2 = true;
invalidX2 = false;
//check if market price is equal or lower than ema20
if(Close[0] <= ema20[0])
{
invalidX2 = true;
validX2 = false;
}
else if(validX2 && !invalidX2)
{
//original Draw.Text() call
Print("ABOVE200: VALID " + Instrument.FullName + " at: " + Time[0]);
Draw.Text(this, "AV-X2"+CurrentBar, "AV-X2", 0, Low[0] - (TickSize*TextOffset), Brushes.Blue);
}
else if (!validX2 && invalidX2)
{
//Draw.Text() call for invalidX2
Print("ABOVE200: INVALID " + Instrument.FullName + " at: " + Time[0]);
Draw.Text(this, "AnX2"+CurrentBar, "AnX2", 0, Low[0] - (TickSize*TextOffset), Brushes.Gold);
}
}
//BELOW200 condition
else if(CrossBelow(ema50, ema200, 1) && ema20[0] < ema50[0])
{
validX2 = true;
invalidX2 = false;
//check if market price is equal or higher than ema20
if(Close[0] >= ema20[0])
{
invalidX2 = true;
validX2 = false;
}
else if(validX2 && !invalidX2)
{
//original Draw.Text() call
Print("BELOW200: VALID " + Instrument.FullName + " at: " + Time[0]);
Draw.Text(this, "BV-X2"+CurrentBar, "BV-X2", 0, Low[0] - (TickSize*TextOffset), Brushes.Green);
}
else if (!validX2 && invalidX2)
{
//Draw.Text() call for invalidX2
Print("BELOW200: INVALID " + Instrument.FullName + " at: " + Time[0]);
Draw.Text(this, "BnX2"+CurrentBar, "BnX2", 0, Low[0] - (TickSize*TextOffset), Brushes.Orange);
}
}
}
}
}
Thanks!
Peter

Comment