Last active
November 20, 2024 21:19
-
-
Save danielnegri/3fcf483d0862ae05ef4e9411011bfcb3 to your computer and use it in GitHub Desktop.
NinjaTrader 8 - Power Candle Indicator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 PowerCandle : Indicator | |
{ | |
private EMA fastMA; | |
private SMA sma20; | |
private SMA volSMA; | |
private int drawnRanges; | |
private const int LIMIT_DRAWN_RANGES = 255; | |
protected override void OnStateChange() | |
{ | |
if (State == State.SetDefaults) | |
{ | |
Description = @"Displays power candles."; | |
Name = "Power Candle"; | |
Calculate = Calculate.OnBarClose; | |
IsOverlay = true; | |
VolumePeriod = 20; | |
//Disable this property if your indicator requires custom values that cumulate with each new market data event. | |
//See Help Guide for additional information. | |
IsSuspendedWhileInactive = true; | |
} | |
else if (State == State.DataLoaded) | |
{ | |
drawnRanges = 10; | |
fastMA = EMA(Close, 9); | |
sma20 = SMA(Close, 20); | |
volSMA = SMA(Volume, VolumePeriod); | |
} | |
} | |
protected override void OnBarUpdate() | |
{ | |
if (CurrentBar < 20) return; | |
// Crossed Moving Averages | |
double high0 = High[0]; | |
double low0 = Low[0]; | |
double open0 = Open[0]; | |
double close0 = Close[0]; | |
bool crossesfastMA = low0 <= fastMA[0] && fastMA[0] <= high0; | |
bool crossesSMA20 = low0 <= sma20[0] && sma20[0] <= high0; | |
bool isUpBar = Open[0] < Close[0]; | |
bool hasBody = Math.Abs(close0 - open0) * 1.67 > (high0 - low0); | |
// Calculate Volume | |
bool aboveVolume = IsRising(volSMA) && Volume[0] > (volSMA[0]); | |
// Bar Brushes | |
if (aboveVolume && hasBody && crossesfastMA && crossesSMA20) | |
{ | |
drawRange(isUpBar, Brushes.DarkViolet); | |
} | |
else if (aboveVolume && hasBody) | |
{ | |
drawRange(isUpBar, isUpBar ? Brushes.Green : Brushes.Red); | |
} | |
} | |
private void setBarBrushes(SolidColorBrush up, SolidColorBrush down, bool isUpBar) | |
{ | |
BarBrushes[0] = isUpBar ? up : down; | |
} | |
private void drawRange(bool isUpBar, SolidColorBrush color) | |
{ | |
string oldTag = "Power Range #" + ((drawnRanges + 1) % LIMIT_DRAWN_RANGES).ToString(); | |
if (DrawObjects[oldTag] != null) RemoveDrawObject(oldTag); | |
int barAgo = 0; | |
double range = Instrument.MasterInstrument.RoundToTickSize(High[barAgo] - Low[barAgo]); | |
string tag = "Power Range #" + drawnRanges.ToString(); | |
drawnRanges = (drawnRanges + 1) % LIMIT_DRAWN_RANGES; | |
double yOffset = 4; | |
double y = isUpBar ? Low[barAgo] - yOffset * TickSize : High[barAgo] + yOffset * TickSize; | |
SimpleFont font = new SimpleFont(); | |
font.Bold = true; | |
font.Size = 8; | |
Draw.Text(this, tag, true, range.ToString(), barAgo, y, 0, color, font, TextAlignment.Center, null, color, 20); | |
} | |
#region Properties | |
[Range(3, int.MaxValue), NinjaScriptProperty] | |
[Display(ResourceType = typeof(Custom.Resource), Name = "Volume Period", GroupName = "NinjaScriptParameters", Order = 0)] | |
public int VolumePeriod | |
{ get; set; } | |
#endregion | |
} | |
} | |
#region NinjaScript generated code. Neither change nor remove. | |
namespace NinjaTrader.NinjaScript.Indicators | |
{ | |
public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase | |
{ | |
private PowerCandle[] cachePowerCandle; | |
public PowerCandle PowerCandle(int volumePeriod) | |
{ | |
return PowerCandle(Input, volumePeriod); | |
} | |
public PowerCandle PowerCandle(ISeries<double> input, int volumePeriod) | |
{ | |
if (cachePowerCandle != null) | |
for (int idx = 0; idx < cachePowerCandle.Length; idx++) | |
if (cachePowerCandle[idx] != null && cachePowerCandle[idx].VolumePeriod == volumePeriod && cachePowerCandle[idx].EqualsInput(input)) | |
return cachePowerCandle[idx]; | |
return CacheIndicator<PowerCandle>(new PowerCandle(){ VolumePeriod = volumePeriod }, input, ref cachePowerCandle); | |
} | |
} | |
} | |
namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns | |
{ | |
public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase | |
{ | |
public Indicators.PowerCandle PowerCandle(int volumePeriod) | |
{ | |
return indicator.PowerCandle(Input, volumePeriod); | |
} | |
public Indicators.PowerCandle PowerCandle(ISeries<double> input , int volumePeriod) | |
{ | |
return indicator.PowerCandle(input, volumePeriod); | |
} | |
} | |
} | |
namespace NinjaTrader.NinjaScript.Strategies | |
{ | |
public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase | |
{ | |
public Indicators.PowerCandle PowerCandle(int volumePeriod) | |
{ | |
return indicator.PowerCandle(Input, volumePeriod); | |
} | |
public Indicators.PowerCandle PowerCandle(ISeries<double> input , int volumePeriod) | |
{ | |
return indicator.PowerCandle(input, volumePeriod); | |
} | |
} | |
} | |
#endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment