using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Globalization;
using System.Xml;
using TradeIdeas.XML;
using System.IO;
using TradeIdeas.MiscSupport;
namespace TradeIdeas.TIProGUI
{
public class Bar
{
private DateTime _date;
public DateTime Date
{
get { return _date; }
set
{
_date = value;
_displayDate = _date.ToString(_dateTimeFormat);
}
}
private string _dateTimeFormat = "MMM d, yyyy";
public string DateTimeFormat
{
get { return _dateTimeFormat; }
set
{
_dateTimeFormat = value;
_displayDate = Date.ToString(_dateTimeFormat);
}
}
private string _displayDate;
///
/// Suitable for display for the user.
///
public string DisplayDate
{
get { return _displayDate; }
set { _displayDate = value; }
}
///
/// Suitable for adding directly to the chart. Order is high, low, close, open
///
public double[] Values;
public int Volume = 0;
public Bar(DateTime date, double high, double low, double open, double close, int volume = 0)
{
Date = date;
Values = new double[] { high, low, close, open };
Volume = volume;
}
public Bar(XmlNode definition)
{
Values = new double[] { 0.00, 0.00, 0.00, 0.00 };
Restore(definition);
}
public double High { get { return Values[0]; } set { Values[0] = value; } }
public double Low { get { return Values[1]; } set { Values[1] = value;} }
public double Close { get { return Values[2]; } set { Values[2] = value;} }
public double Open { get { return Values[3]; } set { Values[3] = value;} }
public Color Color()
{
return Color(System.Drawing.Color.Green, System.Drawing.Color.Red, System.Drawing.Color.Black);
}
public static readonly Color FADED_RED = System.Drawing.Color.FromArgb(128 + 64, 128, 128);
public static readonly Color FADED_GREEN = System.Drawing.Color.FromArgb(128, 128 + 64, 128);
public static readonly Color FADED_BLACK = System.Drawing.Color.FromArgb(128, 128, 128);
public Color FadedColor()
{
return Color(FADED_GREEN, FADED_RED, FADED_BLACK);
}
public Color Color(Color up, Color down, Color flat)
{
double open = Open;
double close = Close;
if (close > open)
return up;
else if (close < open)
return down;
else
return flat;
}
public void Restore(XmlNode definition)
{
string dateTimeString = definition.Property("DATETIME", "");
if (dateTimeString != "")
{
DateTime dt;
if (DateTime.TryParse(dateTimeString, out dt))
Date = dt;
}
Open = definition.Property("OPEN", 0.00);
High = definition.Property("HIGH", 0.00);
Low = definition.Property("LOW", 0.00);
Close = definition.Property("CLOSE", 0.00);
}
public void Save(XmlNode parent)
{
parent.SetProperty("DATETIME", Date);
parent.SetProperty("OPEN", Open);
parent.SetProperty("HIGH", High);
parent.SetProperty("LOW", Low);
parent.SetProperty("CLOSE", Close);
}
}
public delegate void InstrumentDataReadyHandler(Instrument instrument);
public class Instrument
{
public event InstrumentDataReadyHandler InstrumentDataReady;
public String Symbol { get; private set; }
public String Description { get; private set; }
private decimal _last = 0;
///
/// Last Price for this instrument
///
public decimal Last
{
get { return _last; }
set
{
_last = value;
if (null != InstrumentDataReady)
InstrumentDataReady(this);
}
}
///
/// Last time a quote was updated for this instrument
///
public DateTime QuoteUpdated { get; set; }
public decimal Bid { get; set; }
public decimal Ask { get; set; }
public int AskSize { get; set; }
public int BidSize { get; set; }
public decimal YesterdayClose { get; set; }
public decimal ChangeLastSixty { get; set; }
public decimal ChangeLastFifteen { get; set; }
public decimal ChangeLastFive { get; set; }
private double? _smartStop = null;
///
/// Smart stop as retrieved by an alert or a TopListRequest.
///
public double? SmartStop
{
get { return _smartStop; }
set { _smartStop = value; }
}
///
/// Minimum price increment for this security.
///
public double? MinMove { get; set; }
private List _bars = new List();
public List Bars
{
get { return _bars; }
private set { _bars = value; }
}
///
/// Day 0 is the first day of the consolidation.
/// FirstDay will be negative. It is the first day for which we can provide data.
///
public int FirstDay { get; private set; }
///
/// This is the last day for which we have data.
/// This should be positive, and therefore part of the consolidation pattern.
///
public int LastDay
{
get
{
return _bars.Count + FirstDay - 1;
}
}
///
/// This describes the day.
/// If we don't have information about this day, we try to extrapolate based on the
/// first or last day that we do know about.
///
/// Which day to find. 0 is the first day of the consolidation.
///
public Bar GetDay(int day)
{
return GetFromZero(day - FirstDay);
}
///
/// This describes the day.
/// If we don't have information about this day, we try to extrapolate based on the
/// first or last day that we do know about.
///
/// Which day to find. 0 is the first day of history.
///
public Bar GetFromZero(int index)
{
if (index < 0)
{
Bar result = _bars[0];
result.DisplayDate = "";
return result;
}
if (index >= _bars.Count)
{
Bar result = _bars[_bars.Count - 1];
result.DisplayDate = "";
return result;
}
return _bars[index];
}
public Instrument(string symbol)
{
Symbol = symbol;
}
public Instrument(string symbol, string description, Bar[] data)
{
Symbol = symbol;
Description = description;
_bars = new List(data);
}
public Instrument(string symbol, string description, string historicalData)
{
Symbol = symbol;
Description = description;
ParseHistoricalData(historicalData);
}
public override bool Equals(System.Object obj)
{
// If parameter is null return false.
if (obj == null)
{
return false;
}
// If parameter cannot be cast to Point return false.
Instrument c = obj as Instrument;
if ((System.Object)c == null)
{
return false;
}
// Return true if the fields match:
return (Symbol == c.Symbol);
}
public bool Equals(Instrument c)
{
// If parameter is null return false:
if ((object)c == null)
{
return false;
}
// Return true if the fields match:
return (Symbol == c.Symbol);
}
public override int GetHashCode()
{
return Symbol.GetHashCode();
}
public double? SimpleMovingAverage(int periods, DateTime? referenceDate = null)
{
if (_bars.Count < periods)
return null;
if (null == referenceDate)
return _bars.Skip(_bars.Count - periods).Average(x => x.Close);
else
{
List appropriateBars = _bars.Where(x => x.Date <= referenceDate).ToList();
if (appropriateBars.Count < periods)
return null;
else
return appropriateBars.Skip(appropriateBars.Count - periods).Average(x => x.Close);
}
}
private void ParseHistoricalData(string historicalData)
{
_bars.Clear();
using (StringReader sr = new StringReader(historicalData))
{
string line;
while ((line = sr.ReadLine()) != null)
{
string[] fields = line.Split('\t');
DateTime date;
if (!DateTime.TryParseExact(fields[0], "MMM d, yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
continue;
double open = 0;
if (!ServerFormats.TryParse(fields[1], out open))
continue;
double high = 0;
if (!ServerFormats.TryParse(fields[2], out high))
continue;
double low = 0;
if (!ServerFormats.TryParse(fields[3], out low))
continue;
double close = 0;
if (!ServerFormats.TryParse(fields[4], out close))
continue;
int volume = 0;
string volumeString = fields[5].Replace(",", "");
if (!ServerFormats.TryParse(volumeString, out volume))
continue;
Bar bar = new Bar(date, high, low, open, close, volume);
_bars.Insert(0, bar);
}
}
}
public override string ToString()
{
return Symbol;
}
public static readonly Instrument CELL = new Instrument("CELL", "Brightpoint Inc. (NASDAQ)", new Bar[]{
new Bar(new DateTime(2012, 6, 14), 5.09, 4.98, 5.02, 5.05),
new Bar(new DateTime(2012, 6, 15), 5.1, 4.9, 5.02, 4.91),
new Bar(new DateTime(2012, 6, 18), 4.95, 4.78, 4.86, 4.81),
new Bar(new DateTime(2012, 6, 19), 4.85, 4.71, 4.83, 4.76),
new Bar(new DateTime(2012, 6, 20), 4.81, 4.69, 4.77, 4.74),
new Bar(new DateTime(2012, 6, 21), 4.74, 4.57, 4.71, 4.59),
new Bar(new DateTime(2012, 6, 22), 4.77, 4.63, 4.64, 4.74),
new Bar(new DateTime(2012, 6, 25), 4.74, 4.56, 4.68, 4.56),
new Bar(new DateTime(2012, 6, 26), 4.64, 4.51, 4.6, 4.51),
new Bar(new DateTime(2012, 6, 27), 5.28, 4.56, 4.56, 5.24),
new Bar(new DateTime(2012, 6, 28), 6.19, 5.21, 5.21, 5.56),
new Bar(new DateTime(2012, 6, 29), 5.75, 5, 5.62, 5.41),
new Bar(new DateTime(2012, 7, 2), 9.01, 8.78, 8.85, 9.01),
new Bar(new DateTime(2012, 7, 3), 8.94, 8.86, 8.87, 8.87),
new Bar(new DateTime(2012, 7, 5), 8.93, 8.87, 8.87, 8.89),
new Bar(new DateTime(2012, 7, 6), 8.92, 8.87, 8.88, 8.89),
new Bar(new DateTime(2012, 7, 9), 8.99, 8.87, 8.88, 8.9),
new Bar(new DateTime(2012, 7, 10), 8.95, 8.89, 8.94, 8.9),
new Bar(new DateTime(2012, 7, 11), 8.94, 8.84, 8.9, 8.84),
new Bar(new DateTime(2012, 7, 12), 8.9, 8.84, 8.87, 8.86)
});
public static readonly Instrument BWMS = new Instrument("BWMS", "Blackwater Midstream Corp. (OTC BB)", new Bar[] {
new Bar(new DateTime(2012, 6, 14), 0.5, 0.5, 0.5, 0.5),
new Bar(new DateTime(2012, 6, 15), 0.5, 0.5, 0.5, 0.5),
new Bar(new DateTime(2012, 6, 18), 0.5, 0.5, 0.5, 0.5),
new Bar(new DateTime(2012, 6, 19), 0.49, 0.49, 0.49, 0.49),
new Bar(new DateTime(2012, 6, 20), 0.49, 0.49, 0.49, 0.49),
new Bar(new DateTime(2012, 6, 21), 0.5, 0.49, 0.5, 0.49),
new Bar(new DateTime(2012, 6, 22), 0.48, 0.48, 0.48, 0.48),
new Bar(new DateTime(2012, 6, 25), 0.48, 0.42, 0.42, 0.44),
new Bar(new DateTime(2012, 6, 26), 0.5, 0.44, 0.45, 0.5),
new Bar(new DateTime(2012, 6, 27), 0.5, 0.5, 0.5, 0.5),
new Bar(new DateTime(2012, 6, 28), 0.54, 0.4, 0.54, 0.53),
new Bar(new DateTime(2012, 6, 29), 0.62, 0.53, 0.55, 0.61),
new Bar(new DateTime(2012, 7, 2), 0.61, 0.61, 0.61, 0.61),
new Bar(new DateTime(2012, 7, 3), 0.62, 0.61, 0.61, 0.61),
new Bar(new DateTime(2012, 7, 5), 0.61, 0.6, 0.6, 0.61),
new Bar(new DateTime(2012, 7, 6), 0.62, 0.61, 0.61, 0.61),
new Bar(new DateTime(2012, 7, 9), 0.61, 0.61, 0.61, 0.61),
new Bar(new DateTime(2012, 7, 10), 0.61, 0.61, 0.61, 0.61),
new Bar(new DateTime(2012, 7, 11), 0.61, 0.6, 0.6, 0.61),
new Bar(new DateTime(2012, 7, 12), 0.61, 0.6, 0.61, 0.61)
});
public static readonly Instrument HRG = new Instrument("HRG", "Harbinger Group Inc. (NYSE)", new Bar[]{
new Bar(new DateTime(2012, 6, 14), 6.83, 6.23, 6.35, 6.8),
new Bar(new DateTime(2012, 6, 15), 7.07, 6.82, 6.83, 6.96),
new Bar(new DateTime(2012, 6, 18), 7.44, 6.52, 6.95, 7.29),
new Bar(new DateTime(2012, 6, 19), 7.37, 6.92, 7.31, 7.15),
new Bar(new DateTime(2012, 6, 20), 7.1, 6.89, 7.1, 7.1),
new Bar(new DateTime(2012, 6, 21), 7.24, 6.86, 7.1, 7.08),
new Bar(new DateTime(2012, 6, 22), 7.71, 7.02, 7.05, 7.37),
new Bar(new DateTime(2012, 6, 25), 8.33, 7.04, 7.22, 7.97),
new Bar(new DateTime(2012, 6, 26), 8.1, 6.33, 8, 6.93),
new Bar(new DateTime(2012, 6, 27), 7.4, 6.61, 6.79, 7.02),
new Bar(new DateTime(2012, 6, 28), 7.27, 6.78, 6.93, 7.2),
new Bar(new DateTime(2012, 6, 29), 7.84, 7.31, 7.31, 7.79),
new Bar(new DateTime(2012, 7, 2), 8.04, 7.8, 7.86, 8.02),
new Bar(new DateTime(2012, 7, 3), 8.14, 8, 8.08, 8.09),
new Bar(new DateTime(2012, 7, 5), 8.14, 8.01, 8.1, 8.05),
new Bar(new DateTime(2012, 7, 6), 8.09, 7.78, 7.95, 8.04),
new Bar(new DateTime(2012, 7, 9), 8.15, 8, 8.06, 8.12),
new Bar(new DateTime(2012, 7, 10), 8.13, 8, 8.13, 8.06),
new Bar(new DateTime(2012, 7, 11), 8.19, 7.89, 8.05, 8.08),
new Bar(new DateTime(2012, 7, 12), 8.19, 7.9, 7.99, 8.11)
});
public static readonly Instrument[] SAMPLES = new Instrument[] { CELL, BWMS, HRG };
private static readonly Random _random = new Random();
public static Instrument RANDOM_SAMPLE { get { return Instrument.SAMPLES[_random.Next() % Instrument.SAMPLES.Length]; } }
}
}