ninjatrader/drawing-tools/AnchoredVWAP.cs

198 lines
7.1 KiB
C#
Raw Normal View History

2023-11-03 16:20:45 +00:00
#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 SharpDX.Direct2D1;
#endregion
//This namespace holds Drawing tools in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.DrawingTools
{
public class AnchoredVWAP : DrawingTool
{
private const string ANCHOR_ICON = "\u2693";
private const double MOUSE_PROXIMITY = 15;
public ChartAnchor Anchor { get; set; }
public override IEnumerable<ChartAnchor> Anchors
{
get { return new[] { Anchor }; }
}
private List<SharpDX.Vector2> VWAPVectors;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Anchors a VWAP to the specified bar on the chart";
Name = "Anchored VWAP";
DrawingState = DrawingState.Building;
AnchorBar = 0;
Stroke = new Stroke(Brushes.Yellow, 2f);
if (Anchor == null)
Anchor = new ChartAnchor {
DisplayName = "Anchored VWAP",
DrawingTool = this
};
}
else if (State == State.Terminated)
{
Dispose();
}
}
public override object Icon { get { return ANCHOR_ICON; } }
public override Cursor GetCursor(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, Point point)
{
switch (DrawingState)
{
case DrawingState.Building:
return Cursors.Pen;
case DrawingState.Editing:
ChartAnchor closestAnchor = GetClosestAnchor(chartControl, chartPanel, chartScale, MOUSE_PROXIMITY, point);
return Anchor == closestAnchor ? Cursors.SizeWE : null;
case DrawingState.Moving:
return Cursors.SizeWE;
default:
return null;
}
}
public override Point[] GetSelectionPoints(ChartControl chartControl, ChartScale chartScale)
{
ChartPanel chartPanel = chartControl.ChartPanels[chartScale.PanelIndex];
return new[] { Anchor.GetPoint(chartControl, chartPanel, chartScale, false) };
}
public override void OnBarsChanged() { }
public override void OnCalculateMinMax() { }
public override void OnMouseDown(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, ChartAnchor dataPoint)
{
switch (DrawingState)
{
case DrawingState.Building:
AnchorBar = (int)dataPoint.SlotIndex;
DrawingState = DrawingState.Normal;
IsSelected = false;
break;
case DrawingState.Editing:
Point point = dataPoint.GetPoint(chartControl, chartPanel, chartScale);
ChartAnchor closestAnchor = GetClosestAnchor(chartControl, chartPanel, chartScale, MOUSE_PROXIMITY, point);
if (Anchor == closestAnchor)
DrawingState = DrawingState.Moving;
else
{
DrawingState = DrawingState.Normal;
IsSelected = false;
}
break;
case DrawingState.Normal:
DrawingState = DrawingState.Editing;
IsSelected = true;
break;
default:
break;
}
}
public override void OnMouseMove(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, ChartAnchor dataPoint)
{
switch (DrawingState)
{
case DrawingState.Moving:
AnchorBar = (int)dataPoint.SlotIndex;
break;
default:
break;
}
}
public override void OnMouseUp(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, ChartAnchor dataPoint)
{
switch (DrawingState)
{
case DrawingState.Moving:
DrawingState = DrawingState.Editing;
break;
default:
break;
}
}
public override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
UpdateVWAP(chartControl, chartScale);
AntialiasMode originalAntialiasMode = RenderTarget.AntialiasMode;
RenderTarget.AntialiasMode = AntialiasMode.PerPrimitive;
SharpDX.Direct2D1.PathGeometry VWAPGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
GeometrySink VWAPGeometrySink = VWAPGeometry.Open();
VWAPGeometrySink.BeginFigure(VWAPVectors.First(), FigureBegin.Hollow);
VWAPGeometrySink.AddLines(VWAPVectors.ToArray());
VWAPGeometrySink.EndFigure(FigureEnd.Open);
VWAPGeometrySink.Close();
RenderTarget.DrawGeometry(VWAPGeometry, Stroke.Brush.ToDxBrush(RenderTarget), Stroke.Width);
VWAPGeometry.Dispose();
RenderTarget.AntialiasMode = originalAntialiasMode;
}
private void UpdateVWAP(ChartControl chartControl, ChartScale chartScale)
{
VWAPVectors = new List<SharpDX.Vector2>();
Bars bars = chartControl.BarsArray[0].Bars;
double totalVolume = 0;
double volumeWeightedPrice = 0;
for (int i = AnchorBar; i < bars.Count; i++)
{
double volume = bars.GetVolume(i);
double price = (bars.GetOpen(i) + bars.GetHigh(i) + bars.GetLow(i) + bars.GetClose(i)) / 4;
totalVolume += volume;
volumeWeightedPrice += price * volume;
int x = chartControl.GetXByBarIndex(chartControl.BarsArray[0], i);
int y = chartScale.GetYByValue(volumeWeightedPrice / totalVolume);
VWAPVectors.Add(new SharpDX.Vector2(x, y));
if (i == AnchorBar)
Anchor = CreateAnchor(new Point(x, y), chartControl, chartScale);
}
}
[Display(ResourceType = typeof(Custom.Resource), GroupName = "Anchored VWAP", Name = "Anchor Bar", Order = 1)]
public int AnchorBar { get; set; }
[Display(ResourceType = typeof(Custom.Resource), GroupName = "Anchored VWAP", Name = "AVWAP", Order = 2)]
public Stroke Stroke { get; set; }
}
}