.NET
Microsoft Technologies based on the .NET software framework.
3,648 questions
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FinanceChart
{
public partial class MainWindow : Form
{
private DataLoader dataLoader { get; set; }
private List<DataModel> data = new List<DataModel>();
private List<DataModel> dataFiltered = new List<DataModel>();
private List<DataModel> dataNormalized = new List<DataModel>();
private PointF mousePoint { get; set; }
private int dateBorder { get; set; }
private int costBorder { get; set; }
private float volumeHeight { get; set; }
private int heightConst = 16;
private int widthConst = 39;
private DateTime oldest { get; set; }
private DateTime newest { get; set; }
public MainWindow()
{
InitializeComponent();
dateBorder = 100;
costBorder = 130;
PictureBox.Height = this.Height + heightConst;
PictureBox.Width = this.Width + widthConst;
volumeHeight = PictureBox.Height / 5;
dataLoader = new DataLoader();
data = dataLoader.LoadData();
dataFiltered = data;
oldest = data.Aggregate((first, other) => first.date < other.date ? first : other).date;
newest = data.Aggregate((first, other) => first.date > other.date ? first : other).date;
}
private void PictureBox_Paint(object sender, PaintEventArgs e)
{
DrawBackground(e);
NormalizeData();
DrawCursor(e);
DrawGraph(e);
DrawBorder(e);
}
private void PictureBox_Resize(object sender, EventArgs e)
{
PictureBox.Invalidate();
}
private void Form1_Resize(object sender, EventArgs e)
{
PictureBox.Height = this.Height + heightConst;
PictureBox.Width = this.Width + widthConst;
volumeHeight = PictureBox.Height / 5;
}
private void DrawBackground(PaintEventArgs e)
{
int height = this.Height;
Color color = Color.FromArgb(60, Color.Gray);
for (int i = 100; i <= this.Width; i = i + 200)
{
Rectangle rectangle = new Rectangle();
rectangle.X = i;
rectangle.Y = 0;
rectangle.Height = height;
rectangle.Width = 100;
e.Graphics.FillRectangle(new SolidBrush(color), rectangle);
}
}
private void NormalizeData()
{
dataNormalized.Clear();
int grafWidth = PictureBox.Width - costBorder;
int grafHeight = PictureBox.Height - dateBorder;
int itemsPerPixel = (int)Math.Ceiling(Convert.ToDecimal(dataFiltered.Count / grafWidth));
if (itemsPerPixel == 0) itemsPerPixel = 1;
for (int i = 0; i < dataFiltered.Count; i = i + itemsPerPixel)
{
dataNormalized.Add(dataFiltered[i]);
}
dataNormalized.Add(dataFiltered[dataFiltered.Count - 1]);
float highestValue = dataNormalized.Aggregate((first, other) => first.close < other.close ? first : other).close;
float lowestValue = dataNormalized.Aggregate((first, other) => first.close > other.close ? first : other).close;
for (int i = 0; i < dataNormalized.Count; i++)
{
PointF temp = new PointF((float)((float)i / (float)dataNormalized.Count * grafWidth), (((dataNormalized[i].close - lowestValue) / (highestValue - lowestValue)) * (grafHeight - volumeHeight)));
dataNormalized[i].grafPoint = temp;
}
float highestVolume = dataNormalized.Aggregate((first, other) => first.volume < other.volume ? first : other).volume;
float lowestVolume = dataNormalized.Aggregate((first, other) => first.volume > other.volume ? first : other).volume;
for (int i = 0; i < dataNormalized.Count; i++)
{
PointF temp = new PointF(dataNormalized[i].grafPoint.X, ((dataNormalized[i].volume - lowestVolume) / (highestVolume - lowestVolume) * volumeHeight) + grafHeight - volumeHeight);
dataNormalized[i].volumePoint = temp;
}
}
private void DrawGraph(PaintEventArgs e)
{
for (int i = 0; i < dataNormalized.Count; i++)
{
// graph
if (i != dataNormalized.Count - 1)
{
DrawLine(e, dataNormalized[i], dataNormalized[i + 1]);
}
// volume
if (i == 0)
{
DrawVolume(e, dataNormalized[i], true);
}
else if (dataNormalized[i - 1].close < dataNormalized[i].close)
{
DrawVolume(e, dataNormalized[i], true);
}
else
{
DrawVolume(e, dataNormalized[i], false);
}
}
}
private void DrawBorder(PaintEventArgs e)
{
Pen pen = new Pen(Brushes.Black, 2);
Rectangle rectangle = new Rectangle(new Point(0, 0), new Size(PictureBox.Width - this.costBorder, PictureBox.Height - this.dateBorder));
e.Graphics.DrawRectangle(pen, rectangle);
}
private void DrawVolume(PaintEventArgs e, DataModel _data, bool closeHigh)
{
Pen pen = new Pen(Color.FromArgb(100, Color.Green), 2);
if (closeHigh == false)
{
pen = new Pen(Color.FromArgb(100, Color.Red), 2);
}
e.Graphics.DrawLine(pen, new PointF(_data.volumePoint.X, PictureBox.Height - dateBorder), _data.volumePoint);
}
private void DrawLine(PaintEventArgs e, DataModel first, DataModel second)
{
Pen pen = new Pen(Color.Blue, 2);
e.Graphics.DrawLine(pen, first.grafPoint, second.grafPoint);
}
private void DrawCursor(PaintEventArgs e)
{
Pen pen = new Pen(Brushes.Gray);
float[] dashValues = { 5, 5 };
pen.DashPattern = dashValues;
DataModel focusedObject = dataNormalized.Aggregate((x, y) => Math.Abs(x.grafPoint.X - mousePoint.X) < Math.Abs(y.grafPoint.X - mousePoint.X) ? x : y);
focusedObject.focused = true;
e.Graphics.DrawLine(pen, new PointF(focusedObject.grafPoint.X, 0), new PointF(focusedObject.grafPoint.X, PictureBox.Height - this.dateBorder + 5));
e.Graphics.DrawLine(pen, new PointF(0, focusedObject.grafPoint.Y), new PointF(PictureBox.Width - this.costBorder + 5, focusedObject.grafPoint.Y));
Font font = new Font(FontFamily.GenericSansSerif, 7, FontStyle.Bold);
//date
e.Graphics.DrawString(focusedObject.date.ToString("dd/MM/yyyy"), font, Brushes.Black, new PointF(focusedObject.grafPoint.X, PictureBox.Height - this.dateBorder + 5));
//volume
e.Graphics.DrawString(focusedObject.volume.ToString(), font, Brushes.Black, new PointF(focusedObject.grafPoint.X, PictureBox.Height - this.dateBorder - this.volumeHeight / 2));
//close
e.Graphics.DrawString(focusedObject.close.ToString(), font, Brushes.Black, new PointF(PictureBox.Width - this.costBorder + 5, focusedObject.grafPoint.Y));
label1.Text = "Open: " + focusedObject.open;
label2.Text = "High: " + focusedObject.high;
label3.Text = "Low: " + focusedObject.low;
label4.Text = "Close: " + focusedObject.close;
string temp;
if ((float)focusedObject.volume / 1000000 >= 1)
{
temp = (float)focusedObject.volume / 1000000 + " Mil.";
}
else if ((float)focusedObject.volume / 1000 >= 1)
{
temp = (float)focusedObject.volume / 1000 + " Tis.";
}
else
{
temp = focusedObject.volume.ToString();
}
label5.Text = "Volume " + temp;
label8.Text = "% Change: " + Math.Round(((focusedObject.close - focusedObject.open) / focusedObject.open * 100), 2) + "%";
}
private void SetDataBetweenDates(DateTime dateTime1, DateTime dateTime2)
{
dataFiltered = data.Where(x => x.date > dateTime1 && x.date < dateTime2).ToList();
}
private void MainWindow_Load(object sender, EventArgs e)
{
dateTimePicker1.Value = oldest;
dateTimePicker2.Value = newest;
this.Activate();
}
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
if (dateTimePicker1.Value <= oldest)
{
dateTimePicker1.Value = oldest;
}
else if (dateTimePicker1.Value >= newest)
{
dateTimePicker1.Value = newest;
}
else
{
SetDataBetweenDates(dateTimePicker1.Value, dateTimePicker2.Value);
PictureBox.Invalidate();
}
}
private void dateTimePicker2_ValueChanged(object sender, EventArgs e)
{
if (dateTimePicker1.Value <= oldest)
{
dateTimePicker1.Value = oldest;
}
else if (dateTimePicker1.Value >= newest)
{
dateTimePicker1.Value = newest;
}
else
{
SetDataBetweenDates(dateTimePicker1.Value, dateTimePicker2.Value);
PictureBox.Invalidate();
}
}
private void button1_Click(object sender, EventArgs e)
{
dataFiltered = data;
PictureBox.Invalidate();
}
private void PictureBox_MouseMove(object sender, MouseEventArgs e)
{
mousePoint = e.Location;
PictureBox.Invalidate();
}
}
}