/// <summary> /// Returns a y-axis that is suitable for drawing this plot. /// </summary> /// <returns>A suitable y-axis.</returns> public Axis SuggestYAxis() { CandleDataAdapter candleData = new CandleDataAdapter(this.DataSource, this.DataMember, this.AbscissaData, this.OpenData, this.LowData, this.HighData, this.CloseData); return(candleData.SuggestYAxis()); }
/// <summary> /// Calculates the physical (not world) separation between abscissa values. /// </summary> /// <param name="cd">Candle adapter containing data</param> /// <param name="xAxis">Physical x axis the data is plotted against.</param> /// <returns>physical separation between abscissa values.</returns> private static float CalculatePhysicalSeparation(CandleDataAdapter cd, PhysicalAxis xAxis) { if (cd.Count > 1) { int xPos1 = (int)(xAxis.WorldToPhysical(((PointOLHC)cd[0]).X, false)).X; int xPos2 = (int)(xAxis.WorldToPhysical(((PointOLHC)cd[1]).X, false)).X; int minDist = xPos2 - xPos1; if (cd.Count > 2) { // to be pretty sure we get the smallest gap. int xPos3 = (int)(xAxis.WorldToPhysical(((PointOLHC)cd[2]).X, false)).X; if (xPos3 - xPos2 < minDist) { minDist = xPos3 - xPos2; } if (cd.Count > 3) { int xPos4 = (int)(xAxis.WorldToPhysical(((PointOLHC)cd[3]).X, false)).X; if (xPos4 - xPos3 < minDist) { minDist = xPos4 - xPos3; } } } return(minDist); } return(0.0f); }
/// <summary> /// Returns a y-axis that is suitable for drawing this plot. /// </summary> /// <returns>A suitable y-axis.</returns> public Axis SuggestYAxis() { CandleDataAdapter candleData = new CandleDataAdapter(DataSource, DataMember, AbscissaData, OpenData, LowData, HighData, CloseData); return(candleData.SuggestYAxis()); }
/// <summary> /// Draws the candle plot on a GDI+ surface agains the provided x and y axes. /// </summary> /// <param name="g">The GDI+ surface on which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public void Draw(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis) { CandleDataAdapter cd = new CandleDataAdapter(this.DataSource, this.DataMember, this.AbscissaData, this.OpenData, this.LowData, this.HighData, this.CloseData); Brush bearishBrush = new SolidBrush(BearishColor); Brush bullishBrush = new SolidBrush(BullishColor); uint offset = 0; if (this.centered_) { offset = (uint)(CalculatePhysicalSeparation(cd, xAxis) / 2.0f); } uint addAmount = (uint)StickWidth / 2; uint stickWidth = (uint)StickWidth; if (StickWidth == AutoScaleStickWidth) { // default addAmount = 2; stickWidth = 4; float minDist = CalculatePhysicalSeparation(cd, xAxis); addAmount = (uint)(minDist / 3); stickWidth = addAmount * 2; } Pen p = new Pen(this.color_); /* * // brant hyatt proposed. * if (this.Style == Styles.Stick) * { * p.Width = stickWidth; * addAmount = stickWidth + 2; * } */ for (int i = 0; i < cd.Count; ++i) { PointOLHC point = (PointOLHC)cd[i]; if ((!double.IsNaN(point.Open)) && (!double.IsNaN(point.High)) && (!double.IsNaN(point.Low)) && (!double.IsNaN(point.Close))) { int xPos = (int)(xAxis.WorldToPhysical(point.X, false)).X; if (xPos + offset + addAmount < xAxis.PhysicalMin.X || xAxis.PhysicalMax.X < xPos + offset - addAmount) { continue; } int yPos1 = (int)(yAxis.WorldToPhysical(point.Low, false)).Y; int yPos2 = (int)(yAxis.WorldToPhysical(point.High, false)).Y; int yPos3 = (int)(yAxis.WorldToPhysical(point.Open, false)).Y; int yPos4 = (int)(yAxis.WorldToPhysical(point.Close, false)).Y; if (this.Style == Styles.Stick) { /* * // brant hyatt proposed. * if (i > 0) * { * if ( ((PointOLHC)cd[i]).Close > ((PointOLHC)cd[i-1]).Close) * { * p.Color = BullishColor; * } * else * { * p.Color = BearishColor; * } * } */ g.DrawLine(p, xPos + offset, yPos1, xPos + offset, yPos2); g.DrawLine(p, xPos - addAmount + offset, yPos3, xPos + offset, yPos3); g.DrawLine(p, xPos + offset, yPos4, xPos + addAmount + offset, yPos4); } else if (this.Style == Styles.Filled) { g.DrawLine(p, xPos + offset, yPos1, xPos + offset, yPos2); if (yPos3 > yPos4) { g.FillRectangle(bullishBrush, xPos - addAmount + offset, yPos4, stickWidth, yPos3 - yPos4); g.DrawRectangle(p, xPos - addAmount + offset, yPos4, stickWidth, yPos3 - yPos4); } else if (yPos3 < yPos4) { g.FillRectangle(bearishBrush, xPos - addAmount + offset, yPos3, stickWidth, yPos4 - yPos3); g.DrawRectangle(p, xPos - addAmount + offset, yPos3, stickWidth, yPos4 - yPos3); } else { g.DrawLine(p, xPos - addAmount + offset, yPos3, xPos - addAmount + stickWidth + offset, yPos3); } } } } }
/// <summary> /// /// </summary> /// <param name="d"></param> /// <returns></returns> public override CandleStyle Create(CandleDataAdapter d) { return(new Stick()); }
/// <summary> /// /// </summary> /// <param name="d"></param> /// <returns></returns> public abstract CandleStyle Create(CandleDataAdapter d);
/// <summary> /// /// </summary> /// <param name="d"></param> /// <returns></returns> public override CandleStyle Create(CandleDataAdapter d) { return new Stick (); }
/// <summary> /// /// </summary> /// <param name="d"></param> /// <returns></returns> public abstract CandleStyle Create(CandleDataAdapter d);
/// <summary> /// Calculates the physical (not world) separation between abscissa values. /// </summary> /// <param name="cd">Candle adapter containing data</param> /// <param name="xAxis">Physical x axis the data is plotted against.</param> /// <returns>physical separation between abscissa values.</returns> private static double CalculatePhysicalSeparation(CandleDataAdapter cd, PhysicalAxis xAxis) { if (cd.Count > 1) { double xPos1 = (xAxis.WorldToPhysical( ((PointOLHC)cd[0]).X, false )).X; double xPos2 = (xAxis.WorldToPhysical( ((PointOLHC)cd[1]).X, false )).X; double minDist = xPos2 - xPos1; if (cd.Count > 2) { // to be pretty sure we get the smallest gap. double xPos3 = (xAxis.WorldToPhysical(((PointOLHC)cd[2]).X, false)).X; if (xPos3 - xPos2 < minDist) { minDist = xPos3 - xPos2; } if (cd.Count > 3) { double xPos4 = (xAxis.WorldToPhysical(((PointOLHC)cd[3]).X, false)).X; if (xPos4 - xPos3 < minDist) { minDist = xPos4 - xPos3; } } } return minDist; } return 0; }
/// <summary> /// Returns a Y-axis that is suitable for drawing this plot. /// </summary> public Axis SuggestYAxis() { CandleDataAdapter candleData = new CandleDataAdapter (DataSource, DataMember, AbscissaData, OpenData, LowData, HighData, CloseData); return candleData.SuggestYAxis (); }
/// <summary> /// Draws the candle plot with the specified Drawing Context and X,Y axes /// </summary> /// <param name="ctx">The Drawing Context with which to draw</param> /// <param name="xAxis">The physical X-Axis to draw against</param> /// <param name="yAxis">The physical Y-Axis to draw against</param> public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis) { CandleDataAdapter cd = new CandleDataAdapter (DataSource, DataMember, AbscissaData, OpenData, LowData, HighData, CloseData); double offset = 0; if (Centered) { offset = CalculatePhysicalSeparation (cd,xAxis)/2; } double addAmount = StickWidth/2; double stickWidth = StickWidth; if (StickWidth == AutoScaleStickWidth) { // default addAmount = 2; stickWidth = 4; double minDist = CalculatePhysicalSeparation (cd, xAxis); addAmount = minDist / 3; stickWidth = addAmount * 2; } ctx.Save (); ctx.SetLineWidth (1); /* // brant hyatt proposed. if (Style == Styles.Stick) { p.Width = stickWidth; addAmount = stickWidth + 2; } */ for (int i=0; i<cd.Count; ++i) { PointOLHC point = (PointOLHC)cd [i]; if ((!double.IsNaN (point.Open)) && (!double.IsNaN(point.High)) && (!double.IsNaN (point.Low)) && (!double.IsNaN(point.Close))) { double xPos = (xAxis.WorldToPhysical (point.X, false)).X; if (xPos + offset + addAmount < xAxis.PhysicalMin.X || xAxis.PhysicalMax.X < xPos + offset - addAmount) { continue; } double yLo = (yAxis.WorldToPhysical (point.Low, false)).Y; double yHi = (yAxis.WorldToPhysical (point.High, false)).Y; double yOpn = (yAxis.WorldToPhysical (point.Open, false)).Y; double yCls = (yAxis.WorldToPhysical (point.Close,false)).Y; if (Style == Styles.Stick) { /* // brant hyatt proposed. if (i > 0) { if ( ((PointOLHC)cd[i]).Close > ((PointOLHC)cd[i-1]).Close) { p.Color = BullishColor; } else { p.Color = BearishColor; } } */ ctx.SetColor (Color); ctx.MoveTo (xPos+offset, yLo); ctx.LineTo (xPos+offset, yHi); // Low to High line ctx.MoveTo (xPos-addAmount+offset, yOpn); ctx.LineTo (xPos+offset, yOpn); // Open line ctx.MoveTo (xPos+addAmount+offset, yCls); ctx.LineTo (xPos+offset, yCls); // Close line ctx.Stroke (); } else if (Style == Styles.Filled) { ctx.MoveTo (xPos+offset, yLo); ctx.LineTo (xPos+offset, yHi); ctx.Stroke (); if (yOpn > yCls) { ctx.SetColor (BullishColor); ctx.Rectangle (xPos-addAmount+offset, yCls, stickWidth, yOpn - yCls); ctx.FillPreserve (); ctx.SetColor (Color); ctx.Stroke (); } else if (yOpn < yCls) { ctx.SetColor (BearishColor); ctx.Rectangle (xPos-addAmount+offset, yOpn, stickWidth, yCls - yOpn); ctx.FillPreserve (); ctx.SetColor (Color); ctx.Stroke (); } else { // Cls == Opn ctx.MoveTo (xPos-addAmount+offset, yOpn); ctx.LineTo (xPos-addAmount+stickWidth+offset, yCls); ctx.Stroke (); } } } } ctx.Restore (); }
/// <summary> /// Returns a y-axis that is suitable for drawing this plot. /// </summary> /// <returns>A suitable y-axis.</returns> public Axis SuggestYAxis() { CandleDataAdapter candleData = new CandleDataAdapter( this.DataSource, this.DataMember, this.AbscissaData, this.OpenData, this.LowData, this.HighData, this.CloseData ); return candleData.SuggestYAxis(); }
/// <summary> /// Draws the candle plot on a GDI+ surface agains the provided x and y axes. /// </summary> /// <param name="g">The GDI+ surface on which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { CandleDataAdapter cd = new CandleDataAdapter( this.DataSource, this.DataMember, this.AbscissaData, this.OpenData, this.LowData, this.HighData, this.CloseData ); Brush bearishBrush = new SolidBrush( BearishColor ); Brush bullishBrush = new SolidBrush( BullishColor ); uint offset = 0; if (this.centered_) { offset = (uint)(CalculatePhysicalSeparation(cd,xAxis) / 2.0f); } uint addAmount = (uint)StickWidth/2; uint stickWidth = (uint)StickWidth; if (StickWidth == AutoScaleStickWidth) { // default addAmount = 2; stickWidth = 4; float minDist = CalculatePhysicalSeparation( cd, xAxis ); addAmount = (uint)(minDist / 3); stickWidth = addAmount * 2; } Pen p = new Pen(this.color_); /* // brant hyatt proposed. if (this.Style == Styles.Stick) { p.Width = stickWidth; addAmount = stickWidth + 2; } */ for (int i=0; i<cd.Count; ++i) { PointOLHC point = (PointOLHC)cd[i]; if ( (!double.IsNaN (point.Open)) && (!double.IsNaN(point.High)) && (!double.IsNaN (point.Low)) && (!double.IsNaN(point.Close)) ) { int xPos = (int)(xAxis.WorldToPhysical( point.X, false )).X; if (xPos + offset + addAmount < xAxis.PhysicalMin.X || xAxis.PhysicalMax.X < xPos + offset - addAmount) { continue; } int yPos1 = (int)(yAxis.WorldToPhysical( point.Low, false )).Y; int yPos2 = (int)(yAxis.WorldToPhysical( point.High, false )).Y; int yPos3 = (int)(yAxis.WorldToPhysical( point.Open, false )).Y; int yPos4 = (int)(yAxis.WorldToPhysical( point.Close, false )).Y; if (this.Style == Styles.Stick) { /* // brant hyatt proposed. if (i > 0) { if ( ((PointOLHC)cd[i]).Close > ((PointOLHC)cd[i-1]).Close) { p.Color = BullishColor; } else { p.Color = BearishColor; } } */ g.DrawLine( p, xPos+offset, yPos1, xPos+offset, yPos2 ); g.DrawLine( p, xPos-addAmount+offset, yPos3, xPos+offset, yPos3 ); g.DrawLine( p, xPos+offset, yPos4, xPos+addAmount+offset, yPos4 ); } else if (this.Style == Styles.Filled) { g.DrawLine( p, xPos+offset, yPos1, xPos+offset, yPos2 ); if (yPos3 > yPos4) { g.FillRectangle( bullishBrush, xPos-addAmount+offset, yPos4, stickWidth, yPos3 - yPos4 ); g.DrawRectangle( p, xPos-addAmount+offset, yPos4, stickWidth, yPos3 - yPos4 ); } else if (yPos3 < yPos4) { g.FillRectangle( bearishBrush, xPos-addAmount+offset, yPos3, stickWidth, yPos4 - yPos3 ); g.DrawRectangle( p, xPos-addAmount+offset, yPos3, stickWidth, yPos4 - yPos3 ); } else { g.DrawLine( p, xPos-addAmount+offset, yPos3, xPos-addAmount+stickWidth+offset, yPos3 ); } } } } }
/// <summary> /// Draws the candle plot with the specified Drawing Context and X,Y axes /// </summary> /// <param name="ctx">The Drawing Context with which to draw</param> /// <param name="xAxis">The physical X-Axis to draw against</param> /// <param name="yAxis">The physical Y-Axis to draw against</param> public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis) { CandleDataAdapter cd = new CandleDataAdapter(DataSource, DataMember, AbscissaData, OpenData, LowData, HighData, CloseData); double offset = 0; if (Centered) { offset = CalculatePhysicalSeparation(cd, xAxis) / 2; } double addAmount = StickWidth / 2; double stickWidth = StickWidth; if (StickWidth == AutoScaleStickWidth) { // default addAmount = 2; stickWidth = 4; double minDist = CalculatePhysicalSeparation(cd, xAxis); addAmount = minDist / 3; stickWidth = addAmount * 2; } ctx.Save(); ctx.SetLineWidth(1); /* * // brant hyatt proposed. * if (Style == Styles.Stick) * { * p.Width = stickWidth; * addAmount = stickWidth + 2; * } */ for (int i = 0; i < cd.Count; ++i) { PointOLHC point = (PointOLHC)cd [i]; if ((!double.IsNaN(point.Open)) && (!double.IsNaN(point.High)) && (!double.IsNaN(point.Low)) && (!double.IsNaN(point.Close))) { double xPos = (xAxis.WorldToPhysical(point.X, false)).X; if (xPos + offset + addAmount < xAxis.PhysicalMin.X || xAxis.PhysicalMax.X < xPos + offset - addAmount) { continue; } double yLo = (yAxis.WorldToPhysical(point.Low, false)).Y; double yHi = (yAxis.WorldToPhysical(point.High, false)).Y; double yOpn = (yAxis.WorldToPhysical(point.Open, false)).Y; double yCls = (yAxis.WorldToPhysical(point.Close, false)).Y; if (Style == Styles.Stick) { /* * // brant hyatt proposed. * if (i > 0) * { * if ( ((PointOLHC)cd[i]).Close > ((PointOLHC)cd[i-1]).Close) * { * p.Color = BullishColor; * } * else * { * p.Color = BearishColor; * } * } */ ctx.SetColor(Color); ctx.MoveTo(xPos + offset, yLo); ctx.LineTo(xPos + offset, yHi); // Low to High line ctx.MoveTo(xPos - addAmount + offset, yOpn); ctx.LineTo(xPos + offset, yOpn); // Open line ctx.MoveTo(xPos + addAmount + offset, yCls); ctx.LineTo(xPos + offset, yCls); // Close line ctx.Stroke(); } else if (Style == Styles.Filled) { ctx.MoveTo(xPos + offset, yLo); ctx.LineTo(xPos + offset, yHi); ctx.Stroke(); if (yOpn > yCls) { ctx.SetColor(BullishColor); ctx.Rectangle(xPos - addAmount + offset, yCls, stickWidth, yOpn - yCls); ctx.FillPreserve(); ctx.SetColor(Color); ctx.Stroke(); } else if (yOpn < yCls) { ctx.SetColor(BearishColor); ctx.Rectangle(xPos - addAmount + offset, yOpn, stickWidth, yCls - yOpn); ctx.FillPreserve(); ctx.SetColor(Color); ctx.Stroke(); } else // Cls == Opn { ctx.MoveTo(xPos - addAmount + offset, yOpn); ctx.LineTo(xPos - addAmount + stickWidth + offset, yCls); ctx.Stroke(); } } } } ctx.Restore(); }