/Trading/SchemaTrading/tables/Data/CDataList.customisation.cs
C# | 382 lines | 319 code | 29 blank | 34 comment | 51 complexity | 4fd43199b8b1f57e83a0c2951afab144 MD5 | raw file
- using System;
- using System.Text;
- using System.Data;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Web;
-
- using Framework;
-
- namespace SchemaTrading
- {
- //Collection Class (Customisable half)
- public partial class CDataList
- {
- #region Filters
- #endregion
-
- #region Searching (Optional)
- //Represents a simple search box to search PK and any string columns (add overloads as required, based on the pattern below)
- //e.g. public CDataList Search(string nameOrId, int seriesId) { ...
- public CDataList Search(string nameOrId)
- {
- //1. Normalisation
- nameOrId = (nameOrId??string.Empty).Trim().ToLower();
-
- //2. Start with a complete list
- CDataList results = this;
-
- //3. Use any available index, such as those generated for fk/bool columns
- //Normal Case - non-unique index (e.g. foreign key)
- //if (int.MinValue != seriesId) results = results.GetBySeriesId(seriesId);
-
- //Special case - unique index (e.g. primary key)
- /*
- if (!string.IsNullOrEmpty(nameOrId))
- {
- int id;
- if (int.TryParse(nameOrId, out id))
- {
- CData obj = this.GetById(id);
- if (null != obj)
- {
- results = new CDataList(1);
- results.Add(obj);
- return results;
- }
- }
- }
- */
-
- //4. Exit early if remaining (non-index) filters are blank
- if (string.IsNullOrEmpty(nameOrId)) return results;
-
- //5. Manually search each record using custom match logic, building a shortlist
- CDataList shortList = new CDataList();
- foreach (CData i in results)
- if (Match(nameOrId, i))
- shortList.Add(i);
- return shortList;
- }
- //Manual Searching e.g for string-based columns i.e. anything not indexed (add more params if required)
- private bool Match(string name, CData obj)
- {
- if (!string.IsNullOrEmpty(name)) //Match any string column
- {
- return false; //If filter is active, reject any items that dont match
- }
- return true; //No active filters (should catch this in step #4)
- }
- #endregion
-
- #region Cloning
- public CDataList Clone(CDataSrc target) //, int parentId)
- {
- //No Transaction
- if (target is CDataSrcRemote)
- return Clone(target, null); //, parentId);
-
- //Transaction
- using (IDbConnection cn = target.Local.Connection())
- {
- IDbTransaction tx = cn.BeginTransaction();
- try
- {
- CDataList clone = Clone(target, tx); //, parentId);
- tx.Commit();
- return clone;
- }
- catch
- {
- tx.Rollback();
- throw;
- }
- }
- }
- public CDataList Clone(CDataSrc target, IDbTransaction txOrNull) //, int parentId)
- {
- CDataList list = new CDataList(this.Count);
- foreach (CData i in this)
- list.Add(i.Clone(target, txOrNull)); //, parentId)); *Child entities must reference the new parent
- return list;
- }
- #endregion
-
- #region Export to Csv
- //Web - Need to add a project reference to System.Web, or comment out these two methods
- public void ExportToCsv(HttpResponse response, string fileName, List<EData> columns, List<EDecision> decisions)
- {
- CDataSrc.ExportToCsv(response, fileName); //Standard response headers
- StreamWriter sw = new StreamWriter(response.OutputStream);
- ExportToCsv(sw, columns, decisions);
- sw.Flush();
- response.End();
- }
-
- //Non-web
- public void ExportToCsv(string filePath, List<EData> columns, List<EDecision> decisions)
- {
- StreamWriter sw = new StreamWriter(filePath);
- ExportToCsv(sw, columns, decisions);
- sw.Close();
- }
-
- //Logic
- protected void ExportToCsv(StreamWriter sw, List<EData> columns, List<EDecision> decisions)
- {
- List<string> headings = new List<string>(1 + columns.Count + decisions.Count);
- headings.Add("Date");
- foreach (EData i in columns)
- headings.Add(i.ToString());
- foreach (EDecision i in decisions)
- headings.Add(string.Concat(i, " (", CData.GetTooltip(i), ")"));
-
- CDataSrc.ExportToCsv(headings.ToArray(), sw);
- foreach (CData d in this)
- {
- List<object> data = new List<object>(1 + columns.Count + decisions.Count);
- data.Add(d.DataDate.ToString("d-MMM-yyyy"));
- foreach (EData i in columns)
- data.Add(d.GetData(i));
- foreach (EDecision i in decisions)
- data.Add(d.GetDecision(i));
- CDataSrc.ExportToCsv(data.ToArray(), sw);
- }
- }
- #endregion
-
- #region Custom
- public DateTime MinDate { get { return Count == 0 ? DateTime.MinValue : this[0].DataDate; } }
- public DateTime MaxDate { get { return Count == 0 ? DateTime.MinValue : this[Count - 1].DataDate; } }
- public TimeSpan TimeSpan { get { return Count == 0 ? TimeSpan.MinValue : MaxDate.AddDays(1).Subtract(MinDate); } }
- public int TotalDays { get { return (int)TimeSpan.TotalDays; } }
- #endregion
-
-
-
- #region Foreign-Key Indices (Subsets)
- //Index by DataSeriesId
- public CDataList GetBySeriesId(int seriesId)
- {
- CDataList temp = null;
- if (!IndexBySeriesId.TryGetValue(seriesId, out temp))
- {
- temp = new CDataList();
- IndexBySeriesId[seriesId] = temp;
- }
- return temp;
- }
-
- [NonSerialized]
- private Dictionary<int, CDataList> _indexBySeriesId;
- private Dictionary<int, CDataList> IndexBySeriesId
- {
- get
- {
- if (null == _indexBySeriesId)
- {
- Dictionary<int, CDataList> index = new Dictionary<int, CDataList>();
- CDataList temp = null;
- foreach (CData i in this)
- {
- if (!index.TryGetValue(i.DataSeriesId, out temp))
- {
- temp = new CDataList();
- index[i.DataSeriesId] = temp;
- }
- temp.Add(i);
- }
- _indexBySeriesId = index;
- foreach (CDataList i in index.Values)
- i.DoCalcs();
- }
- return _indexBySeriesId;
- }
- }
- #endregion
-
- #region Date Index
- public CData GetByDate(DateTime date)
- {
- CData c = null;
- IndexByDate.TryGetValue(date, out c);
- return c;
- }
- [NonSerialized]
- private Dictionary<DateTime, CData> _indexByDate;
- private Dictionary<DateTime, CData> IndexByDate
- {
- get
- {
- if (null != _indexByDate && _indexByDate.Count == this.Count)
- return _indexByDate;
-
- _indexByDate = new Dictionary<DateTime, CData>(this.Count);
- foreach (CData i in this)
- _indexByDate[i.DataDate] = i;
- return _indexByDate;
- }
- }
- #endregion
-
-
- #region Trading Simulation
- public void DoCalcs()
- {
- lock (this)
- {
- foreach (CData i in this)
- {
- i.ClearAllCalcs();
- i.Prev = Prev(i);
- i.Next = Next(i);
- if (null == i.Prev)
- i.Simulation = new CSimulation(i);
- else
- i.Simulation = new CSimulation(i.Prev.Simulation, i);
- }
- }
- }
-
- public CData Last { get { return 0 == Count ? null : this[this.Count - 1]; } }
- public CData Prev(CData d)
- {
- int index = this.IndexOf(d);
- if (-1 == index)
- index = this.IndexOf(this.GetById(d.DataId));
- if (0 == index)
- return null;
- return this[index - 1];
- }
- public CData Next(CData d)
- {
- int index = this.IndexOf(d);
- if (-1 == index)
- index = this.IndexOf(this.GetById(d.DataId));
- if (this.Count - 1 == index)
- return null;
- return this[index + 1];
- }
-
- public double SimulatedTotal { get { return null == Last ? CSimulation.LEVERAGE * CSimulation.START : this.Last.SimulatedTotal; } }
- public double SimulatedProfit { get { return SimulatedTotal - CSimulation.LEVERAGE * CSimulation.START; } }
- public double SimulatedReturns { get { return SimulatedProfit / CSimulation.START; } }
- public double AnnualisedReturns { get { return Math.Pow(1 + SimulatedReturns, 365.0 / TotalDays) - 1; } }
- public double ExposureAdjustedReturns { get { return AnnualisedReturns / (AverageExposure * CSimulation.LEVERAGE); } }
- private double _avgExp = double.NaN;
- public double AverageExposure
- {
- get
- {
- if (double.IsNaN(_avgExp))
- {
- double total = 0;
- foreach (CData i in this)
- total += i.Simulation.Exposure;
- _avgExp = total / Count;
- }
- return _avgExp;
- }
- }
- private double _maxExp = double.NaN;
- public double MaxExposure
- {
- get
- {
- if (double.IsNaN(_maxExp))
- {
- double max = 0;
- foreach (CData i in this)
- max = Math.Max(max, i.Simulation.Exposure);
- _maxExp = max;
- }
- return _maxExp;
- }
- }
- private double _sumClosing = double.NaN;
- public double SumClosing
- {
- get
- {
- if (double.IsNaN(_sumClosing))
- {
- double sum = 0;
- foreach (CData i in this)
- sum += i.DataClose;
- _sumClosing = sum;
- }
- return _sumClosing;
- }
- }
- private double _sumSquaresClosing = double.NaN;
- public double SumSquaresClosing
- {
- get
- {
- if (double.IsNaN(_sumSquaresClosing))
- {
- double sum = 0;
- foreach (CData i in this)
- sum += Math.Pow(i.DataClose, 2);
- _sumSquaresClosing = sum;
- }
- return _sumSquaresClosing;
- }
- }
- public double MeanClosing { get { return SumClosing / Count; } }
- public double VolatilityClosing { get { return (SumSquaresClosing / Count) - Math.Pow(MeanClosing, 2); } }
- public double StdDevClosing { get { return Math.Sqrt(VolatilityClosing); } }
-
- private int _wins = int.MinValue;
- private int _losses = int.MinValue;
- private int _flat = int.MinValue;
- public int Wins { get { if (int.MinValue == _wins) DoCount(); return _wins; } }
- public int Losses { get { if (int.MinValue == _losses)DoCount(); return _losses; } }
- public int Flat { get { if (int.MinValue == _flat) DoCount(); return _flat; } }
- public double WinsPercent { get { return (double)Wins / (double)Count; } }
- public double LossesPercent { get { return (double)Losses / (double)Count; } }
- public double FlatPercent { get { return (double)Flat / (double)Count; } }
- private void DoCount()
- {
- if (this.Count == 0)
- return;
- lock (this)
- {
- _wins = 0;
- _losses = 0;
- _flat = 0;
- foreach (CData i in this)
- if (double.IsNaN(i.Returns) || 0 == i.Returns)
- _flat += 1;
- else if (i.Returns > 0)
- _wins += 1;
- else
- _losses += 1;
- }
- }
-
- private double _low = double.NaN;
- private double _high = double.NaN;
- public double Low { get { if (double.IsNaN(_low)) DoHighLow(); return _low; } }
- public double High { get { if (double.IsNaN(_high)) DoHighLow(); return _high; } }
- private void DoHighLow()
- {
- if (this.Count == 0)
- return;
- lock (this)
- {
- _low = double.PositiveInfinity;
- _high = 0;
- foreach (CData i in this)
- if (_low > i.SimulatedTotal)
- _low = i.SimulatedTotal;
- else if (_high < i.SimulatedTotal)
- _high = i.SimulatedTotal;
- }
- }
- #endregion
-
-
- }
- }