Hola buenas días. Me gustaría emplear la herramienta Prorealtime, pero para ello me gustaría tener el indicador que uso muy frecuentemente que es un indicador de divergencias entre el precio y el indicador. Se que en la plataforma 11.0 de prorealtime hay un CCI divergencias, pero lo que me interesa a mi es que siga pintando en el gráfico que la divergencia se sigue cumpliendo….
El indicador está pensado para toda clase de divergencias en cualquier indicador, pero en mi caso solo me interesa el CCI.
Adjunto capturas de pantalla y el código.
Muchas gracias.
//Código
#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;
using System.Net;
using System.IO;
using System.Data.SqlClient;
using System.Collections.ObjectModel;
#endregion
//This namespace holds Indicators in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Indicators
{
#region Clases
public class SignalsDivergencia
{
public DateTime time;
public string direccion;
public string instrumento;
}
public static class DivergenciasSignals
{
private static ObservableCollection _coleccionSignalsDivergencias = new ObservableCollection();
public static ObservableCollection ColeccionSignalsDivergencias
{
get
{
return _coleccionSignalsDivergencias;
}
}
}
#endregion
public class DivergenceSpotterV2 : Indicator
{
private DivergenceSpotter_IndicatorType indicatorType; // Default setting for IndicatorType
private int fastPeriod; // Default setting for FastPeriod
private int slowPeriod; // Default setting for SlowPeriod
private int signalPeriod; // Default setting for SignalPeriod
private int lookbackPeriod; //If “0”, then lookback to first instance of indicator crossing 0 line
//if “>0”, then lookback only that amount of bars
private int barSensitivity; //small values increase divergences, large values decrease
//ideal value is 50% of lookbackPeriod
private bool alerta;
private int bkgopacity;
private int LastSignal;
private int BarOfLastSignal;
// User defined variables (add any user defined variables below)
private int bardiff, i;
private bool DoneSearching, RunInit;
private Brush StripeBackgroundColor;
private Series TheIndicator;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @”Enter the description for your new custom Indicator here.”;
Name = “DivergenceSpotterV2”;
Calculate = Calculate.OnBarClose;
IsOverlay = true;
DisplayInDataBox = true;
DrawOnPricePanel = true;
DrawHorizontalGridLines = true;
DrawVerticalGridLines = true;
PaintPriceMarkers = true;
ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
//Disable this property if your indicator requires custom values that cumulate with each new market data event.
//See Help Guide for additional information.
IsSuspendedWhileInactive = false;
indicatorType = DivergenceSpotter_IndicatorType.CCI; // Default setting for IndicatorType
fastPeriod = 20; // Default setting for FastPeriod
slowPeriod = 26; // Default setting for SlowPeriod
signalPeriod = 9; // Default setting for SignalPeriod
lookbackPeriod = 0; //If “0”, then lookback to first instance of indicator crossing 0 line
//if “>0”, then lookback only that amount of bars
barSensitivity=7; //small values increase divergences, large values decrease
//ideal value is 50% of lookbackPeriod
alerta = false;
bkgopacity = 25;
LastSignal = 0;
BarOfLastSignal=-10;
// User defined variables (add any user defined variables below)
bardiff=0;
DoneSearching = true;
RunInit=true;
AddPlot(new Stroke(Brushes.Blue, 2), PlotStyle.Dot, “BuySignal”);
AddPlot(new Stroke(Brushes.DeepPink, 2), PlotStyle.Dot, “SellSignal”);
}
else if (State == State.Configure)
{
if (RunInit && ChartControl != null)
{
RunInit = false;
IsAutoScale = false;
}
}
else if (State == State.DataLoaded)
{
TheIndicator = new Series(this, MaximumBarsLookBack.Infinite);
}
}
protected override void OnBarUpdate()
{
if(RunInit) return;
int LowestBarIndexPossible = Math.Max(fastPeriod,Math.Max(slowPeriod,lookbackPeriod));
if(CurrentBar < 1+LowestBarIndexPossible) return; if(indicatorType == DivergenceSpotter_IndicatorType.MACD) TheIndicator[0] = MACD(fastPeriod,slowPeriod,signalPeriod)[0]; else if(indicatorType == DivergenceSpotter_IndicatorType.TRIX) TheIndicator[0] = TRIX(slowPeriod,signalPeriod)[0]; else if(indicatorType == DivergenceSpotter_IndicatorType.StochFastK) TheIndicator[0] = StochasticsFast(slowPeriod, fastPeriod).K[0]-50.0; else if(indicatorType == DivergenceSpotter_IndicatorType.StochRSI) TheIndicator[0] = StochRSI(fastPeriod)[0]-0.5; else if(indicatorType == DivergenceSpotter_IndicatorType.CCI) TheIndicator[0] = CCI(fastPeriod)[0]; else if(indicatorType == DivergenceSpotter_IndicatorType.BOP) TheIndicator[0] = BOP(fastPeriod)[0]; else if(indicatorType == DivergenceSpotter_IndicatorType.CMO) TheIndicator[0] = CMO(fastPeriod)[0]; else if(indicatorType == DivergenceSpotter_IndicatorType.ChaikinMoneyFlow) TheIndicator[0] = ChaikinMoneyFlow(fastPeriod)[0]; else if(indicatorType == DivergenceSpotter_IndicatorType.Momentum) TheIndicator[0] = Momentum(fastPeriod)[0]; else if(indicatorType == DivergenceSpotter_IndicatorType.MFI) TheIndicator[0] = MFI(fastPeriod)[0]; else if(indicatorType == DivergenceSpotter_IndicatorType.RSI) TheIndicator[0] = RSI(fastPeriod,signalPeriod)[0]-50; //signalPeriod is here, but is ignored in the divergence calc else if(indicatorType == DivergenceSpotter_IndicatorType.ROC) TheIndicator[0] = ROC(fastPeriod)[0]; else if (indicatorType == DivergenceSpotter_IndicatorType.StochSlowD) TheIndicator[0] = Stochastics(slowPeriod, fastPeriod, signalPeriod).D[0] - 50; else if (indicatorType == DivergenceSpotter_IndicatorType.StochFastD) TheIndicator[0] = StochasticsFast(slowPeriod, fastPeriod).D[0] - 50; else return; double Hprice = double.MinValue; double Lprice = High[0]; double Hindicator = TheIndicator[0]; double Lindicator = TheIndicator[0]; int HPriceBar = -1; int LPriceBar = -1; int LIndicatorBar = -1; int HIndicatorBar = -1; i=1; DoneSearching=false; while(!DoneSearching) { if (High[i]>Hprice) //a new high in price was found, record it
{ Hprice = High[i];
HPriceBar = i; //this is the bar number of the highest price in the lookbackPeriod
}
if(Low[i]Hindicator) //a new high in the indicator was found, record it
{ Hindicator = TheIndicator[i];
HIndicatorBar = i;//this is the bar number of the highest indicator value in the lookbackPeriod
}
if(TheIndicator[i]CurrentBar-LowestBarIndexPossible-1)
DoneSearching =true; //limit of search reached
if(lookbackPeriod==0)//then find the last time the indicator crossed the “0” line
{
if (TheIndicator[i] * TheIndicator[i+1] < 0.0) DoneSearching =true; } else //terminate the search when i has exceeded the lookbackPeriod { if (i > lookbackPeriod)
DoneSearching =true;
}
}
SellSignal[0] = 0;
BuySignal[0] = 0;
BackBrush = null;
if(CurrentBar – BarOfLastSignal > 10) LastSignal=0;
if(TheIndicator[0]>0) //look for sell divergence since Indicator is above ZERO
{
bardiff = HIndicatorBar-HPriceBar; //How many bars separated the highs?
if(bardiff>barSensitivity) {
SellSignal[0] = Low[0]-Math.Max((High[0]-Low[0])/2,5*TickSize);
if (State == State.Realtime && alerta)
{
Print(Time[0] + “–> Sell Signal en –>” + Instrument.MasterInstrument.Name + “–>TimeFrame: ” + BarsPeriod.Value + “–> Precio” + SellSignal[0]);
InsertarSignals(Instrument.MasterInstrument.Name, “DIVERGENCIA”, 0, (decimal)SellSignal[0], “SELL”);
}
if (LastSignal != -1 && bkgopacity > 0)
{
BackBrush = new SolidColorBrush(Color.FromArgb((byte)Math.Round(255.0 * bkgopacity / 10, 0), 255, 51, 153));
//Añadimos la señal a la colección
DivergenciasSignals.ColeccionSignalsDivergencias.Add(new SignalsDivergencia() { time = Time[0], instrumento = Instrument.MasterInstrument.Name, direccion = “SELL” });
if (State == State.Realtime && alerta)
{
Print(“Divergencia detectada<-->Sell>–>” + Instrument.MasterInstrument.Name);
InsertarSignals(Instrument.MasterInstrument.Name, “DIVERGENCIA”, 0, 0, “SELL”);
}
}
LastSignal = -1;
BarOfLastSignal = CurrentBar;
}
}
else //look for Buy divergence since Indicator is below ZERO
{
bardiff = LIndicatorBar-LPriceBar; //How many bars separated the lows?
if(bardiff>barSensitivity) {
BuySignal[0] = High[0]+Math.Max((High[0]-Low[0])/2,5*TickSize);
if (State == State.Realtime && alerta)
{
Print(Time[0] + “–> Buy Signal en –>” + Instrument.MasterInstrument.Name + “–>TimeFrame: ” + BarsPeriod.Value + “–> Precio” + BuySignal[0]);
InsertarSignals(Instrument.MasterInstrument.Name, “DIVERGENCIA”, 0, (decimal)BuySignal[0], “BUY”);
}
if (LastSignal != 1 && bkgopacity > 0)
{
BackBrush = new SolidColorBrush(Color.FromArgb((byte)Math.Round(255.0 * bkgopacity / 10, 0), 0, 0, 255));
DivergenciasSignals.ColeccionSignalsDivergencias.Add(new SignalsDivergencia() { time = Time[0], instrumento = Instrument.MasterInstrument.Name, direccion = “BUY” });
if (State == State.Realtime && alerta)
{
Print(“Divergencia detectada<-->Buy>–>” + Instrument.MasterInstrument.Name);
InsertarSignals(Instrument.MasterInstrument.Name, “DIVERGENCIA”, 0, 0, “BUY”);
}
}
LastSignal = 1;
BarOfLastSignal = CurrentBar;
}
}
}