198 lines
7.1 KiB
C#
198 lines
7.1 KiB
C#
#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; }
|
|
|
|
}
|
|
}
|