
//
// Copyright (C) 2019, Order Flow Analytics Inc <www.orderflowanalytics.com>.
// OFA reserves the right to modify or overwrite this NinjaScript component with each release.
//
// By installing, using in whole or in part any sample code from Order Flow Analytics you agree to fully indemnify and hold harmless OrderFlowAnalytics, Inc 
// and its affiliates from and against any claims, losses, liabilities and expenses that may be incurred 
// as a result having downloaded and/or used any or all of the available code.
// Do thoroughly test any code & modifications for indicators and strategies in Replay Test mode

#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 NinjaTrader.OFA;
#endregion

//This namespace holds Indicators in this folder and is required. Do not change it. 
namespace NinjaTrader.NinjaScript.Indicators
{
	public class OFASampleBarsVolumesAtPriceAccess : Indicator
	{
		private OFAIndicatorSTCORE OFAIndicatorSTCORE1;
		
		double low_diag_bid=0.0;						
		double low_diag_ask=0.0;
		double high_diag_ask=0.0;
		double high_diag_bid=0.0;
		
		private struct OFA_BA_Volume
		{
			public double volume;
			public double sell_volume;
			public double buy_volume;
			public bool   isBidAlert;
			public bool   isOfferAlert;
		}
		
		// List only for the current bar being processed and market data updating .. gets cleared on first tick of bar 
		
		private SortedList<double, OFA_BA_Volume> _ofa_ba_v = new SortedList<double, OFA_BA_Volume>();
		
		protected override void OnStateChange()
		{
			if (State == State.SetDefaults)
			{
				Description									= @"OFA Sample Inidcator to show accessing bar volumes at price";
				Name										= "OFASampleBarsVolumesAtPriceAccess";
				Calculate									= Calculate.OnBarClose;
				IsOverlay									= true;
				DisplayInDataBox							= true;
				DrawOnPricePanel							= true;
				DrawHorizontalGridLines						= false;
				DrawVerticalGridLines						= false;
				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					= true;

			}
			else if (State == State.Configure)
			{
						
				;
			}
			
			else if (State == State.DataLoaded)
			{				
				
				OFAIndicatorSTCORE1				= OFAIndicatorSTCORE(Close, 30, 70, OFAColorLogic.POC);
			}
		}

		protected override void OnBarUpdate()
		{
			//Add your custom indicator logic here
			// For any indicator loaded into Bloodhound - can only be BarsInProgress == 0 ie the Primary Data Series
			
			if (BarsInProgress != 0) 
				return;

			if (CurrentBars[0] < 1)
				return;
			
			if (State == State.Historical)
				return;
			
			
			if (IsFirstTickOfBar)
			{	
				// Store the data for the bar just closed before clearing if you want to reference the bar data after
				// processing the data structure to store the new live bar
				
				_ofa_ba_v.Clear();
			}
				
			//Print("OFA Bar Price Ind printing price group FOR Loop index ");
			
			// It is recommended to use the for loop below for accessing the data
			// for comparison have included commented out foreach alternative of this : the foreach can result in collection modified
			// error sometimes so just be aware of this.
			
			for (int index = 0; index < OFAIndicatorSTCORE1.BarPrice.Count() ; index++)
            {

                var rowitem = OFAIndicatorSTCORE1.BarPrice.ElementAt(index);
				
				if (_ofa_ba_v.ContainsKey(Instrument.MasterInstrument.RoundToTickSize(rowitem.Price)))
				{
					OFA_BA_Volume tmp=new OFA_BA_Volume();
					tmp.buy_volume= rowitem.BuyVolume;
					tmp.sell_volume= rowitem.SellVolume;
					tmp.isBidAlert= rowitem.IsBidAlert;
					tmp.isOfferAlert= rowitem.IsOfferAlert;
					tmp.volume= rowitem.BuyVolume+rowitem.SellVolume;
					_ofa_ba_v[Instrument.MasterInstrument.RoundToTickSize(rowitem.Price)]=tmp;
				}
				else
				{
					OFA_BA_Volume tmp=new OFA_BA_Volume();
					tmp.buy_volume= rowitem.BuyVolume;
					tmp.sell_volume= rowitem.SellVolume;
					tmp.volume= rowitem.BuyVolume+rowitem.SellVolume;
					tmp.isBidAlert= rowitem.IsBidAlert;
					tmp.isOfferAlert= rowitem.IsOfferAlert;
					_ofa_ba_v.Add(Instrument.MasterInstrument.RoundToTickSize(rowitem.Price),tmp);
				}
				
				// Example to extract the High Bid price 1 tick below High
		        // and Low Ask / Offer price 1 tick above low
		
				if (Instrument.MasterInstrument.RoundToTickSize(Low[0]) == Instrument.MasterInstrument.RoundToTickSize(rowitem.Price)) {
						Print(" Low = ");
						Print(rowitem.Price);
						low_diag_bid=rowitem.SellVolume;
				}
				if (Instrument.MasterInstrument.RoundToTickSize(Low[0]+TickSize) == Instrument.MasterInstrument.RoundToTickSize(rowitem.Price)) {
					Print(" Low + ticksize = ");
					Print(rowitem.Price);
					low_diag_ask=rowitem.BuyVolume;
				}
				
				if (Instrument.MasterInstrument.RoundToTickSize(High[0]) == Instrument.MasterInstrument.RoundToTickSize(rowitem.Price)) {
					Print(" High = ");
					Print(rowitem.Price);
					high_diag_ask=rowitem.BuyVolume;	
				}
				if (Instrument.MasterInstrument.RoundToTickSize(High[0]-TickSize) == Instrument.MasterInstrument.RoundToTickSize(rowitem.Price)) {
					Print(" High - ticksize = ");
					Print(rowitem.Price);
					high_diag_bid=rowitem.SellVolume;
				}
				
				Print(Time[0]);
				Print(rowitem.SellVolume);
				Print(rowitem.BuyVolume);
				Print(rowitem.IsBidAlert);
				Print(rowitem.IsOfferAlert);
				Print(rowitem.Price);
			}
					
			
			
			// The following is alternative to process the price rows
			// be aware in certain instances collection modified error can arise
			// and so the above for loop is recommended
			
//			foreach (OFACOREBarPrice bprice in OFAIndicatorSTCORE1.BarPrice)
//			{
				
				
//					if (_ofa_ba_v.ContainsKey(Instrument.MasterInstrument.RoundToTickSize(bprice.Price)))
//					{
//						OFA_BA_Volume tmp=new OFA_BA_Volume();
//						tmp.buy_volume= bprice.BuyVolume;
//						tmp.sell_volume= bprice.SellVolume;
//						tmp.isBidAlert= bprice.IsBidAlert;
//						tmp.isOfferAlert= bprice.IsOfferAlert;
//						tmp.volume= bprice.BuyVolume+bprice.SellVolume;
//						_ofa_ba_v[Instrument.MasterInstrument.RoundToTickSize(bprice.Price)]=tmp;
//					}
//					else
//					{
//						OFA_BA_Volume tmp=new OFA_BA_Volume();
//						tmp.buy_volume= bprice.BuyVolume;
//						tmp.sell_volume= bprice.SellVolume;
//						tmp.volume= bprice.BuyVolume+bprice.SellVolume;
//						tmp.isBidAlert= bprice.IsBidAlert;
//						tmp.isOfferAlert= bprice.IsOfferAlert;
//						_ofa_ba_v.Add(Instrument.MasterInstrument.RoundToTickSize(bprice.Price),tmp);
//					}
					
//					// Example to extract the High Bid price 1 tick below High
//			        // and Low Ask / Offer price 1 tick above low
			
//					if (Instrument.MasterInstrument.RoundToTickSize(Low[0]) == Instrument.MasterInstrument.RoundToTickSize(bprice.Price)) {
//							Print(" Low = ");
//							Print(bprice.Price);
//							low_diag_bid=bprice.SellVolume;
//					}
//					if (Instrument.MasterInstrument.RoundToTickSize(Low[0]+TickSize) == Instrument.MasterInstrument.RoundToTickSize(bprice.Price)) {
//						Print(" Low + ticksize = ");
//						Print(bprice.Price);
//						low_diag_ask=bprice.BuyVolume;
//					}
					
//					if (Instrument.MasterInstrument.RoundToTickSize(High[0]) == Instrument.MasterInstrument.RoundToTickSize(bprice.Price)) {
//						Print(" High = ");
//						Print(bprice.Price);
//						high_diag_ask=bprice.BuyVolume;	
//					}
//					if (Instrument.MasterInstrument.RoundToTickSize(High[0]-TickSize) == Instrument.MasterInstrument.RoundToTickSize(bprice.Price)) {
//						Print(" High - ticksize = ");
//						Print(bprice.Price);
//						high_diag_bid=bprice.SellVolume;
//					}
					
//					Print(Time[0]);
//					Print(bprice.SellVolume);
//					Print(bprice.BuyVolume);
//					Print(bprice.IsBidAlert);
//					Print(bprice.IsOfferAlert);
//					Print(bprice.Price);
//			}
			
		
		}

		#region Properties


		#endregion
		

	}
}

#region NinjaScript generated code. Neither change nor remove.

namespace NinjaTrader.NinjaScript.Indicators
{
	public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
	{
		private OFASampleBarsVolumesAtPriceAccess[] cacheOFASampleBarsVolumesAtPriceAccess;
		public OFASampleBarsVolumesAtPriceAccess OFASampleBarsVolumesAtPriceAccess()
		{
			return OFASampleBarsVolumesAtPriceAccess(Input);
		}

		public OFASampleBarsVolumesAtPriceAccess OFASampleBarsVolumesAtPriceAccess(ISeries<double> input)
		{
			if (cacheOFASampleBarsVolumesAtPriceAccess != null)
				for (int idx = 0; idx < cacheOFASampleBarsVolumesAtPriceAccess.Length; idx++)
					if (cacheOFASampleBarsVolumesAtPriceAccess[idx] != null &&  cacheOFASampleBarsVolumesAtPriceAccess[idx].EqualsInput(input))
						return cacheOFASampleBarsVolumesAtPriceAccess[idx];
			return CacheIndicator<OFASampleBarsVolumesAtPriceAccess>(new OFASampleBarsVolumesAtPriceAccess(), input, ref cacheOFASampleBarsVolumesAtPriceAccess);
		}
	}
}

namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
{
	public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
	{
		public Indicators.OFASampleBarsVolumesAtPriceAccess OFASampleBarsVolumesAtPriceAccess()
		{
			return indicator.OFASampleBarsVolumesAtPriceAccess(Input);
		}

		public Indicators.OFASampleBarsVolumesAtPriceAccess OFASampleBarsVolumesAtPriceAccess(ISeries<double> input )
		{
			return indicator.OFASampleBarsVolumesAtPriceAccess(input);
		}
	}
}

namespace NinjaTrader.NinjaScript.Strategies
{
	public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
	{
		public Indicators.OFASampleBarsVolumesAtPriceAccess OFASampleBarsVolumesAtPriceAccess()
		{
			return indicator.OFASampleBarsVolumesAtPriceAccess(Input);
		}

		public Indicators.OFASampleBarsVolumesAtPriceAccess OFASampleBarsVolumesAtPriceAccess(ISeries<double> input )
		{
			return indicator.OFASampleBarsVolumesAtPriceAccess(input);
		}
	}
}

#endregion
