This commit is contained in:
2024-02-23 06:53:16 -05:00
commit dbdccce727
1094 changed files with 57645 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="SkiaSharp.Views.Forms" Version="1.68.3" />
<PackageReference Include="Xamarin.Essentials" Version="1.5.3.2" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,161 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using MarketData.Utils;
using MarketData.Numerical;
namespace MarketData.MarketDataModel
{
public class BollingerBandElementsByDate : Dictionary<DateTime, BollingerBandElement>
{
public BollingerBandElementsByDate()
{
}
}
public class BollingerBands : BollingerBandElements
{
public BollingerBands()
{
}
public BollingerBands(List<BollingerBandElement> bollingerBandElements)
{
foreach(BollingerBandElement bollingerBandElement in bollingerBandElements)Add(bollingerBandElement);
}
public static String GetHeader(int movingAverageDays)
{
StringBuilder sb = new StringBuilder();
sb.Append("Date,Symbol,Open,High,Low,Close,Volume,SMA(").Append(movingAverageDays).Append("),StDev(").Append(movingAverageDays).Append("),K,L,K-1,L+1");
return sb.ToString();
}
public BollingerBandElementsByDate GetBollingerBandElementsByDate()
{
BollingerBandElementsByDate bollingerBandElementsByDate = new BollingerBandElementsByDate();
for (int index = 0; index < Count; index++)
{
BollingerBandElement bollingerBandElement = this[index];
if (!bollingerBandElementsByDate.ContainsKey(bollingerBandElement.Date)) bollingerBandElementsByDate.Add(bollingerBandElement.Date, bollingerBandElement);
}
return bollingerBandElementsByDate;
}
}
public class BollingerBandElements : List<BollingerBandElement>
{
public BollingerBandElements()
{
}
public BollingerBandElements(List<BollingerBandElement> bollingerBandElements)
{
foreach(BollingerBandElement bollingerBandElement in bollingerBandElements)Add(bollingerBandElement);
}
public LeastSquaresResult LeastSquaresFitClose()
{
double[] closingPrices=(from BollingerBandElement bollingerBandElement in this select bollingerBandElement.Close).ToList().ToArray();
LeastSquaresResult leastSquaresResult=Numerics.LeastSquares(closingPrices);
return leastSquaresResult;
}
}
public class BollingerBandElement
{
private DateTime date;
private String symbol;
private double open;
private double high;
private double low;
private double close;
private long volume;
private double smaN;
private double stdevN;
private double k;
private double l;
private double kl1;
private double lp1;
public BollingerBandElement()
{
}
public DateTime Date
{
get { return date; }
set { date = value; }
}
public String Symbol
{
get { return symbol; }
set { symbol = value; }
}
public double Open
{
get { return open; }
set { open = value; }
}
public double High
{
get { return high; }
set { high = value; }
}
public double Low
{
get { return low; }
set { low = value; }
}
public double Close
{
get { return close; }
set { close = value; }
}
public double SMAN
{
get { return smaN; }
set { smaN = value; }
}
public double StDevN
{
get { return stdevN; }
set { stdevN = value; }
}
public long Volume
{
get { return volume; }
set { volume = value; }
}
public double K
{
get { return k; }
set { k = value; }
}
public double L
{
get { return l; }
set { l = value; }
}
public double KL1
{
get { return kl1; }
set { kl1 = value; }
}
public double LP1
{
get { return lp1; }
set { lp1 = value; }
}
public override String ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(Utility.DateTimeToStringMMSDDSYYYY(Date)).Append(",");
sb.Append(Symbol).Append(",");
sb.Append(Open).Append(",");
sb.Append(High).Append(",");
sb.Append(Low).Append(",");
sb.Append(Close).Append(",");
sb.Append(Volume).Append(",");
sb.Append(SMAN).Append(",");
sb.Append(StDevN).Append(",");
sb.Append(K).Append(",");
sb.Append(L).Append(",");
sb.Append(KL1).Append(",");
sb.Append(LP1);
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MarketData.MarketDataModel
{
public class Constants
{
public const String CONST_ALL ="{All}";
public const String CONST_DASHES = "---";
public const String NA = "N.A.";
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MarketData.MarketDataModel
{
public class GainLossSummaryItemCollection : List<GainLossSummaryItem>
{
public GainLossSummaryItemCollection()
{
}
public GainLossSummaryItemCollection(List<GainLossSummaryItem> gainLossSummaryItemCollection)
{
foreach(GainLossSummaryItem gainLossSummaryItem in gainLossSummaryItemCollection)Add(gainLossSummaryItem);
}
public GainLossSummaryItemCollection SortByChange()
{
GainLossSummaryItemCollection gainLossSummaryCollection=new GainLossSummaryItemCollection((from GainLossSummaryItem gainLossSummaryItem in this orderby gainLossSummaryItem.Date descending,gainLossSummaryItem.Change descending, gainLossSummaryItem.Symbol descending select gainLossSummaryItem).ToList());
return gainLossSummaryCollection;
}
}
public class GainLossSummaryItem
{
public GainLossSummaryItem()
{
}
public DateTime Date{get;set;}
public String Symbol{get;set;}
public String CompanyName{get;set;}
public double CurrentGainLoss{get;set;}
public double PreviousGainLoss{get;set;}
public double Change{get;set;}
public double ChangePercent{get;set;}
public bool HasStopLimit{get;set;}
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace MarketData.MarketDataModel.GainLoss
{
public class DMAValue
{
private DateTime date;
private double value;
private double maValue;
public DMAValue()
{
}
public DMAValue(DateTime date, double value)
{
this.date = date;
this.value = value;
}
public DateTime Date
{
get { return date; }
set { date = value; }
}
public double Value
{
get { return value; }
set { this.value = value; }
}
public double MAValue
{
get { return maValue; }
set { this.maValue = value; }
}
}
}

View File

@@ -0,0 +1,21 @@
using System.Collections.Generic;
namespace MarketData.MarketDataModel.GainLoss
{
public class DMAValues : List<DMAValue>
{
public DMAValues()
{
}
public float[] GetValues(int startIndex, int count)
{
if (startIndex + count > Count) return null;
float[] valuesArray = new float[count];
for (int index = startIndex, arrayIndex = 0; index < startIndex + count; index++, arrayIndex++)
{
valuesArray[arrayIndex] = (float)this[index].Value;
}
return valuesArray;
}
}
}

View File

@@ -0,0 +1,19 @@
using System;
namespace MarketData.MarketDataModel.GainLoss
{
// **************************************************************************************************************************************************************
// *********************************************** G A I N / L O S S C O M P O U N D M O D E L ****************************************
// **************************************************************************************************************************************************************
// This GainLossModel will be used to model the GainLossView in terms of surfacing the Active Gain/Loss, Active Exposure, Active Gain/Loss%, Total Gain/Loss, Total Gain/Loss % data
public class GainLossCompoundModel
{
public DateTime Date{get;set;}
public double ActiveExposure{get;set;}
public double ActiveGainLoss{get;set;}
public double ActiveGainLossPercent{get;set;}
public double TotalGainLoss{get;set;}
public double TotalGainLossPercent{get;set;}
public double TotalDividendsPaid{get;set;}
}
}

View File

@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
namespace MarketData.MarketDataModel.GainLoss
{
// The GainLossCompoundModelCollection contains both the active gain loss and the total gain loss time series data
public class GainLossCompoundModelCollection : List<GainLossCompoundModel>
{
public GainLossCompoundModelCollection()
{
}
public GainLossCompoundModelCollection(List<GainLossCompoundModel> items)
{
foreach(GainLossCompoundModel item in items)Add(item);
}
public GainLossCompoundModelCollection(GainLossCollection activeGainLossCollection,TotalGainLossCollection totalGainLossCollection)
{
if(null==activeGainLossCollection||null==totalGainLossCollection)return;
Dictionary<DateTime,GainLossItem> activeGainLossCollectionByDate=new Dictionary<DateTime,GainLossItem>();
Dictionary<DateTime,TotalGainLossItem> totalGainLossCollectionByDate=new Dictionary<DateTime,TotalGainLossItem>();
foreach(GainLossItem gainLossItem in activeGainLossCollection)if(!activeGainLossCollectionByDate.ContainsKey(gainLossItem.Date))activeGainLossCollectionByDate.Add(gainLossItem.Date,gainLossItem);
foreach(TotalGainLossItem gainLossItem in totalGainLossCollection)if(!totalGainLossCollectionByDate.ContainsKey(gainLossItem.Date))totalGainLossCollectionByDate.Add(gainLossItem.Date,gainLossItem);
List<DateTime> dates=new List<DateTime>(activeGainLossCollectionByDate.Keys);
dates.Sort();
foreach(DateTime date in dates)
{
GainLossItem activeGainLossItem=activeGainLossCollectionByDate[date];
if(!totalGainLossCollectionByDate.ContainsKey(date))continue;
TotalGainLossItem totalGainLossItem=totalGainLossCollectionByDate[date];
GainLossCompoundModel gainLossModel=new GainLossCompoundModel();
gainLossModel.Date=activeGainLossItem.Date;
gainLossModel.ActiveExposure=activeGainLossItem.Exposure;
gainLossModel.ActiveGainLoss=activeGainLossItem.GainLoss;
gainLossModel.ActiveGainLossPercent=activeGainLossItem.GainLossPercent;
gainLossModel.TotalGainLoss=totalGainLossItem.TotalGainLoss;
gainLossModel.TotalGainLossPercent=totalGainLossItem.TotalGainLossPercent;
gainLossModel.TotalDividendsPaid=totalGainLossItem.TotalDividendsPaid;
Add(gainLossModel);
}
}
public DMAValues DMAValuesActiveGainLoss
{
get
{
DMAValues dmaValues = new DMAValues();
foreach (GainLossCompoundModel gainLoss in this)
{
dmaValues.Add(new DMAValue(gainLoss.Date,gainLoss.ActiveGainLoss));
}
return dmaValues;
}
}
public DMAValues DMAValuesTotalGainLoss
{
get
{
DMAValues dmaValues = new DMAValues();
foreach (GainLossCompoundModel gainLoss in this)
{
dmaValues.Add(new DMAValue(gainLoss.Date,gainLoss.TotalGainLoss));
}
return dmaValues;
}
}
public DMAValues DMAValuesActiveGainLossPercent
{
get
{
DMAValues dmaValues = new DMAValues();
foreach (GainLossCompoundModel gainLoss in this)
{
dmaValues.Add(new DMAValue(gainLoss.Date,gainLoss.ActiveGainLossPercent));
}
return dmaValues;
}
}
public DMAValues DMAValuesTotalGainLossPercent
{
get
{
DMAValues dmaValues = new DMAValues();
foreach (GainLossCompoundModel gainLoss in this)
{
dmaValues.Add(new DMAValue(gainLoss.Date,gainLoss.TotalGainLossPercent));
}
return dmaValues;
}
}
}
}

View File

@@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using MarketData.Utils;
namespace MarketData.MarketDataModel.GainLoss
{
// *********************************************************************************************************************************************************************
// ************************************************************************ G A I N L O S S **************************************************************************
// *********************************************************************************************************************************************************************
// This gain loss provides a picture of the Active Gain/Loss. The gain loss on open positions
public class GainLossItem : IComparable
{
private DateTime date;
private double gainLoss;
private double gainLossPercent;
private double exposure;
private double dividends;
private bool valueIsPercent;
public GainLossItem()
{
}
public GainLossItem(DateTime date, double gainLoss,double exposure,bool valueIsPercent)
{
this.date = date;
this.gainLoss = gainLoss;
this.exposure = exposure;
this.valueIsPercent = valueIsPercent;
}
public GainLossItem(DateTime date, double gainLoss,double gainLossPercent,double exposure,bool valueIsPercent)
{
this.date = date;
this.gainLoss = gainLoss;
this.gainLossPercent=gainLossPercent;
this.exposure = exposure;
this.valueIsPercent = valueIsPercent;
}
public GainLossItem(DateTime date, double gainLoss,double gainLossPercent,double exposure,double dividends,bool valueIsPercent)
{
this.date = date;
this.gainLoss = gainLoss;
this.gainLossPercent=gainLossPercent;
this.exposure = exposure;
this.dividends=dividends;
this.valueIsPercent = valueIsPercent;
}
public DateTime Date
{
get { return date; }
}
public double Exposure
{
get
{
return exposure;
}
}
public double GainLoss
{
get { return gainLoss; }
}
public double Dividends
{
get{return dividends;}
}
public double GainLossPercent
{
get { return gainLossPercent; }
}
public bool ValueIsPercent
{
get
{
return valueIsPercent;
}
set
{
valueIsPercent = value;
}
}
public String FormattedGainLoss
{
get
{
if (valueIsPercent) return Utility.FormatNumber(gainLoss);
return Utility.FormatCurrency(gainLoss);
}
}
public int CompareTo(Object obj)
{
if (!obj.GetType().IsInstanceOfType(this)) throw new Exception("Expected GainLoss");
GainLossItem that = (GainLossItem)obj;
return date.CompareTo(that.Date);
}
}
public class GainLossCollection : List<GainLossItem>
{
public GainLossCollection(ICollection<GainLossItem> gainLoss)
: base(gainLoss)
{
}
public DMAValues DMAValues
{
get
{
DMAValues dmaValues = new DMAValues();
foreach (GainLossItem gainLoss in this)
{
dmaValues.Add(new DMAValue(gainLoss.Date,gainLoss.GainLoss));
}
return dmaValues;
}
}
}
}

View File

@@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace MarketData.MarketDataModel.GainLoss
{
// ****************************************************************************************************************************************************
// ********************************************************************** T O T A L G A I N L O S S *************************************************
// ****************************************************************************************************************************************************
// This Gain/Loss provides a picture of the total Gain/Loss. This is Gain/Loss generated by all trades
public class TotalGainLossCollection : List<TotalGainLossItem>
{
public TotalGainLossCollection(ICollection<TotalGainLossItem> gainLoss)
: base(gainLoss)
{
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.IO;
//using MarketData.Utils;
//using System.Collections.ObjectModel;
//using MarketData.Generator.GainLoss;
//using MarketData.DataAccess;
namespace MarketData.MarketDataModel.GainLoss
{
// ****************************************************************************************************************************************************
// ********************************************************************** T O T A L G A I N L O S S *************************************************
// ****************************************************************************************************************************************************
// This Gain/Loss provides a picture of the total Gain/Loss. This is Gain/Loss generated by all trades
public class TotalGainLossItem : IComparable
{
public TotalGainLossItem(DateTime date,double totalGainLoss,double totalGainLossPercent,double totalExposure,double totalMarketValue)
{
Date=date;
TotalGainLoss=totalGainLoss;
TotalExposure=totalExposure;
TotalMarketValue=totalMarketValue;
TotalGainLossPercent=totalGainLossPercent;
}
public TotalGainLossItem(DateTime date,double totalGainLoss,double totalGainLossPercent,double totalExposure,double totalMarketValue,double totalDividendsPaid)
{
Date=date;
TotalGainLoss=totalGainLoss;
TotalExposure=totalExposure;
TotalMarketValue=totalMarketValue;
TotalGainLossPercent=totalGainLossPercent;
TotalDividendsPaid=totalDividendsPaid;
}
public DateTime Date{get;private set;}
public double TotalGainLoss{get;private set;}
public double TotalGainLossPercent{get;private set;}
public double TotalExposure{get;private set;}
public double TotalMarketValue{get;private set;}
public double TotalDividendsPaid{get;private set;}
public int CompareTo(Object obj)
{
if (!obj.GetType().IsInstanceOfType(this)) throw new Exception("Expected GainLoss");
TotalGainLossItem that = (TotalGainLossItem)obj;
return Date.CompareTo(that.Date);
}
}
}

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MarketData.MarketDataModel
{
public class Headlines : List<Headline>
{
}
public class Headline
{
public Headline()
{
}
public Headline(Headline headline)
{
Date=headline.Date;
Symbol=headline.Symbol;
CompanyName=headline.CompanyName;
Entry=headline.Entry;
Modified=headline.Modified;
Source=headline.Source;
}
public Headline(String symbol,DateTime date,String entry)
{
Symbol=symbol;
Date=date;
Entry=entry;
Modified=DateTime.Now;
}
public DateTime Date{get;set;}
public String Symbol{get;set;}
public String CompanyName{get;set;}
public String Entry{get;set;}
public DateTime Modified{get;set;}
public String Source{get;set;}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//using MarketData.Generator;
namespace MarketData.MarketDataModel
{
// These are models that were designed to be consumed by the mobile platform
public class PortfolioTradesWithParityPrice
{
public PortfolioTradesWithParityPrice(PortfolioTrades portfolioTrades, Price parityPrice)
{
Trades = portfolioTrades;
ParityPrice = parityPrice;
}
public Price ParityPrice { get; set; }
public PortfolioTrades Trades { get; set; }
}
// ************************************************************************************
public class GainLossSummaryItemDetail: GainLossSummaryItem
{
public GainLossSummaryItemDetail()
{
}
public GainLossSummaryItemDetail(GainLossSummaryItem gainLossSummaryItem)
{
this.Date=gainLossSummaryItem.Date;
this.Symbol=gainLossSummaryItem.Symbol;
this.CompanyName=gainLossSummaryItem.CompanyName;
this.CurrentGainLoss=gainLossSummaryItem.CurrentGainLoss;
this.PreviousGainLoss=gainLossSummaryItem.PreviousGainLoss;
this.Change=gainLossSummaryItem.Change;
this.ChangePercent=gainLossSummaryItem.ChangePercent;
this.HasStopLimit = gainLossSummaryItem.HasStopLimit;
}
public int Lots{get;set;}
public double Shares{get;set;}
public double Exposure{get;set;}
public double DividendYield{get;set;} // decimal
public double AnnualDividend{get;set;} // amount
public ParityElement ParityElement{get;set;}
public String ParityElementDescription{get{return null==ParityElement?"":ParityElement.ToString();}}
public double AllTimeGainLossPercent{get;set;}
public double PercentDistanceFromAllTimeGainLossPercent{get;set;}
public Price LatestPrice{get;set;}
public double PriceChange{get;set;}
public bool HasStopLimit{get;set;}
}
}

View File

@@ -0,0 +1,96 @@
using System;
using System.Text;
using MarketData.Utils;
using MarketData.MarketDataModel;
namespace MarketData.MarketDataModel
{
public class ModelTrade
{
public enum TradeType { Buy, Sell };
private DateTime tradeDate;
private String symbol;
private int shares;
private double price;
private TradeType tradeType;
private int daysHeld;
private double gainLoss;
private double exposure;
private double returnOnPosition;
private String comment;
public ModelTrade()
{
}
public String Symbol
{
get { return symbol; }
set { symbol = value; }
}
public DateTime TradeDate
{
get { return tradeDate; }
set { tradeDate = value; }
}
public int Shares
{
get { return shares; }
set { shares = value; }
}
public double Price
{
get { return price; }
set { price = value; }
}
public int DaysHeld
{
get { return daysHeld; }
set { daysHeld = value; }
}
public double GainLoss
{
get { return gainLoss; }
set { gainLoss = value; }
}
public double Return
{
get { return returnOnPosition; }
set { returnOnPosition = value; }
}
public double Exposure
{
get { return exposure; }
set { exposure = value; }
}
public String Comment
{
get { return comment; }
set { comment = value; }
}
public ModelTrade.TradeType Type
{
get { return tradeType; }
set { tradeType = value; }
}
public static String Header
{
get
{
return "Date,Buy/Sell,Symbol,Shares,Price,Gain/Loss,Days Held,Comment";
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(Utility.DateTimeToStringMMSDDSYYYY(TradeDate)).Append(",");
sb.Append(tradeType.Equals(ModelTrade.TradeType.Sell) ? "Sell" : "Buy").Append(",");
sb.Append(Symbol).Append(",");
sb.Append(Shares).Append(",");
sb.Append("\"" + String.Format("{0:C}", price) + "\"").Append(",");
sb.Append("\"" + String.Format("{0:C}", gainLoss) + "\"").Append(",");
sb.Append(daysHeld).Append(",");
sb.Append("\"").Append(null!=comment?comment:"").Append("\"");
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MarketData.Utils;
namespace MarketData.MarketDataModel
{
public class ParityElement
{
public String Symbol { get; set; }
public DateTime PricingDate { get; set; }
public double ParityOffsetPrice { get; set; }
public double ParityOffsetPercent { get; set; } // This is not a percent it needs to be multiplied by 100 to be a percentage
public override String ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("Even @").Append(Utility.FormatCurrency(ParityOffsetPrice)).Append(" (").Append(ParityOffsetPercent > 0 ? "+" : "").Append(Utility.FormatPercent(ParityOffsetPercent)).Append(")");
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
//using MarketData.DataAccess;
namespace MarketData.MarketDataModel
{
public class Portfolio
{
private List<ModelTrade> trades = new List<ModelTrade>();
private bool openPosition = false;
private double availableCash;
private double initialCash;
public Portfolio(double initialCash)
{
this.initialCash = this.availableCash = initialCash;
}
public List<ModelTrade> Trades
{
get { return trades; }
set { trades = value; }
}
public double AvailableCash
{
get { return availableCash; }
set { availableCash = value; }
}
public double GetPortfolioReturn(Price priceOpenPosition)
{
return (GetPortfolioValue(priceOpenPosition)-initialCash)/initialCash;
}
// pass in latest price so we can price any open position
public double GetPortfolioValue(Price priceOpenPosition)
{
double cashValue = AvailableCash;
if (0 != trades.Count)
{
ModelTrade lastTrade = trades[trades.Count - 1];
if (lastTrade.Type.Equals(ModelTrade.TradeType.Buy)) cashValue += (lastTrade.Shares * priceOpenPosition.Close);
}
return cashValue;
}
public void Add(ModelTrade trade)
{
trades.Add(trade);
}
public ModelTrade GetLastTrade()
{
return trades[trades.Count - 1];
}
public bool HasOpenPosition
{
get { return openPosition; }
set { openPosition = value; }
}
public int GetTradeCount()
{
return trades.Count;
}
public double GetAverageGainLoss()
{
double totalGainLoss = 0;
for (int index = 0; index < trades.Count; index++)
{
totalGainLoss += trades[index].GainLoss;
}
return totalGainLoss / trades.Count;
}
public int GetAverageHoldingDays()
{
int totalHoldingDays = 0;
int numberOfSellTrades = 0;
for (int index = 0; index < trades.Count; index++)
{
ModelTrade trade = trades[index];
if (trade.Type == ModelTrade.TradeType.Sell)
{
totalHoldingDays += trades[index].DaysHeld;
numberOfSellTrades++;
}
}
return (numberOfSellTrades>0?totalHoldingDays / numberOfSellTrades:0);
}
public int GetMinHoldingDays()
{
int minHoldingDays = Int16.MaxValue;
for (int index = 0; index < trades.Count; index++)
{
ModelTrade trade = trades[index];
int holdingDays = trade.DaysHeld;
if (trade.Type == ModelTrade.TradeType.Sell && holdingDays < minHoldingDays) minHoldingDays = holdingDays;
}
return minHoldingDays;
}
public int GetMaxHoldingDays()
{
int maxHoldingDays =0;
for (int index = 0; index < trades.Count; index++)
{
ModelTrade trade = trades[index];
int holdingDays = trade.DaysHeld;
if (trade.Type==ModelTrade.TradeType.Sell && holdingDays > maxHoldingDays) maxHoldingDays = holdingDays;
}
return maxHoldingDays;
}
}
}

View File

@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MarketData.Utils;
namespace MarketData.MarketDataModel
{
public class PortfolioTrade
{
private int tradeId=-1;
private String symbol;
private DateTime tradeDate;
private double shares;
private double price;
private double commission;
private String buySell;
private String account;
private String status;
private double sellPrice=double.NaN;
private DateTime sellDate=Utility.Epoch;
public int TradeId
{
get {return tradeId ;}
set { tradeId = value; ;}
}
public String Symbol
{
get { return symbol; }
set { symbol = value; }
}
public DateTime TradeDate
{
get { return tradeDate; }
set { tradeDate = value; }
}
public double Shares
{
get { return shares; }
set { shares = value; }
}
public double Exposure()
{
return Price*Shares;
}
public String BuySell
{
get { return buySell; }
set { buySell = value; }
}
public String Status
{
get { return status; }
set { status = value; }
}
public bool IsOpen
{
get { return status.ToUpper().Equals("OPEN"); }
}
public bool IsClosed
{
get { return !IsOpen; }
}
public String Account
{
get { return account; }
set{account=value;}
}
public DateTime SellDate
{
get { return sellDate; }
set { sellDate = value; }
}
public double SellPrice
{
get { return sellPrice;}
set { sellPrice = value;}
}
public double Price
{
get { return price; }
set { price = value; }
}
public double Commission
{
get { return commission; }
set { commission = value; }
}
}
}

View File

@@ -0,0 +1,179 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MarketData.Utils;
namespace MarketData.MarketDataModel
{
public class Position
{
public String Symbol { get; set; }
public double Shares{get;set;}
public double Exposure { get; set; }
public double MarketValue { get; set; }
}
public class PortfolioTrades : List<PortfolioTrade>
{
public PortfolioTrades()
{
}
public PortfolioTrades(List<PortfolioTrade> trades)
{
if(null==trades)return;
for (int index = 0; index < trades.Count; index++) Add(trades[index]);
}
public List<String> Symbols
{
get
{
Dictionary<String, String> uniqueSymbols = new Dictionary<String, String>();
List<String> symbols = new List<String>();
foreach (PortfolioTrade portfolioTrade in this)
{
if (!uniqueSymbols.ContainsKey(portfolioTrade.Symbol)) uniqueSymbols.Add(portfolioTrade.Symbol, portfolioTrade.Symbol);
}
symbols = new List<String>(uniqueSymbols.Values);
symbols.Sort();
return symbols;
}
}
public List<Position> GetPositions(DateTime asOf)
{
List<Position> positions = new List<Position>();
List<String> symbols = Symbols;
foreach (String symbol in symbols) positions.Add(GetPosition(symbol, asOf));
return positions;
}
public Position GetPosition(String symbol,DateTime asof)
{
List<PortfolioTrade> portfolioTrades = new List<PortfolioTrade>();
for (int index = 0; index < Count; index++)
{
PortfolioTrade portfolioTrade = this[index];
if (!portfolioTrade.Symbol.Equals(symbol)) continue;
if (portfolioTrade.IsOpen && portfolioTrade.TradeDate<=asof) { portfolioTrades.Add(portfolioTrade); continue; }
if (portfolioTrade.IsClosed && portfolioTrade.SellDate > asof) { portfolioTrades.Add(portfolioTrade); continue; }
}
if (0 == portfolioTrades.Count) return null;
Position position = new Position();
position.Symbol = symbol;
position.Shares = portfolioTrades.Sum(x => x.Shares);
position.Exposure = portfolioTrades.Sum(x=>x.Shares*x.Price);
return position;
}
public double Exposure(){return this.Sum(x=>x.Exposure());}
public List<String> Accounts
{
get
{
Dictionary<String, String> uniqueAccounts = new Dictionary<String, String>();
List<String> accounts = new List<String>();
foreach (PortfolioTrade portfolioTrade in this)
{
if (!uniqueAccounts.ContainsKey(portfolioTrade.Account)) uniqueAccounts.Add(portfolioTrade.Account, portfolioTrade.Account);
}
accounts = new List<String>(uniqueAccounts.Values);
accounts.Sort();
return accounts;
}
}
public DateTime GetMinTradeDate()
{
DateTime minDate = Utility.Epoch;
minDate = (from portfolioTrade in this select portfolioTrade.TradeDate).Min();
return minDate;
}
public DateTime GetMinTradeDate(String symbol)
{
DateTime minDate=Utility.Epoch;
symbol=symbol.ToUpper();
minDate = (from portfolioTrade in this where portfolioTrade.Symbol.Equals(symbol) select portfolioTrade.TradeDate).Min();
return minDate;
}
// We just want the trades (open or closed) on or before the specified date. This will be used to run a cumulative gain/loss and return
public PortfolioTrades GetTradesOnOrBefore(DateTime date)
{
PortfolioTrades tradesOnOrBefore = new PortfolioTrades();
foreach (PortfolioTrade portfolioTrade in this)
{
if (date >= portfolioTrade.TradeDate) tradesOnOrBefore.Add(portfolioTrade);
}
return tradesOnOrBefore;
}
// This will remove trades that are status='CLOSED' and SELL_DATE=closingDate
// The user of this fucntion would be making the inference that a trade that closed on closingDate should not be seen as part of the holdings.
// For example. The assumption would be that trades that closed on closingDate would not be a part of the portfolio on closingDate
public PortfolioTrades RemoveClosedTradesWhereClosedOn(DateTime closingDate)
{
PortfolioTrades portfolioTrades;
List<PortfolioTrade> removeTrades = (from PortfolioTrade portfolioTrade in this where portfolioTrade.Status.Equals("CLOSED") && portfolioTrade.SellDate.Date.Equals(closingDate.Date) select portfolioTrade).ToList();
if (null != removeTrades && 0 != removeTrades.Count) portfolioTrades = new PortfolioTrades(this.Except(removeTrades).ToList());
else portfolioTrades = this;
return portfolioTrades;
}
public PortfolioTrades GetOpenTradesOn(DateTime date)
{
PortfolioTrades openTrades = new PortfolioTrades();
foreach (PortfolioTrade portfolioTrade in this)
{
if (Utility.Epoch.Equals(portfolioTrade.SellDate)) // No sell date so trade is open
{
if (date >= portfolioTrade.TradeDate) openTrades.Add(portfolioTrade);
}
else // sell date is not epoch so see if date is in between tradedate and selldate
{
if (date >= portfolioTrade.TradeDate && date < portfolioTrade.SellDate) openTrades.Add(portfolioTrade); // assume that if the sell date is equal to date then the position is closed
}
}
return openTrades;
}
public bool HasOpenPositions(String symbol)
{
int openTrades=(from PortfolioTrade portfolioTrade in this where portfolioTrade.Symbol.Equals(symbol) && portfolioTrade.IsOpen select portfolioTrade).Count();
return openTrades>0?true:false;
}
public bool HasOpenPositionsOn(String symbol,DateTime dateTime)
{
PortfolioTrades portfolioTrades=GetOpenTradesOn(dateTime);
int numTrades=(from PortfolioTrade portfolioTrade in portfolioTrades where portfolioTrade.Symbol.Equals(symbol) select portfolioTrade).Count();
return numTrades>0?true:false;
}
// This method relies on the fact that BreakoutTrades method in PortfolioDA.GetTradesSymbol() creates pairs of BUY and SELL legs with paired legs sharing the same TradeId.
// The open trades will show up with count==1 when we group them by TradeId
public PortfolioTrades GetOpenTrades()
{
if(0==Count)return new PortfolioTrades();
PortfolioTrades openTrades=new PortfolioTrades((from PortfolioTrade trade in this select trade).GroupBy(x=>x.TradeId).Where(grouping=>grouping.Count()==1).Select(grouping=>grouping.FirstOrDefault()).ToList());
return openTrades;
}
public PortfolioTrades FilterAccount(String account)
{
PortfolioTrades portfolioTrades = new PortfolioTrades();
foreach (PortfolioTrade portfolioTrade in this)
{
if (portfolioTrade.Account.Equals(account)) portfolioTrades.Add(portfolioTrade);
}
return portfolioTrades;
}
public PortfolioTrades FilterAccount(List<String> accounts)
{
PortfolioTrades portfolioTrades = new PortfolioTrades();
foreach (PortfolioTrade portfolioTrade in this)
{
if(accounts.Any(x=>x.Equals(portfolioTrade.Account)))portfolioTrades.Add(portfolioTrade);
}
return portfolioTrades;
}
public PortfolioTrades FilterSymbol(String symbol)
{
PortfolioTrades portfolioTrades = new PortfolioTrades();
foreach (PortfolioTrade portfolioTrade in this)
{
if (portfolioTrade.Symbol.Equals(symbol)) portfolioTrades.Add(portfolioTrade);
}
return portfolioTrades;
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
namespace MarketData.MarketDataModel
{
public class PositionWithDescription : MarketDataModel.Position
{
public PositionWithDescription()
{
}
public PositionWithDescription(MarketDataModel.Position position, String companyName, String description)
{
if (null == position || null == description) return;
this.Symbol = position.Symbol;
this.Shares = position.Shares;
this.MarketValue = position.MarketValue;
this.Exposure = position.Exposure;
this.Description = description;
this.CompanyName = companyName;
}
public String Description { get; set; }
public String CompanyName { get; set; }
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
namespace MarketData.MarketDataModel
{
public class PremarketElement
{
public String Market { get; set; }
public double ChangePercent { get; set; }
public double ChangeValue { get; set; }
public DateTime Timestamp { get; set; }
}
public class PremarketElements:List<PremarketElement>
{
public PremarketElements()
{
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
namespace MarketData.MarketDataModel
{
public class PriceIndex
{
public String Code{get;set;}
public String Name{get;set;}
public double Value{get;set;}
public DateTime AsOf{get;set;}
public String Source{get;set;}
}
public class PriceIndices : List<PriceIndex>
{
public PriceIndices()
{
}
public PriceIndices(List<PriceIndex> priceIndices)
{
foreach(PriceIndex priceIndex in priceIndices)
{
Add(priceIndex);
}
}
}
}

View File

@@ -0,0 +1,448 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using MarketData.Utils;
using MarketData.Numerical;
//using MarketData.DataAccess;
namespace MarketData.MarketDataModel
{
public class PricesByDate : Dictionary<DateTime, Price>
{
private DateTime maxDate=Utility.Epoch;
private DateTime minDate=Utility.Epoch;
public PricesByDate()
{
}
public new void Add(DateTime key,Price price)
{
base.Add(key,price);
if(key>maxDate)maxDate=key;
else if(Utility.IsEpoch(minDate))minDate=key;
else if(key<minDate)minDate=key;
}
public DateTime MaxDate
{
get{return maxDate;}
}
public DateTime MinDate
{
get{return minDate;}
}
}
public class PriceComparerDesc : IComparer<Price>
{
public int Compare(Price p1, Price p2)
{
if (p1.Date < p2.Date) return -1;
else if (p1.Date > p2.Date) return 1;
return 0;
}
}
// Throughout the application it is assumed that these collections, when populated, be be in descending date order.
public class Prices : List<Price>
{
public Prices()
{
}
public Prices(Price[] prices)
{
foreach (Price price in prices) Add(price);
}
public Prices(List<Price> prices)
{
foreach(Price price in prices)Add(price);
}
public Prices(String strCSV,String symbol)
{
String[] csvLines = strCSV.Split('\n');
Clear();
for (int index = 1; index < csvLines.Length; index++)
{
if (csvLines[index].Length < 1) continue;
String[] lineItems = csvLines[index].Split(',');
Price price = new Price();
String[] dateParts = lineItems[0].Split('-');
try { price.Date = new DateTime(int.Parse(dateParts[0]), int.Parse(dateParts[1]), int.Parse(dateParts[2])); }
catch (Exception /*exception*/)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("'{0}' does not contain a date", lineItems[0]));
continue;
}
price.Symbol = symbol;
price.Open = Double.Parse(lineItems[1]);
price.High = Double.Parse(lineItems[2]);
price.Low = Double.Parse(lineItems[3]);
price.Close = Double.Parse(lineItems[4]);
price.Volume = Int64.Parse(lineItems[5]);
if(lineItems.Length>6)price.AdjClose=Double.Parse(lineItems[6]);
Add(price);
}
}
// This Beta differs wildly with Yahoo Finance. Yahoo finance uses 36 buckets of monthly returns which was simulated when building this Investopedia-based routine.
// I have yet to discover the cause of the difference but I leave this routine in place as a matter of further study and to make comparisons.
// I tested the bucket methodology against just using a stream of returns and they produce the same result so this routine simply uses a stream of returns.
// At any rate, the beta produced by this method does not match to Yahoo finance.
//public double Beta(Prices bmkPrices)
//{
// double beta=double.NaN;
// if(Count!=bmkPrices.Count)return beta;
// float[] cumReturnsPricesArray=GetReturns();
// float[] cumReturnsPricesBenchmark=bmkPrices.GetReturns();
// beta=Numerics.Beta(ref cumReturnsPricesArray,ref cumReturnsPricesBenchmark);
// return beta*10;
//}
// Assumes that the prices are stored lowest date first
public double MaxDrawdown()
{
return Numerics.MaxDrawdown(GetPrices());
}
public double MaxUpside()
{
return Numerics.MaxUpside(GetPrices());
}
public PricesByDate GetPricesByDate()
{
PricesByDate pricesByDate = new PricesByDate();
for (int index = 0; index < Count; index++) pricesByDate.Add(this[index].Date, this[index]);
return pricesByDate;
}
public Prices Top(int count)
{
Prices prices = new Prices();
for (int index = 0; index < count && index<Count; index++)
{
prices.Add(this[index]);
}
return prices;
}
public Prices Bottom(int count)
{
Prices prices = new Prices();
for (int index = Count-1; index>=0 && prices.Count<count; index--)
{
prices.Add(this[index]);
}
return prices;
}
public double Volatility()
{
float[] pricesAr = GetPrices();
return Numerics.StdDev(ref pricesAr);
}
public double Min()
{
float[] pricesAr = GetPrices();
return Numerics.Min(ref pricesAr);
}
public double MinLow()
{
float[] pricesAr = GetPricesLow();
return Numerics.Min(ref pricesAr);
}
public double Max()
{
float[] pricesAr = GetPrices();
return Numerics.Max(ref pricesAr);
}
public double Mean()
{
float[] pricesAr = GetPrices();
return Numerics.Mean(ref pricesAr);
}
public double[] GetLeastSquaresFit()
{
double[] pricesArray = new double[Count];
for (int index = 0; index < Count; index++)
{
pricesArray[index] = (float)this[index].Close;
}
LeastSquaresResult leastSquaresResult=Numerics.LeastSquares(pricesArray);
return leastSquaresResult.LeastSquares;
}
public double[] GetVolume()
{
double[] volumeArray = new double[Count];
for (int index = 0; index < Count; index++)
{
volumeArray[index] = (double)this[index].Volume;
}
return volumeArray;
}
public float[] GetPrices()
{
float[] pricesArray = new float[Count];
for (int index = 0; index < Count; index++)
{
pricesArray[index] = (float)this[index].Close;
}
return pricesArray;
}
public float[] GetPricesLow()
{
float[] pricesArray = new float[Count];
for (int index = 0; index < Count; index++)
{
pricesArray[index] = (float)this[index].Low;
}
return pricesArray;
}
public float[] GetPricesHigh()
{
float[] pricesArray = new float[Count];
for (int index = 0; index < Count; index++)
{
pricesArray[index] = (float)this[index].High;
}
return pricesArray;
}
public float[] GetPrices(int startIndex, int count)
{
if (startIndex + count > Count) return null;
float[] pricesArray=new float[count];
for (int index = startIndex,arrayIndex=0; index < startIndex + count; index++,arrayIndex++)
{
pricesArray[arrayIndex] = (float)this[index].Close;
}
return pricesArray;
}
public float[] GetPricesHigh(int startIndex, int count)
{
if (startIndex + count > Count) return null;
float[] pricesArray = new float[count];
for (int index = startIndex, arrayIndex = 0; index < startIndex + count; index++, arrayIndex++)
{
pricesArray[arrayIndex] = (float)this[index].High;
}
return pricesArray;
}
public float[] GetPricesLow(int startIndex, int count)
{
if (startIndex + count > Count) return null;
float[] pricesArray = new float[count];
for (int index = startIndex, arrayIndex = 0; index < startIndex + count; index++, arrayIndex++)
{
pricesArray[arrayIndex] = (float)this[index].Low;
}
return pricesArray;
}
public float[] GetReturns()
{
if(Count==0||1==Count)return null;
float[] returns = new float[Count - 1];
for (int index = 0; index < Count - 1; index++)
{
Price currentPrice = this[index];
Price prevPrice = this[index + 1];
if (0.00 == prevPrice.Close) returns[index] = 0.00F;
else returns[index] = (float)((currentPrice.Close - prevPrice.Close) / Math.Abs(prevPrice.Close));
}
return returns;
}
public double GetReturn1D()
{
if(Count<2)return double.NaN;
Prices pricesForReturn1D=new Prices(this.Take(2).ToList());
return pricesForReturn1D.GetCumulativeReturn();
}
public float[] GetReturns(int dayCount)
{
if(Count-dayCount<=0)return new float[0];
float[] returns = new float[Count - dayCount];
for (int index = 0; index < Count - dayCount; index++)
{
Price currentPrice = this[index];
Price prevPrice = this[index + dayCount];
if (0.00 == prevPrice.Close) returns[index] = 0.00F;
else returns[index] = (float)((currentPrice.Close - prevPrice.Close) / Math.Abs(prevPrice.Close));
}
return returns;
}
public double GetCumulativeReturn()
{
float[] returns=GetReturns();
if(null==returns)return double.NaN;
double itemReturn=0.00;
for(int index=0;index<returns.Length;index++)itemReturn+=(double)returns[index];
return itemReturn;
}
public double GetCumulativeReturn(int dayCount)
{
float[] returns=GetReturns(dayCount);
double itemReturn=0.00;
for(int index=0;index<returns.Length;index++)itemReturn+=(double)returns[index];
return itemReturn;
}
public double[] GetReturnsAsDoubleArray()
{
double[] returns = new double[Count - 1];
for (int index = 0; index < Count - 1; index++)
{
Price currentPrice = this[index];
Price prevPrice = this[index + 1];
if (0.00 == prevPrice.Close) returns[index] = 0.00;
else returns[index] = (double)((currentPrice.Close - prevPrice.Close) / Math.Abs(prevPrice.Close));
}
return returns;
}
public double[] GetReturnsAsDoubleArray(int dayCount)
{
if (0 == Count) return null;
double[] returns = new double[Count - dayCount];
for (int index = 0; index < Count - dayCount; index++)
{
Price currentPrice = this[index];
Price prevPrice = this[index + dayCount];
if (0.00 == prevPrice.Close) returns[index] = 0.00F;
else returns[index] = ((currentPrice.Close - prevPrice.Close) / Math.Abs(prevPrice.Close));
}
return returns;
}
// *********************************
//public static Prices GetMonthlyPrices(String symbol, DateTime asof, int months = 36)
//{
// DateGenerator dateGenerator = new DateGenerator();
// Prices prices = new Prices();
// DateTime startDate = dateGenerator.GetCurrMonthStart(asof);
// DateTime minPricingDate = PricingDA.GetEarliestDate(symbol);
// Dictionary<DateTime, Price> symbolPricesByDate = new Dictionary<DateTime, Price>();
// List<DateTime> historicalDates = new List<DateTime>();
// while (historicalDates.Count < (months + 1))
// {
// historicalDates.Add(startDate);
// startDate = dateGenerator.GetPrevMonthStart(startDate);
// }
// DateTime requestStartDate = dateGenerator.DaysAddActual(asof, 5); // advance 5 days to provide an error margin for holidays
// Prices symbolPrices = PricingDA.GetPrices(symbol, requestStartDate, historicalDates[historicalDates.Count - 1]);
// foreach (Price price in symbolPrices) symbolPricesByDate.Add(price.Date, price);
// startDate = dateGenerator.GetCurrMonthStart(asof);
// while (prices.Count < (months + 1))
// {
// Price price = GetPrice(symbol, startDate, symbolPricesByDate);
// if (null == price) return null;
// prices.Add(price);
// startDate = dateGenerator.GetPrevMonthStart(startDate);
// if (startDate < minPricingDate) break;
// }
// return prices;
//}
private static Price GetPrice(String symbol,DateTime requestedDate, Dictionary<DateTime, Price> symbolPricesByDate)
{
int maxAdvanceDays = 5;
Price symbolPrice = null;
for (int advanceDays = 0; advanceDays < maxAdvanceDays; advanceDays++)
{
if (!symbolPricesByDate.ContainsKey(requestedDate)) { requestedDate = requestedDate.AddDays(1); continue; }
symbolPrice = symbolPricesByDate[requestedDate];
}
return symbolPrice;
}
// **********************************
}
public class Price
{
private String symbol;
private DateTime date;
private double open;
private double high;
private double low;
private double close;
private long volume;
private double adjClose;
public Price()
{
}
public Price Clone()
{
Price clonePrice=new Price();
clonePrice.Symbol=Symbol;
clonePrice.Date=Date;
clonePrice.Open=Open;
clonePrice.High=High;
clonePrice.Low=Low;
clonePrice.Close=Close;
clonePrice.Volume=Volume;
clonePrice.AdjClose=AdjClose;
return clonePrice;
}
public String Symbol
{
get { return symbol; }
set { symbol = value; }
}
public DateTime Date
{
get { return date; }
set { date = value; }
}
public double Open
{
get { return open; }
set { open = value; }
}
public double High
{
get { return high; }
set { high = value; }
}
public double Low
{
get { return low; }
set { low = value; }
}
public double Close
{
get { return close; }
set { close = value; }
}
public long Volume
{
get { return volume; }
set { volume = value; }
}
public double AdjClose
{
get { return adjClose; }
set { adjClose = value; }
}
public bool IsValid
{
get
{
if(null==symbol)return false;
if(Utility.IsEpoch(date))return false;
if(double.IsNaN(open))return false;
if(double.IsNaN(high))return false;
if(double.IsNaN(low))return false;
if(double.IsNaN(close))return false;
if(double.IsNaN(adjClose))return false;
return true;
}
}
public static String Header
{
get { return "Date,Symbol,Open,High,Low,Close,Volume,Adj Close"; } // ,M12,M26,MACD,Signal,Histogram
}
public override String ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(symbol).Append(",");
sb.Append(Utility.DateTimeToStringMMSDDSYYYY(Date)).Append(",");
sb.Append(String.Format("{0:0.00}", Open)).Append(",");
sb.Append(String.Format("{0:0.00}", High)).Append(",");
sb.Append(String.Format("{0:0.00}", Low)).Append(",");
sb.Append(String.Format("{0:0.00}", Close)).Append(",");
sb.Append(Volume).Append(",");
sb.Append(String.Format("{0:0.00}", AdjClose));
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
namespace MarketData.MarketDataModel
{
public class StopLimit
{
public String Symbol{get;set;}
public double StopPrice{get;set;}
public double Shares{get;set;}
public String StopType{get;set;}
public int Active{get;set;}
}
}

View File

@@ -0,0 +1,144 @@
using System;
using System.Linq;
using System.Collections.Generic;
using MarketData.Numerical;
namespace MarketData.MarketDataModel
{
public class TimeSeriesCollection : List<TimeSeriesElement>
{
public TimeSeriesCollection()
{
}
public TimeSeriesCollection(List<TimeSeriesElement> elements)
{
if (null == elements) return;
foreach (TimeSeriesElement element in elements) Add(element);
}
// Returns the intersection of both sets on the common dates
public static AlignDatesResult AlignDates(TimeSeriesCollection tsA,TimeSeriesCollection tsB)
{
List<DateTime> tsADates=(from ts in tsA select ts.AsOf).ToList();
List<DateTime> tsBDates=(from ts in tsB select ts.AsOf).ToList();
List<DateTime> tsIntersect=tsADates.Intersect(tsBDates).Distinct().ToList();
tsA=new TimeSeriesCollection((from ts in tsA where tsIntersect.Any(x=>x.Equals(ts.AsOf)) select ts).ToList());
tsB=new TimeSeriesCollection((from ts in tsB where tsIntersect.Any(x=>x.Equals(ts.AsOf)) select ts).ToList());
return new AlignDatesResult(tsA,tsB);
}
public float[] ToFloat()
{
float[] values = new float[Count];
for (int index = 0; index < Count; index++) values[index] = (float)this[index].Value;
return values;
}
public bool ContainsNegativeValues()
{
int count= (from TimeSeriesElement element in this where element.Value < 0 select element).Count();
return count > 0 ? true : false;
}
public TimeSeriesCollection RemoveNegativeValues()
{
return new TimeSeriesCollection((from TimeSeriesElement element in this where element.Value >= 0 select element).ToList());
}
// Removes the outliers from the collection. If the resulting collection contains zero elements then returns the original collection.
//public TimeSeriesCollection RemoveOutliers(int standardDeviations=4)
//{
// double[] values = (from TimeSeriesElement element in this select element.Value).ToArray();
// double valuesStd=Numerics.Volatility(ref values)*standardDeviations;
// TimeSeriesCollection timeSeriesCollection=new TimeSeriesCollection((from TimeSeriesElement element in this where element.Value <=valuesStd select element).ToList());
// if(0==timeSeriesCollection.Count)return this;
// else return timeSeriesCollection;
//}
}
public class TimeSeriesElement
{
public enum ElementType { INVALID, OTHER,BVPS, EPS, OperatingCashflow,FreeCashflow,Revenue,QuarterlyRevenue,Inventory,QuarterlyInventory,ROIC,OperatingIncome,WorkingCapital,ROA,NetIncomeAvailableToCommonShareholders,TaxRate,InterestExpense,COGS};
private String symbol;
private DateTime asof;
private ElementType elementType;
private double value;
private String otherType;
public TimeSeriesElement()
{
}
public String Symbol
{
get { return symbol; }
set { symbol = value; }
}
public DateTime AsOf
{
get { return asof; }
set { asof = value; }
}
public double Value
{
get { return value; }
set { this.value = value; }
}
public String OtherType
{
get{return otherType;}
set{otherType=value;}
}
public TimeSeriesElement.ElementType Type
{
get { return elementType; }
set { elementType = value; }
}
public static String StringForType(TimeSeriesElement.ElementType type)
{
switch (type)
{
case ElementType.INVALID :
return "???";
case ElementType.BVPS:
return "bvps";
case ElementType.EPS:
return "eps";
case ElementType.OperatingCashflow :
return "operating_cashflow";
case ElementType.FreeCashflow:
return "free_cashflow";
case ElementType.Revenue:
return "revenue";
case ElementType.QuarterlyRevenue:
return "quarterly_revenue";
case ElementType.OperatingIncome:
return "operating_income";
case ElementType.ROIC:
return "roic";
case ElementType.WorkingCapital:
return "working_capital";
case ElementType.ROA:
return "roa";
case ElementType.TaxRate :
return "tax_rate";
case ElementType.InterestExpense:
return "interest_expense";
case ElementType.NetIncomeAvailableToCommonShareholders:
return "net_income_available_to_common_shareholders";
case ElementType.COGS:
return "cogs";
default:
return "???";
}
}
}
public class AlignDatesResult
{
public AlignDatesResult()
{
}
public AlignDatesResult(TimeSeriesCollection collectionA,TimeSeriesCollection collectionB)
{
CollectionA=collectionA;
CollectionB=collectionB;
}
public TimeSeriesCollection CollectionA{get;set;}
public TimeSeriesCollection CollectionB{get;set;}
}
}

View File

@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//using MarketData.DataAccess;
using MarketData.MarketDataModel;
using MarketData.Utils;
// This Beta calculator is modelled after Yahoo Finance Beta calculator. It calculates Beta using 36 monthly prices start at beginning of previous month and going back 36 months
// While the calculator does not match exactly to Yahoo Finance I will use this as an alternative in the event that Yahoo Finance Beta is no longer available.
namespace MarketData.Numerical
{
public class BetaPrices : List<BetaPrice>
{
public BetaPrices()
{
}
// assuming that the list is in descending date order
public double[] ReturnsBenchmark()
{
double[] returns=new double[Count-1];
for(int index=Count-2;index>=0;index--)
{
if(this[index+1].PriceBenchmark.Close==0.00)returns[index]=0.00;
else returns[index]=(this[index].PriceBenchmark.Close-this[index+1].PriceBenchmark.Close)/this[index+1].PriceBenchmark.Close;
}
return returns;
}
public double[] ReturnsSymbol()
{
double[] returns=new double[Count-1];
for(int index=Count-2;index>=0;index--)
{
if(this[index+1].PriceSymbol.Close==0.00)returns[index]=0.00;
else returns[index]=(this[index].PriceSymbol.Close-this[index+1].PriceSymbol.Close)/this[index+1].PriceSymbol.Close;
}
return returns;
}
}
public class BetaPrice
{
public BetaPrice(String symbol,String benchmark,Price symbolPrice,Price benchmarkPrice,DateTime pricingDate)
{
Symbol=symbol;
Benchmark=benchmark;
PricingDate=pricingDate;
PriceSymbol=symbolPrice;
PriceBenchmark=benchmarkPrice;
}
public DateTime PricingDate{get;set;}
public String Symbol{get;set;}
public String Benchmark{get;set;}
public Price PriceSymbol{get;set;}
public Price PriceBenchmark{get;set;}
}
public class BetaGenerator
{
private BetaGenerator()
{
}
//public static double Beta(String symbol,int months = 36)
//{
// return Beta(symbol, PricingDA.GetLatestDate(symbol), months);
//}
//public static double Beta(String symbol,DateTime asof,int months=36)
//{
// try
// {
// String benchmark = "SPY";
// DateGenerator dateGenerator = new DateGenerator();
// BetaPrices betaPrices = new BetaPrices();
// DateTime startDate = dateGenerator.GetPrevMonthStart(asof);
// DateTime minPricingDate = PricingDA.GetEarliestDate(symbol);
// Dictionary<DateTime, Price> symbolPricesByDate = new Dictionary<DateTime, Price>();
// Dictionary<DateTime, Price> benchmarkPricesByDate = new Dictionary<DateTime, Price>();
// List<DateTime> historicalDates = new List<DateTime>();
// while (historicalDates.Count < (months + 1))
// {
// historicalDates.Add(startDate);
// startDate = dateGenerator.GetPrevMonthStart(startDate);
// }
// Prices symbolPrices = PricingDA.GetPrices(symbol, asof, historicalDates[historicalDates.Count - 1]);
// Prices benchmarkPrices = PricingDA.GetPrices(benchmark, asof, historicalDates[historicalDates.Count - 1]);
// foreach (Price price in symbolPrices) symbolPricesByDate.Add(price.Date, price);
// foreach (Price price in benchmarkPrices) benchmarkPricesByDate.Add(price.Date, price);
// startDate = dateGenerator.GetPrevMonthStart(asof);
// while (betaPrices.Count < (months + 1))
// {
// BetaPrice betaPrice = GetPrice(symbol, benchmark, startDate, symbolPricesByDate, benchmarkPricesByDate);
// if (null == betaPrice)
// {
// return double.NaN;
// }
// betaPrices.Add(betaPrice);
// startDate = dateGenerator.GetPrevMonthStart(startDate);
// if (startDate < minPricingDate) break;
// }
// double[] returnsSymbol = betaPrices.ReturnsSymbol();
// double[] returnsBenchmark = betaPrices.ReturnsBenchmark();
// double beta = Numerics.Beta(ref returnsSymbol, ref returnsBenchmark);
// return beta;
// }
// catch (Exception exception)
// {
// MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception:{0}",exception.ToString()));
// return double.NaN;
// }
//}
private static BetaPrice GetPrice(String symbol, String benchmark, DateTime requestedDate, Dictionary<DateTime, Price> symbolPricesByDate, Dictionary<DateTime, Price> benchmarkPricesByDate)
{
try
{
int maxAdvanceDays = 10;
Price symbolPrice = null;
Price benchmarkPrice = null;
for (int advanceDays = 0; advanceDays < maxAdvanceDays; advanceDays++)
{
if (!symbolPricesByDate.ContainsKey(requestedDate)) { requestedDate = requestedDate.AddDays(1); continue; }
symbolPrice = symbolPricesByDate[requestedDate];
if (!benchmarkPricesByDate.ContainsKey(requestedDate)) { requestedDate = requestedDate.AddDays(1); continue; }
benchmarkPrice = benchmarkPricesByDate[requestedDate];
}
if (null == symbolPrice || null == benchmarkPrice) return null;
symbolPrice.Date = requestedDate.Date;
benchmarkPrice.Date = requestedDate.Date;
return new BetaPrice(symbol, benchmark, symbolPrice, benchmarkPrice, requestedDate);
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Exception:{0}", exception.ToString()));
return null;
}
}
}
}

View File

@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MarketData.Numerical
{
public interface IBinValueExtractor
{
double BinValue();
}
public class BinCollection<T> : List<BinItems<T>>
{
}
public class BinItems<T> : List<T>
{
public BinItems()
{
}
public BinItems(List<T> list)
{
foreach(T item in list)Add(item);
}
}
public class BinHelper<T> where T : IBinValueExtractor
{
public static BinCollection<T> CreateBins(BinItems<T> items,int bins)
{
BinCollection<T> binCollection=new BinCollection<T>();
if(null==items||0==items.Count)
{
for(int index=0;index<bins;index++)binCollection.Add(new BinItems<T>());
return binCollection;
}
items.Sort();
T minItem=items[0];
T maxItem=items[items.Count-1];
double midPoint=(maxItem.BinValue()-minItem.BinValue())/(double)bins;
List<double> borderValues=new List<double>();
for(int index=0;index<bins+1;index++)
{
if(0==index){borderValues.Add(minItem.BinValue());continue;}
else if(index==bins)borderValues.Add(borderValues[index-1]+midPoint+1);
else borderValues.Add(borderValues[index-1]+midPoint);
}
binCollection.Add(new BinItems<T>());
for(int index=0;index<borderValues.Count;index++)
{
double lowerBound;
double upperBound;
BinItems<T> binItems=binCollection[binCollection.Count-1];
lowerBound=borderValues[index];
if(index==borderValues.Count-1)upperBound=maxItem.BinValue();
else upperBound=borderValues[index+1];
for(int itemIndex=0;itemIndex<items.Count;itemIndex++)
{
T item=items[itemIndex];
if(item.BinValue()>=lowerBound&&item.BinValue()<upperBound)binItems.Add(item);
}
if(index<borderValues.Count-2)binCollection.Add(new BinItems<T>());
}
return binCollection;
}
}
}

View File

@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using MarketData.MarketDataModel;
namespace MarketData.Numerical
{
/// <summary>
/// Black Sholes Option Pricing Model for simplest scenario
/// </summary>
public class BlackScholesOptionPricingModel
{
private BlackScholesOptionPricingModel()
{
}
/// <summary>
/// Get Option price by applying BlackScholesOptionPricingModel
/// </summary>
/// <param name="optionType">Enum to indicate whether Call or Put</param>
/// <param name="S">Price of underlying</param>
/// <param name="X">Strike price</param>
/// <param name="T">Time to expiration in years</param>
/// <param name="r">Risk free interest rate</param>
/// <param name="v">Volatility</param>
/// <returns></returns>
//public static double GetPrice(OptionTypeEnum optionType, double S, double X, double T, double r, double v)
//{
// double d1 = 0.0;
// double d2 = 0.0;
// double optionValue = 0.0;
// d1 = (Math.Log(S / X) + (r + v * v / 2.0) * T) / (v * Math.Sqrt(T));
// d2 = d1 - v * Math.Sqrt(T);
// if (optionType == OptionTypeEnum.CallOption)
// {
// optionValue = S * CumulativeNormalDistributionFun(d1) - X * Math.Exp(-r * T) * CumulativeNormalDistributionFun(d2);
// }
// else if (optionType == OptionTypeEnum.PutOption)
// {
// optionValue = X * Math.Exp(-r * T) * CumulativeNormalDistributionFun(-d2) - S * CumulativeNormalDistributionFun(-d1);
// }
// return optionValue;
//}
/// <summary>
/// Cumulative normal distribution function
/// </summary>
/// <param name="d"></param>
/// <returns></returns>
private static double CumulativeNormalDistributionFun(double d)
{
double L = 0.0;
double K = 0.0;
double dCND = 0.0;
const double a1 = 0.31938153;
const double a2 = -0.356563782;
const double a3 = 1.781477937;
const double a4 = -1.821255978;
const double a5 = 1.330274429;
L = Math.Abs(d);
K = 1.0 / (1.0 + 0.2316419 * L);
dCND = 1.0 - 1.0 / Math.Sqrt(2 * Convert.ToDouble(Math.PI)) * Math.Exp(-L * L / 2.0) * (a1 * K + a2 * K * K + a3 * Math.Pow(K, 3.0) + a4 * Math.Pow(K, 4.0) + a5 * Math.Pow(K, 5.0));
if (d < 0)
{
return 1.0 - dCND;
}
else
{
return dCND;
}
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
using System.Collections;
//using System.Data.SqlClient;
using System.Text;
using System.IO;
// Filename: KSTest.cs
// Author:Yan Kvitko
// Date:01/2005
namespace MarketData.Numerical
{
[Serializable]
public class KSTest
{
private int h;
private double pValue;
private double ksStat;
private double criticalValue;
public KSTest()
{
}
public KSTest(int h, double pValue, double ksStat, double criticalValue)
{
this.h=h;
this.pValue=pValue;
this.ksStat=ksStat;
this.criticalValue=criticalValue;
}
public int H
{
get{return h;}
set{h=value;}
}
public double PValue
{
get{return pValue;}
set{pValue=value;}
}
public double KSStat
{
get{return ksStat;}
set{ksStat=value;}
}
public double CriticalValue
{
get{return criticalValue;}
set{criticalValue=value;}
}
}
}

View File

@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MarketData.Utils;
namespace MarketData.Numerical
{
public class LeastSquaresResult
{
public double[] LeastSquares { get; set; }
public double YIntercept { get; set; }
public double XIntercept { get; set; }
public double Slope { get; set; }
public void Extend(int itemCount, double slope) // extend the result set by itemCount by applying the slope to subsequent values
{
if (null == LeastSquares || 0 == LeastSquares.Length) return;
double[] extendedItems = new double[itemCount + LeastSquares.Length];
Array.Copy(LeastSquares, 0, extendedItems, itemCount, LeastSquares.Length);
for (int index = itemCount - 1; index >= 0; index--)
{
extendedItems[index] = extendedItems[index + 1] + slope;
}
LeastSquares = extendedItems;
}
}
public class LeastSquaresResultWithR2 : LeastSquaresResult
{
public double RSquared { get; set; }
}
// **********************************************************************************************************************************************
public class LeastSquaresHelper
{
private LeastSquaresHelper()
{
}
// This version reverses the slope because the input data is in reverse order
// The input data should be in the following manner observations[count-1]=earliest data point, observations[0]=most recent data point
// This version should be retained as-is because it is being referenced in models etc.,
public static LeastSquaresResult CalculateLeastSquares(double[] observations)
{
try
{
LeastSquaresResult leastSquaresResult = new LeastSquaresResult();
double[] xSeries = new double[observations.Length];
double[] xMinusXMean = new double[observations.Length];
double[] yMinusYMean = new double[observations.Length];
double[] meanProduct = new double[observations.Length];
double[] xMinusXMeanSquared = new double[observations.Length];
double[] leastSquares = new double[observations.Length];
double xMean = double.NaN;
double yMean = double.NaN;
double slope = double.NaN;
double yIntercept = double.NaN;
for (int index = 0; index < xSeries.Length; index++) xSeries[index] = index + 1;
xMean = Numerics.Mean(ref xSeries);
yMean = Numerics.Mean(ref observations);
for (int index = 0; index < observations.Length; index++)
{
xMinusXMean[index] = xSeries[index] - xMean;
yMinusYMean[index] = observations[index] - yMean;
meanProduct[index] = xMinusXMean[index] * yMinusYMean[index];
xMinusXMeanSquared[index] = xMinusXMean[index] * xMinusXMean[index];
}
slope = Numerics.Sum(ref meanProduct) / Numerics.Sum(ref xMinusXMeanSquared);
yIntercept = Numerics.YIntercept(xMean, yMean, slope);
for (int index = 0; index < leastSquares.Length; index++) leastSquares[index] = slope * xSeries[index] + yIntercept;
leastSquaresResult.LeastSquares = leastSquares;
leastSquaresResult.YIntercept = yIntercept;
leastSquaresResult.XIntercept = xMean;
leastSquaresResult.Slope = slope * -1.00;
return leastSquaresResult;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG, exception.ToString());
return null;
}
}
// This version uses the true slope whereas the version above reverses the slope due to the arrangement of the input data
// The input data should be in the following manner observations[0]=earliest data point, observations[count-1]=most recent data point
public static LeastSquaresResultWithR2 CalculateLeastSquaresWithR2(double[] observations)
{
try
{
LeastSquaresResultWithR2 leastSquaresResultWithR2 = new LeastSquaresResultWithR2();
double[] xSeries = new double[observations.Length];
double[] xMinusXMean = new double[observations.Length];
double[] yMinusYMean = new double[observations.Length];
double[] meanProduct = new double[observations.Length];
double[] xMinusXMeanSquared = new double[observations.Length];
double[] leastSquares = new double[observations.Length];
double xMean = double.NaN;
double yMean = double.NaN;
double slope = double.NaN;
double yIntercept = double.NaN;
for (int index = 0; index < xSeries.Length; index++) xSeries[index] = index + 1;
xMean = Numerics.Mean(ref xSeries);
yMean = Numerics.Mean(ref observations);
for (int index = 0; index < observations.Length; index++)
{
xMinusXMean[index] = xSeries[index] - xMean;
yMinusYMean[index] = observations[index] - yMean;
meanProduct[index] = xMinusXMean[index] * yMinusYMean[index];
xMinusXMeanSquared[index] = xMinusXMean[index] * xMinusXMean[index];
}
slope = Numerics.Sum(ref meanProduct) / Numerics.Sum(ref xMinusXMeanSquared);
yIntercept = Numerics.YIntercept(xMean, yMean, slope);
for (int index = 0; index < leastSquares.Length; index++) leastSquares[index] = slope * xSeries[index] + yIntercept;
leastSquaresResultWithR2.LeastSquares = leastSquares;
leastSquaresResultWithR2.YIntercept = yIntercept;
leastSquaresResultWithR2.XIntercept = xMean;
leastSquaresResultWithR2.Slope = slope;
// calculate the R2
double[] estimated = new double[observations.Length];
double[] estimatedLessMeanSquared = new double[observations.Length];
double sumOfEstimatedLessMeanSquared = 0.00;
double sumofsquares = 0.00;
foreach (double observation in observations) sumofsquares += Math.Pow(observation - yMean, 2);
for (int index = 0; index < observations.Length; index++) estimated[index] = yIntercept + (slope * (index + 1));
for (int index = 0; index < observations.Length; index++) estimatedLessMeanSquared[index] = Math.Pow(estimated[index] - yMean, 2);
foreach (double value in estimatedLessMeanSquared) sumOfEstimatedLessMeanSquared += value;
leastSquaresResultWithR2.RSquared = sumOfEstimatedLessMeanSquared / sumofsquares;
return leastSquaresResultWithR2;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG, exception.ToString());
return null;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,114 @@
using System;
using System.Collections;
namespace MarketData.Numerical
{
// The column is the key, the row is the value.
// For Time series elements put the date in the column and the value in the row
public class Element
{
private double row;
private double column;
public Element()
{
}
public Element(double column, double row)
{
this.column = column;
this.row = row;
}
public double Row
{
get { return row; }
set { row = value; }
}
public double Column
{
get { return column; }
set { column = value; }
}
}
public class CatmullRom
{
private CatmullRom()
{
}
public static bool PerformSpline(Element[] sourcePairs, Element[] destPairs)
{
double a0, a1, a2, a3;
double dx, dx1, dx2;
double dy, dy1, dy2;
double endPointOne;
double endPointTwo;
double resamplingPos;
double xPoint;
int clampOne, clampTwo;
int direction;
int destSize = destPairs.Length;
int sourceSize = sourcePairs.Length;
int inputIndex, index;
a0 = a1 = a2 = a3 = endPointOne = 0;
if (sourceSize < 2 || destSize < 1) return false;
if (((Element)sourcePairs[0]).Column < ((Element)sourcePairs[1]).Column)
{
if (((Element)destPairs[0]).Column < ((Element)sourcePairs[0]).Column ||
((Element)destPairs[destSize - 1]).Column > ((Element)sourcePairs[sourceSize - 1]).Column)
direction = 0;
else direction = 1;
}
else
{
if (((Element)destPairs[0]).Column > ((Element)sourcePairs[0]).Column ||
((Element)destPairs[destSize - 1]).Column < ((Element)sourcePairs[sourceSize - 1]).Column)
direction = 0;
else direction = -1;
}
if (0 == direction) return false;
if (1 == direction) endPointTwo = ((Element)destPairs[0]).Column - 1;
else endPointTwo = ((Element)destPairs[0]).Column + 1;
for (index = 0; index < destSize; index++)
{
resamplingPos = ((Element)destPairs[index]).Column;
if ((1 == direction && resamplingPos > endPointTwo) ||
(-1 == direction && resamplingPos < endPointTwo))
{
for (inputIndex = 0; inputIndex < sourceSize && resamplingPos > ((Element)sourcePairs[inputIndex]).Column; inputIndex++) ;
if (resamplingPos < ((Element)sourcePairs[inputIndex]).Column) inputIndex--;
if (inputIndex < 0) inputIndex = 0;
else if (inputIndex == sourceSize-1) inputIndex--;
endPointOne = ((Element)sourcePairs[inputIndex]).Column;
endPointTwo = ((Element)sourcePairs[inputIndex + 1]).Column;
clampOne = Math.Max(inputIndex - 1, 0);
clampTwo = Math.Min(inputIndex + 2, sourceSize - 1);
double clampOneValue = ((Element)sourcePairs[clampOne]).Column;
double clampTwoValue = ((Element)sourcePairs[clampTwo]).Column;
dx = 1.0 / ((endPointTwo - endPointOne)==0?1:(endPointTwo-endPointOne));
dx1 = 1.0 / ((endPointTwo - clampOneValue) == 0 ? 1 : (endPointTwo - clampOneValue));
dx2 = 1.0 / (clampTwoValue-endPointOne == 0 ? 1 : (clampTwoValue - endPointOne));
dy = (((Element)sourcePairs[inputIndex + 1]).Row - ((Element)sourcePairs[inputIndex]).Row) * dx;
dy1 = (((Element)sourcePairs[inputIndex + 1]).Row - ((Element)sourcePairs[clampOne]).Row) * dx1;
dy2 = (((Element)sourcePairs[clampTwo]).Row - ((Element)sourcePairs[inputIndex]).Row) * dx2;
a0 = ((Element)sourcePairs[inputIndex]).Row;
a1 = dy1;
a2 = dx * (3 * dy - 2 * dy1 - dy2);
a3 = dx * dx * (-2 * dy + dy1 + dy2);
}
xPoint = resamplingPos - endPointOne;
((Element)destPairs[index]).Row = ((a3 * xPoint + a2) * xPoint + a1) * xPoint + a0;
}
return true;
}
public static Element[] CreateSplineSourceElements(double[] columns, double[] rows)
{
Element[] elements = new Element[columns.Length];
if (columns.Length != rows.Length) return null;
for (int index = 0; index < columns.Length; index++)
{
elements[index] = new Element(columns[index], rows[index]);
}
return elements;
}
}
} // namespace

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MarketData.Service
{
public class Authorizations
{
public static String Xor(String input, int magic=5)
{
StringBuilder sb = new StringBuilder();
foreach (char ch in input) sb.Append((char)(ch ^ (char)magic));
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,617 @@
using MarketData.MarketDataModel;
using MarketData.MarketDataModel.GainLoss;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Web;
using Xamarin.Essentials;
namespace MarketData.Service
{
// http://192.168.0.73:8000
public class MarketDataServiceClient
{
private Uri baseUri = null;
private HttpClient httpClient = null;
private String accessToken = null;
private List<Exception> exceptions = new List<Exception>();
private static MarketDataServiceClient marketDataServiceClient=null;
private static readonly TimeSpan CONNECTION_TIMEOUT=new TimeSpan(0,0,60);
private MarketDataServiceClient()
{
}
public static MarketDataServiceClient GetInstance()
{
lock(typeof(MarketDataServiceClient))
{
if(null==marketDataServiceClient)
{
marketDataServiceClient=new MarketDataServiceClient();
}
return marketDataServiceClient;
}
}
public void SetUrl(String url,String user)
{
lock(this)
{
if(String.IsNullOrEmpty(url))return;
baseUri = new Uri(url);
httpClient = new HttpClient();
httpClient.BaseAddress = baseUri;
httpClient.Timeout=CONNECTION_TIMEOUT;
ServiceResult serviceResult=Login(user);
if(!serviceResult.Success)return;
accessToken=(String)serviceResult.ContextSpecificResult;
}
}
public String GetBaseUri()
{
return null==baseUri?"":baseUri.ToString();
}
public bool Ping(String url)
{
lock(this)
{
if(String.IsNullOrEmpty(url))return false;
HttpClient httpClient=new HttpClient();
try
{
httpClient.BaseAddress=new Uri(url);
httpClient=new HttpClient();
httpClient.BaseAddress=new Uri(url);
httpClient.Timeout=new TimeSpan(0,0,10);
bool result=false;
if(!IsNetworkAvailable())return false;
StringBuilder sb = new StringBuilder();
sb.Append("/api/Ping/GetPing");
String json = httpClient.GetStringAsync(sb.ToString()).Result;
result = JsonConvert.DeserializeObject<bool>(json);
return result;
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return false;
}
finally
{
if(null!=httpClient)
{
httpClient.Dispose();
httpClient=null;
}
}
}
}
private ServiceResult Login(String user)
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
StringBuilder sb = new StringBuilder();
user = Authorizations.Xor(user);
sb.Append("/api/Authorization/GetToken?").Append("user=").Append(user);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
String accessToken = JsonConvert.DeserializeObject<String>(json);
return new ServiceResult(accessToken);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
// ********************************************************** C O N S U M E R P R I C E I N D E X *************************************************
public ServiceResult GetDistinctConsumerPriceIndices()
{
lock (this)
{
try
{
if (!IsNetworkAvailable()) return new ServiceResult(false, "No network.");
if (!IsAuthorized()) return new ServiceResult(false, "Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/PriceIndex/GetDistinctPriceIndices?").Append("token=").Append(accessToken);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<String> priceIndices = JsonConvert.DeserializeObject<List<String>>(json);
return new ServiceResult(priceIndices);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false, exception.ToString());
}
}
}
public ServiceResult GetGetConsumerPriceIndex(String indexCode)
{
lock (this)
{
try
{
if (!IsNetworkAvailable()) return new ServiceResult(false, "No network.");
if (!IsAuthorized()) return new ServiceResult(false, "Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/PriceIndex/GetConsumerPriceIndex?").Append("token=").Append(accessToken).Append("&").Append("indexCode=").Append(HttpUtility.UrlEncode(indexCode));
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<PriceIndex> priceIndices = JsonConvert.DeserializeObject<List<PriceIndex>>(json);
return new ServiceResult(priceIndices);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false, exception.ToString());
}
}
}
// ************************************************************************ P R E M A R K E T *************************************************
public ServiceResult GetLatestPremarketData(String market,DateTime marketDate)
{
lock (this)
{
try
{
if (!IsNetworkAvailable()) return new ServiceResult(false, "No network.");
if (!IsAuthorized()) return new ServiceResult(false, "Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/PreMarket/GetLatestPremarketData?").Append("token=").Append(accessToken).Append("&").Append("market=").Append(HttpUtility.UrlEncode(market));
sb.Append("&").Append("marketDate=").Append(marketDate);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<PremarketElement> premarketData = JsonConvert.DeserializeObject<List<PremarketElement>>(json);
return new ServiceResult(premarketData);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false, exception.ToString());
}
}
}
public ServiceResult GetAvailableMarkets()
{
lock (this)
{
try
{
if (!IsNetworkAvailable()) return new ServiceResult(false, "No network.");
if (!IsAuthorized()) return new ServiceResult(false, "Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/PreMarket/GetAvailableMarkets?").Append("token=").Append(accessToken);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<String> availableMarkets = JsonConvert.DeserializeObject<List<String>>(json);
return new ServiceResult(availableMarkets);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false, exception.ToString());
}
}
}
public ServiceResult GetAvailableMarketDates(String market)
{
lock (this)
{
try
{
if (!IsNetworkAvailable()) return new ServiceResult(false, "No network.");
if (!IsAuthorized()) return new ServiceResult(false, "Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/PreMarket/GetAvailableMarketDates?").Append("token=").Append(accessToken).Append("&").Append("market=").Append(HttpUtility.UrlEncode(market));
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<DateTime> availableMarketDates = JsonConvert.DeserializeObject<List<DateTime>>(json);
return new ServiceResult(availableMarketDates);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false, exception.ToString());
}
}
}
// ************************************************************************************************************************************************
public ServiceResult GetPortfolioTradesWithCombinedLots(String symbol)
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized()) return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/Portfolio/GetPortfolioTradesWithCombinedLots?").Append("token=").Append(accessToken).Append("&").Append("symbol=").Append(symbol);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<PortfolioTrade> portfolioTrades= JsonConvert.DeserializeObject<List<PortfolioTrade>>(json);
return new ServiceResult(portfolioTrades);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetStopLimit(String symbol)
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized()) return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/Portfolio/GetStopLimit?").Append("token=").Append(accessToken).Append("&").Append("symbol=").Append(symbol);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
if(null==json)return new ServiceResult(null);
StopLimit stopLimit= JsonConvert.DeserializeObject<StopLimit>(json);
return new ServiceResult(stopLimit);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetPortfolioTradesWithParityPrice(String symbol)
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized()) return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/Portfolio/GetPortfolioTradesWithParityPrice?").Append("token=").Append(accessToken).Append("&").Append("symbol=").Append(symbol);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
PortfolioTradesWithParityPrice portfolioTradesWithParityPrice= JsonConvert.DeserializeObject<PortfolioTradesWithParityPrice>(json);
return new ServiceResult(portfolioTradesWithParityPrice);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetPositionsWithDescription()
{
lock (this)
{
try
{
if (!IsNetworkAvailable()) return new ServiceResult(false, "No network.");
if (!IsAuthorized()) return new ServiceResult(false, "Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/Portfolio/GetOpenPositionsWithDescription?").Append("token=").Append(accessToken);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<PositionWithDescription> positionsWithDescription = JsonConvert.DeserializeObject<List<PositionWithDescription>>(json);
return new ServiceResult(positionsWithDescription);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false, exception.ToString());
}
}
}
public ServiceResult GetWatchList(String watchList)
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized()) return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/WatchList/GetWatchList?").Append("token=").Append(accessToken).Append("&").Append("watchList=").Append(watchList);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<String> symbols= JsonConvert.DeserializeObject<List<String>>(json);
return new ServiceResult(symbols);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetHeadlines(DateTime headlineDate)
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized()) return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/Headlines/GetHeadlines?").Append("token=").Append(accessToken).Append("&").Append("headlineDate=").Append(headlineDate);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<Headline> headlines= JsonConvert.DeserializeObject<List<Headline>>(json);
return new ServiceResult(headlines);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetHeadlineDates()
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized()) return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/Headlines/GetHeadlineDates?").Append("token=").Append(accessToken);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<String> headlineDates= JsonConvert.DeserializeObject<List<String>>(json);
return new ServiceResult(headlineDates);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetLatestHeadlines()
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized()) return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/Headlines/GetLatestHeadlines?").Append("token=").Append(accessToken);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<Headline> latestHeadlines= JsonConvert.DeserializeObject<List<Headline>>(json);
return new ServiceResult(latestHeadlines);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetLatestPricingDate()
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized()) return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/Price/GetLatestPricingDate?").Append("token=").Append(accessToken);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
DateTime latestPricingDate= JsonConvert.DeserializeObject<DateTime>(json);
return new ServiceResult(latestPricingDate);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetGainLossDetails(DateTime selectedDate,String account)
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized()) return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/GainLoss/GetGainLossWithDetail?").Append("token=").Append(accessToken).Append("&selectedDate=").Append(selectedDate.ToShortDateString()).Append("&").Append("account=").Append(account);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<GainLossSummaryItemDetail> gainLossSummaryDetail = JsonConvert.DeserializeObject<List<GainLossSummaryItemDetail>>(json);
return new ServiceResult(gainLossSummaryDetail);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetGainLossDetails(DateTime selectedDate)
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized()) return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/GainLoss/GetGainLossWithDetail?").Append("token=").Append(accessToken).Append("&selectedDate=").Append(selectedDate.ToShortDateString());
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<GainLossSummaryItemDetail> gainLossSummaryDetail = JsonConvert.DeserializeObject<List<GainLossSummaryItemDetail>>(json);
return new ServiceResult(gainLossSummaryDetail);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetCompoundGainLoss(int selectedDays)
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized()) return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
bool includeDividends=false;
sb.Append("/api/GainLoss/GetCompoundGainLoss?").Append("token=").Append(accessToken).Append("&selectedDays=").Append(selectedDays).Append("&").Append("includeDividends=").Append(includeDividends);;
String json = httpClient.GetStringAsync(sb.ToString()).Result;
GainLossCompoundModelCollection gainLossCompoundModelCollection = JsonConvert.DeserializeObject<GainLossCompoundModelCollection>(json);
return new ServiceResult(gainLossCompoundModelCollection);
}
catch (Exception exception)
{
exceptions.Add(exception);
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetAccountsWithOpenTrades()
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized()) return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/Portfolio/GetAccountsWithOpenTrades?").Append("token=").Append(accessToken);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<String> accounts = JsonConvert.DeserializeObject<List<String>>(json);
return new ServiceResult(accounts);
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
return null;
}
}
}
public ServiceResult GetPrices(String symbol, int days)
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized())return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/Price/GetPrices?").Append("token=").Append(accessToken).Append("&").Append("symbol=").Append(symbol).Append("&").Append("days=").Append(days);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<Price> prices = JsonConvert.DeserializeObject<List<Price>>(json);
return new ServiceResult(prices);
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetCompanyNameForSymbol(String symbol)
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized())return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/Price/GetCompanyNameForSymbol?").Append("token=").Append(accessToken).Append("&").Append("symbol=").Append(symbol);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
String companyName = JsonConvert.DeserializeObject<String>(json);
return new ServiceResult(companyName);
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public ServiceResult GetBollingerBands(String symbol,int dayCount)
{
lock(this)
{
try
{
if(!IsNetworkAvailable())return new ServiceResult(false,"No network.");
if (!IsAuthorized())return new ServiceResult(false,"Unauthorized.");
StringBuilder sb = new StringBuilder();
sb.Append("/api/Price/GetBollingerBands?").Append("token=").Append(accessToken).Append("&").Append("symbol=").Append(symbol).Append("&").Append("dayCount=").Append(dayCount);
String json = httpClient.GetStringAsync(sb.ToString()).Result;
List<BollingerBandElement> bollingerBands=JsonConvert.DeserializeObject<List<BollingerBandElement>>(json);
return new ServiceResult(bollingerBands);
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
return new ServiceResult(false,exception.ToString());
}
}
}
public bool IsAuthorized()
{
if (null == accessToken) return false;
return true;
}
public static bool IsNetworkAvailable()
{
var current = Connectivity.NetworkAccess;
if (current == NetworkAccess.Internet)return true;
return false;
}
public static bool IsWiFiNetwork()
{
if(!IsNetworkAvailable())return false;
if(Connectivity.ConnectionProfiles.Contains(ConnectionProfile.WiFi))return true;
return false;
}
}
}

View File

@@ -0,0 +1,32 @@
using MarketData.MarketDataModel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Text;
namespace MarketData.Service
{
public class ServiceResult
{
public ServiceResult(bool success)
{
Success=success;
}
public ServiceResult(bool success,String message)
{
Success=success;
Message=message;
}
public ServiceResult(Object contextSpecificResult)
{
Success=true;
ContextSpecificResult=contextSpecificResult;
}
public bool Success{get;set;}
public Object ContextSpecificResult{get;set;}
public String Message{get;set;}
}
}

View File

@@ -0,0 +1,57 @@
using System;
using System.Text;
using System.Collections.Generic;
namespace MarketData.Utils
{
public class CSVLineHelper
{
public CSVLineHelper()
{
}
public static String[] ParseLine(String strLine)
{
try
{
List<String> items = new List<String>();
int length = strLine.Length;
for (int index = 0; index < length; index++)
{
char ch = strLine[index];
if (ch == '"') items.Add(GetQuotedItem(strLine, ref index, length));
else items.Add(GetItem(strLine, ref index, length));
}
return items.ToArray();
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,exception.ToString());
return null;
}
}
private static String GetQuotedItem(String strLine,ref int index,int length)
{
StringBuilder sb = new StringBuilder();
char ch = '\0';
while (index<length)
{
ch = strLine[++index];
if (ch == '"') { index++; break; }
if (ch != ',') sb.Append(ch);
}
return sb.ToString();
}
private static String GetItem(String strLine, ref int index, int length)
{
StringBuilder sb = new StringBuilder();
char ch='\0';
while (ch != ',' && index<length)
{
ch = strLine[index++];
if (ch != ',') sb.Append(ch);
}
index--;
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,344 @@
using System;
using System.Collections;
using System.Collections.Generic;
using MarketData.Utils;
// Filename: DateGenerator.cs
// Author:Sean Kessler
namespace MarketData.Utils
{
/// <summary>DateGenerator - Generate Historical Dates</summary>
[Serializable]
public class DateGenerator
{
private Hashtable holidays=null;
public DateGenerator()
{
}
public DateTime GetPrevMonthStart(DateTime dateTime)
{
DateTime startDate = new DateTime(dateTime.Year, dateTime.Month, 1);
startDate = startDate.AddMonths(-1);
startDate = GetNextBusinessDay(startDate);
return startDate;
}
public DateTime GetCurrMonthStart(DateTime dateTime)
{
DateTime startDate = new DateTime(dateTime.Year, dateTime.Month, 1);
startDate = GetNextBusinessDay(startDate);
return startDate;
}
public DateGenerator(Hashtable holidays)
{
this.holidays=holidays;
}
public static int GetPrevMonth(int month)
{
if(1==month)return 12;
return month-1;
}
/// <summary>FindPrevBusinessDay - Finds previous business day</summary>
/// <returns>DateTime</returns>
public DateTime FindPrevBusinessDay(DateTime asOf)
{
TimeSpan oneDay=new TimeSpan(1,0,0,0);
asOf=asOf.Subtract(oneDay);
while(IsWeekend(asOf)||IsHoliday(asOf))asOf=asOf.Subtract(oneDay);
return asOf;
}
/// <summary>FindNextBusinessDays - Finds following business day</summary>
/// <returns>DateTime</returns>
public DateTime FindForwardBusinessDay(DateTime asOf,int daysForward)
{
for (int index = 0; index < daysForward; index++)
{
asOf = FindNextBusinessDay(asOf);
}
return asOf;
}
/// <summary>FindNextBusinessDay - Finds following business day</summary>
/// <returns>DateTime</returns>
public DateTime FindNextBusinessDay(DateTime asOf)
{
TimeSpan oneDay=new TimeSpan(1,0,0,0);
asOf=asOf.Add(oneDay);
while(IsWeekend(asOf)||IsHoliday(asOf))asOf=asOf.Add(oneDay);
return asOf;
}
/// <summary>GetPrevBusinessDay - Gets previous business day</summary>
/// <note>If the given date is a business day then this method will return the given date</note>
/// <returns>None</returns>
public DateTime GetPrevBusinessDay(DateTime asOf)
{
TimeSpan oneDay=new TimeSpan(1,0,0,0);
while(IsWeekend(asOf)||IsHoliday(asOf))asOf=asOf.Subtract(oneDay);
return asOf;
}
/// <summary>GetNextBusinessDay - Gets next business day</summary>
/// <note>If the given date is a business day then this method will return the given date</note>
/// <returns>None</returns>
public DateTime GetNextBusinessDay(DateTime asOf)
{
TimeSpan oneDay=new TimeSpan(1,0,0,0);
while(IsWeekend(asOf)||IsHoliday(asOf))asOf=asOf.Add(oneDay);
return asOf;
}
/// <summary>GetNextDay - Gets next business day</summary>
/// <note>If the given date is a business day then this method will return the given date</note>
/// <returns>None</returns>
public DateTime GetNextDay(DateTime asOf)
{
return asOf.Add(Utility.OneDay);
}
/// <summary>GetPrevFriday - Gets date of prior friday</summary>
/// <note>Get the date of the previous friday - if previous Friday is holiday will seek previous business day</note>
/// <returns>None</returns>
public DateTime GetPrevFriday(DateTime asOf)
{
TimeSpan oneDay=new TimeSpan(1,0,0,0);
List<DateTime> historicalDates=null;
int daysToFetch=7;
if(DayOfWeek.Friday==asOf.DayOfWeek)
{
asOf=asOf.Subtract(oneDay);
daysToFetch--;
}
historicalDates=GenerateHistoricalDates(asOf,daysToFetch);
for(int index=0;index<historicalDates.Count;index++)
{
DateTime date=(DateTime)historicalDates[index];
if(DayOfWeek.Friday==date.DayOfWeek)return GetPrevBusinessDay(date);
}
throw new Exception("The week no longer contains Friday?");
}
public DateTime GetCurrentMonthEnd(DateTime asOf)
{
TimeSpan oneDay=new TimeSpan(-1,0,0,0);
DateTime date=new DateTime(asOf.Year,asOf.Month,asOf.Day);
date=new DateTime(date.Year,date.Month,DateTime.DaysInMonth(asOf.Year,asOf.Month));
while(IsWeekend(date)||IsHoliday(asOf))date=date.Add(oneDay);
return date;
}
public DateTime GetNextMonthEnd(DateTime asOf)
{
TimeSpan oneDay=new TimeSpan(-1,0,0,0);
DateTime date=new DateTime(asOf.Year,asOf.Month,asOf.Day);
date=date.AddMonths(1);
date=new DateTime(date.Year,date.Month,DateTime.DaysInMonth(date.Year,date.Month));
while(IsWeekend(date)||IsHoliday(asOf))date=date.Add(oneDay);
return date;
}
public DateTime GetPrevMonthEnd(DateTime asOf)
{
TimeSpan oneDay=new TimeSpan(-1,0,0,0);
DateTime date=new DateTime(asOf.Year,asOf.Month,asOf.Day);
date=date.AddMonths(-1);
date=new DateTime(date.Year,date.Month,DateTime.DaysInMonth(date.Year,date.Month));
while(IsWeekend(date)||IsHoliday(asOf))date=date.Add(oneDay);
return date;
}
public DateTime GetPrevMonthEnd(DateTime asOf,int count)
{
for(int index=0;index<count;index++)
{
asOf=GetPrevMonthEnd(asOf);
}
return asOf;
}
public DateTime EnsureWeekday(DateTime asOf)
{
TimeSpan oneDay=new TimeSpan(1,0,0,0);
if(!IsWeekend(asOf))return asOf;
while(IsWeekend(asOf=asOf.Add(oneDay)));
return asOf;
}
public DateTime GenerateHistoricalDate(DateTime startDate,int dayCount)
{
DateTime histDate;
int datedDates=0;
TimeSpan singleDay;
startDate = startDate.Date;
histDate=startDate;
if(dayCount<0)singleDay=new TimeSpan(-1,0,0,0);
else singleDay=new TimeSpan(1,0,0,0);
dayCount=dayCount<0?-dayCount:dayCount;
while(datedDates<dayCount)
{
if(IsMarketOpen(ref histDate))datedDates++;
histDate=histDate.Subtract(singleDay);
}
return histDate.Add(singleDay);
}
// Does not account for weekends etc.,
public DateTime GenerateFutureDate(DateTime startDate,int dayCount)
{
DateTime futureDate;
int datedDates=0;
TimeSpan singleDay;
startDate = startDate.Date;
futureDate=startDate;
singleDay=new TimeSpan(1,0,0,0);
while(datedDates<dayCount)
{
futureDate=futureDate.Add(singleDay);
datedDates++;
}
return futureDate.Add(singleDay);
}
// Accounts for weekends
public DateTime GenerateFutureBusinessDate(DateTime startDate,int dayCount)
{
DateTime futureDate;
int datedDates=0;
TimeSpan singleDay;
startDate = startDate.Date;
futureDate=startDate;
singleDay=new TimeSpan(1,0,0,0);
while(datedDates<dayCount)
{
if(IsMarketOpen(ref futureDate))datedDates++;
futureDate=futureDate.Add(singleDay);
}
return futureDate.Add(singleDay);
}
public int DaysBetweenActual(DateTime historicalDate)
{
DateTime today = DateTime.Now;
TimeSpan timeSpan = historicalDate.Date - today;
return (int)timeSpan.TotalDays;
}
public int DaysBetweenActual(DateTime historicalDate,DateTime startingDate)
{
TimeSpan timeSpan = historicalDate.Date-startingDate;
int totalDays = (int)timeSpan.TotalDays;
if (historicalDate < startingDate) totalDays = (Math.Abs(totalDays) * -1);
else totalDays = Math.Abs(totalDays);
return totalDays;
}
public DateTime DaysAddActual(DateTime date, int daysActual)
{
TimeSpan days = new TimeSpan(daysActual, 0, 0, 0);
return date + days;
}
public int DaysBetween(DateTime startDate, DateTime endDate)
{
if (startDate > endDate)
{
TimeSpan timeSpan = startDate.Date - endDate.Date;
return (int)timeSpan.TotalDays;
}
else
{
TimeSpan timeSpan = endDate.Date - startDate.Date;
return (int)timeSpan.TotalDays;
}
}
public static List<int> GenerateHistoricalYear(int startYear,int years)
{
List<int> yearsList = new List<int>();
for (int index = 0; index < years; index++)
{
yearsList.Add(startYear);
startYear--;
}
return yearsList;
}
public List<DateTime> GenerateHistoricalDates(DateTime startDate, int dayCount)
{
List<DateTime> histDates=new List<DateTime>();
DateTime histDate;
TimeSpan singleDay;
startDate = startDate.Date;
histDate=startDate;
if(dayCount<0)singleDay=new TimeSpan(-1,0,0,0);
else singleDay=new TimeSpan(1,0,0,0);
dayCount=dayCount<0?-dayCount:dayCount;
while(histDates.Count<dayCount)
{
if(IsMarketOpen(ref histDate))histDates.Add(histDate);
histDate=histDate.Subtract(singleDay);
}
return histDates;
}
// The function will figure out which date is the most recent and which one is the historical date.
// Generally, make startDate the most recent and endDate the historical date.
public List<DateTime> GenerateHistoricalDates(DateTime startDate,DateTime endDate)
{
if (Utility.Epoch.Equals(startDate)||Utility.Epoch.Equals(endDate)) return null;
startDate = startDate.Date;
endDate = endDate.Date;
List<DateTime> histDates = new List<DateTime>();
DateTime histDate;
TimeSpan singleDay;
bool reverse = false;
if (endDate > startDate)
{
reverse = true;
DateTime swap = endDate;
endDate = startDate;
startDate = swap;
}
histDate=startDate;
singleDay=new TimeSpan(1,0,0,0);
while(histDate>=endDate)
{
if(IsMarketOpen(ref histDate))histDates.Add(histDate);
histDate=histDate.Subtract(singleDay);
}
if (reverse) histDates.Reverse();
return histDates;
}
// The function will figure out which date is the most recent and which one is the historical date.
// Generally, make startDate the most recent and endDate the historical date.
public List<DateTime> GenerateHistoricalDatesActual(DateTime startDate, DateTime endDate)
{
if (Utility.Epoch.Equals(startDate) || Utility.Epoch.Equals(endDate)) return null;
startDate = startDate.Date;
endDate = endDate.Date;
List<DateTime> histDates = new List<DateTime>();
DateTime histDate;
TimeSpan singleDay;
bool reverse = false;
if (endDate > startDate)
{
reverse = true;
DateTime swap = endDate;
endDate = startDate;
startDate = swap;
}
histDate = startDate;
singleDay = new TimeSpan(1, 0, 0, 0);
while (histDate >= endDate)
{
histDates.Add(histDate);
histDate = histDate.Subtract(singleDay);
}
if (reverse) histDates.Reverse();
return histDates;
}
private bool IsMarketOpen(ref DateTime dateTime)
{
if(IsWeekend(dateTime)||IsHoliday(dateTime))return false;
return true;
}
public bool IsWeekend(DateTime dateTime)
{
if(DayOfWeek.Sunday==dateTime.DayOfWeek || DayOfWeek.Saturday==dateTime.DayOfWeek)return true;
return false;
}
public bool IsHoliday(DateTime dateTime)
{
if(null==holidays)return false;
return holidays.Contains(dateTime.Date);
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
namespace MarketData.Utils
{
public class DateRange : List<DateTime>
{
public DateRange(DateTime startDate,DateTime endDate)
{
startDate = startDate.Date;
endDate=endDate.Date;
DateGenerator dateGenerator=new DateGenerator();
List<DateTime> dates= dateGenerator.GenerateHistoricalDates(startDate, endDate);
foreach (DateTime date in dates) Add(date);
Sort(); // ensure that no matter how we set this up, the oldest date winds up being at the lowest index of the list
}
public DateTime StartDate
{
get { return this[0]; }
}
public DateTime EndDate
{
get { return this[Count-1]; }
}
}
}

View File

@@ -0,0 +1,159 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Text;
using System.Reflection;
using System.Net;
//using System.Runtime.Remoting.Messaging;
// Filename: MarketDataTrace.cs
// Author:Sean Kessler
// Date:11/2005
namespace MarketData.Utils
{
public enum LogLevel : uint
{
NONE=0x0000,
INFO=0x0002,
DEBUG=0x0004,
VERBOSE=0x0008
};
/// <summary>MarketDataTrace - Utility for .</summary>
public class MDTrace
{
private static LogLevel logLevel=LogLevel.DEBUG;
/// <summary>MarketDataTrace - Private constructor prevents instantiation.</summary>
/// <returns>none</returns>
private MDTrace()
{
}
/// <summary>LogLevel - Get/Set Log level.</summary>
/// <param name="logLevel">The log level.</param>
/// <returns>LogLevel</returns>
public static LogLevel LogLevel
{
get{return logLevel;}
set{logLevel=value;}
}
/// <summary>WriteLine - Writes a line of text to trace log.</summary>
/// <param name="message">string content of message to write.</param>
/// <returns>void</returns>
// [Conditional("TRACE")]
public static void Write(LogLevel logLevel,string message)
{
if(MDTrace.logLevel<logLevel)return;
Trace.Write(GetCallerIP()+GetThreadRep()+GetLogLevelRep()+"["+DateTime.Now.ToString()+"]"+GetMethodInfo()+message);
Console.Write(message);
Flush();
}
/// <summary>WriteLine - Writes a line of text to trace log.</summary>
/// <param name="message">string content of message to write.</param>
/// <returns>void</returns>
// [Conditional("TRACE")]
public static void WriteLine(string message)
{
WriteLine(LogLevel.DEBUG,GetCallerIP()+GetThreadRep()+GetLogLevelRep()+"["+DateTime.Now.ToString()+"]"+" "+GetMethodInfo()+message);
Console.WriteLine(message);
}
/// <summary>WriteLine - Writes a line of text to trace log.</summary>
/// <param name="message">string content of message to write.</param>
/// <returns>void</returns>
// [Conditional("TRACE")]
public static void WriteLine(LogLevel logLevel,Exception exception)
{
if(MDTrace.logLevel<logLevel)return;
Trace.WriteLine(GetCallerIP()+GetThreadRep()+GetLogLevelRep()+"["+DateTime.Now.ToString()+"]"+" "+GetMethodInfo()+exception.ToString());
Console.WriteLine(exception);
Flush();
}
/// <summary>WriteLine - Writes a line of text to trace log.</summary>
/// <param name="message">string content of message to write.</param>
/// <returns>void</returns>
// [Conditional("TRACE")]
public static void WriteLine(LogLevel logLevel,string message)
{
if(MDTrace.logLevel<logLevel)return;
Trace.WriteLine(GetCallerIP()+GetThreadRep()+GetLogLevelRep()+"["+DateTime.Now.ToString()+"]"+" "+GetMethodInfo()+message);
Console.WriteLine(message);
Flush();
}
/// <summary>Indent - set trace log indentation.</summary>
/// <returns>void</returns>
// [Conditional("TRACE")]
public static void Indent()
{
Trace.Indent();
}
/// <summary>Unindent - set trace log indentation back.</summary>
/// <returns>void</returns>
// [Conditional("TRACE")]
public static void Unindent()
{
Trace.Unindent();
}
/// <summary>Flush - Flush trace log buffers to disk.</summary>
/// <returns>void</returns>
// [Conditional("TRACE")]
public static void Flush()
{
Trace.Flush();
}
/// <summary>GetLogLevel - Return current log level.</summary>
/// <returns>LogLevel</returns>
public static LogLevel GetLogLevel(String strLogLevel)
{
if(strLogLevel.Equals("debug"))return LogLevel.DEBUG;
else if(strLogLevel.Equals("verbose"))return LogLevel.VERBOSE;
else if(strLogLevel.Equals("info"))return LogLevel.INFO;
else return LogLevel.NONE;
}
/// <summary>GetLogLevel - Return current log level.</summary>
/// <returns>LogLevel</returns>
private static string GetLogLevelRep()
{
if (MDTrace.logLevel == LogLevel.DEBUG) return "[TRACE.DEBUG]";
else if (MDTrace.logLevel == LogLevel.VERBOSE) return "[TRACE.VERBOSE]";
else if (MDTrace.logLevel == LogLevel.INFO) return "[TRACE.INFO]";
else return "[TRACE.NONE]";
}
/// <summary>GetThreadRep - Return threading information.</summary>
/// <returns>LogLevel</returns>
private static string GetThreadRep()
{
return "[Thread="+Thread.CurrentThread.GetHashCode()+"]";
}
/// <summary>GetMethodInfo - Returns information about the calling method 2 frames up.</summary>
/// <returns>String</returns>
private static String GetMethodInfo()
{
StringBuilder sb=new StringBuilder();
StackFrame frame=new StackFrame(2,true);
MethodBase methodBase=frame.GetMethod();
ParameterInfo[] parameters=methodBase.GetParameters();
sb.Append("[").Append(methodBase.DeclaringType.FullName).Append("::").Append(methodBase.Name).Append("(");
for(int index=0;index<parameters.Length;index++)
{
ParameterInfo parameter=(ParameterInfo)parameters[index];
sb.Append(parameter.Name);
if(!(index==parameters.Length-1))sb.Append(",");
}
sb.Append(")]");
return sb.ToString();
}
/// <summary>GetCallerIP - Returns the calling methods IP address.</summary>
/// <returns>String</returns>
private static String GetCallerIP()
{
String hostName = Dns.GetHostName();
String hostAddress = Dns.GetHostAddresses(hostName).ToString();
if(null!=hostName)hostName=hostName.Split('.')[0];
if(null==hostName && null==hostAddress)return "[LOCAL]";
return "["+hostAddress+"->"+hostName+"]";
}
}
}

View File

@@ -0,0 +1,99 @@
using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.Text;
using System.Collections.Generic;
namespace MarketData.Utils
{
public class NVPDictionary : Dictionary<String,NVP>
{
public NVPDictionary()
{
}
}
public class NVPCollections : List<NVPCollection>
{
public NVPCollections()
{
}
public NVPCollections(List<String> nvpCollections)
{
foreach(String nvpCollectionString in nvpCollections)Add(new NVPCollection(nvpCollectionString));
}
public List<String> ToList()
{
List<String> nvpCollections=new List<String>();
foreach(NVPCollection nvpCollection in this)nvpCollections.Add(nvpCollection.ToString());
return nvpCollections;
}
}
public class NVPCollection : List<NVP>
{
public NVPCollection()
{
}
public NVPCollection(String nvpCollectionString)
{
if(null==nvpCollectionString)return;
String[] nvpItems=nvpCollectionString.Split('|');
if(null==nvpItems)return;
for(int index=0;index<nvpItems.Length;index++)
{
Add(new NVP(nvpItems[index]));
}
}
public NVPDictionary ToDictionary()
{
NVPDictionary dict=new NVPDictionary();
foreach(NVP nvp in this)dict.Add(nvp.Name,nvp);
return dict;
}
public static NVPCollection FromString(String strNVPCollection)
{
return new NVPCollection(strNVPCollection);
}
public override String ToString()
{
StringBuilder sb=new StringBuilder();
for(int index=0;index<Count;index++)
{
NVP nvp=this[index];
sb.Append(nvp.ToString());
if(index<Count-1)sb.Append("|");
}
return sb.ToString();
}
}
public class NVP
{
public NVP(String name,String value)
{
Name=name;
Value=value;
}
public NVP(String nvpString)
{
if(null==nvpString)return;
String[] nvps=nvpString.Split('=');
if(2!=nvps.Length)return;
Name=nvps[0].Trim();
Value=nvps[1].Trim();
}
public T Get<T>()
{
T result=default(T);
try {result = (T)Convert.ChangeType(Value, typeof(T));}
catch {result = default(T);}
return result;
}
public String Name{get;set;}
public String Value{get;set;}
public override String ToString()
{
StringBuilder sb=new StringBuilder();
sb.Append(Name).Append("=").Append(Value);
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.Text;
// Filename: Profiler.cs
// Author:Sean Kessler
namespace MarketData.Utils
{
/// <summary>Profiler - Profiler utility class</summary>
public class Profiler
{
[DllImport("kernel32.dll")]
static extern uint GetTickCount();
private uint elapsedTime;
private uint totalTime;
public Profiler()
{
totalTime = GetTickCount();
Start();
}
public void Reset()
{
totalTime = GetTickCount();
Start();
}
public void Start()
{
elapsedTime = GetTickCount();
}
public uint Stop()
{
return elapsedTime = GetTickCount() - elapsedTime;
}
public uint End()
{
return totalTime = GetTickCount() - totalTime;
}
}
}

View File

@@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace MarketData.Utils
{
public class UpdateManager
{
private StreamWriter streamWriter=null;
private FileStream fileStream=null;
private Dictionary<String,String> entries=new Dictionary<String,String>();
public UpdateManager()
{
}
public bool Prepare(String strPathFileName)
{
try
{
String currentWorkingDirectory=Directory.GetCurrentDirectory();
if(!File.Exists(strPathFileName)||IsExpired(strPathFileName))
{
if(File.Exists(strPathFileName))File.Delete(strPathFileName);
fileStream=new FileStream(strPathFileName,FileMode.Create);
streamWriter=new StreamWriter(fileStream);
Console.WriteLine(String.Format("Creating session file:{0}",strPathFileName));
}
else
{
FileStream fileStream=new FileStream(strPathFileName,FileMode.Open);
StreamReader streamReader=new StreamReader(fileStream);
String strLine=null;
while(null!=(strLine=streamReader.ReadLine()))
{
if(!entries.ContainsKey(strLine))entries.Add(strLine,strLine);
}
Console.WriteLine(String.Format("Loaded {0} entries from session file:{1}",entries.Count,strPathFileName));
streamReader.Close();
streamReader.Dispose();
fileStream.Close();
fileStream.Dispose();
fileStream=new FileStream(strPathFileName,FileMode.Append);
streamWriter=new StreamWriter(fileStream);
}
return true;
}
catch(Exception exception)
{
Console.WriteLine(String.Format("Exception:{0}",exception));
return false;
}
}
private bool IsExpired(String strPathFileName)
{
try
{
DateGenerator dateGenerator=new DateGenerator();
DateTime creationTime=File.GetCreationTime(strPathFileName);
int daysElapsed=Math.Abs(dateGenerator.DaysBetweenActual(creationTime,DateTime.Now));
if(daysElapsed>5)
{
Console.WriteLine(String.Format("{0} is expired. {1} days old.",strPathFileName,daysElapsed));
return true;
}
return false;
}
catch(Exception exception)
{
Console.WriteLine(String.Format("Exception:{0}",exception));
return true;
}
}
public List<String> Entries
{
get{return new List<String>(entries.Keys);}
}
public void Add(String entry)
{
if(null==streamWriter)return;
streamWriter.WriteLine(entry);
streamWriter.Flush();
}
public void Dispose()
{
if(null!=streamWriter){streamWriter.Close();streamWriter.Dispose();}
if(null!=fileStream){fileStream.Close();fileStream.Dispose();}
}
}
}

View File

@@ -0,0 +1,561 @@
using System;
using System.Text;
using System.IO.Compression;
using System.IO;
using System.Globalization;
using System.Linq;
using Microsoft.Win32;
using System.Diagnostics;
using System.Collections.Generic;
using MarketData.MarketDataModel;
namespace MarketData.Utils
{
public class Utility
{
private static DateTime epoch = DateTime.Parse("01-01-0001");
private static TimeSpan oneDay=new TimeSpan(1,0,0,0);
public static String Pad(string str, char filler, int length)
{
int stringLength = str.Length;
if (stringLength >= length) return str;
StringBuilder sb = new StringBuilder();
while (stringLength < length)
{
sb.Append(filler);
stringLength++;
}
return sb.ToString() + str;
}
public static String RemoveHtml(String strItem)
{
String[] codes = { "&#x27;","&#187;" };
if(null==strItem)return strItem;
foreach (String code in codes)
{
strItem = strItem.Replace(code,"'");
}
return strItem;
// String str=strItem.Replace("&#x27;","'");
// return str;
}
public static String RemoveDivs(String strItem)
{
StringBuilder sb=new StringBuilder();
bool inDiv=false;
if(null==strItem)return strItem;
for(int index=0;index<strItem.Length;index++)
{
char ch=strItem[index];
if(ch.Equals('<'))inDiv=true;
else if(ch.Equals('>'))inDiv=false;
else if(!inDiv)sb.Append(ch);
}
return sb.ToString();
}
public static String BetweenString(String strItem, String strBegin, String strEnd)
{
if (null == strItem) return null;
int index=-1;
if(null==strBegin)index=0;
else index = strItem.IndexOf(strBegin);
if (-1 == index) return null;
String str = null;
if(null!=strBegin)str=strItem.Substring(index + strBegin.Length);
else str=strItem;
if(null==strEnd)return str;
index = str.IndexOf(strEnd);
if (-1 == index) return null;
StringBuilder sb = new StringBuilder();
for (int strIndex = 0; strIndex < str.Length; strIndex++)
{
if (index == strIndex) break;
sb.Append(str[strIndex]);
}
return sb.ToString();
}
public static String RemoveAfter(String strItem, char charItem)
{
StringBuilder sb = new StringBuilder();
for (int index = 0; index < strItem.Length; index++)
{
char ch = strItem[index];
if (ch.Equals(charItem)) break;
sb.Append(ch);
}
return sb.ToString();
}
public static bool OutOfRange(double value)
{
return value > 100000000000000000000.00 || value< -99999999999999999999.99;
}
public static String RemoveControlChars(String strItem)
{
StringBuilder sb=new StringBuilder();
for(int index=0;index<strItem.Length;index++)
{
char ch=strItem[index];
if(!char.IsControl(ch))sb.Append(ch);
}
return sb.ToString();
}
public static String GetPath(String strPathFileName)
{
int index=strPathFileName.LastIndexOf('\\');
if (-1 == index) return null;
String strPath = strPathFileName.Substring(0, index);
return strPath;
}
public static String KeepBefore(String strItem,String strKeepBefore)
{
int startPos=strItem.IndexOf(strKeepBefore);
if(-1==startPos)return null;
return strItem.Substring(0,startPos);
}
public static String KeepAfter(String strItem,String strKeepAfter)
{
int startPos=strItem.IndexOf(strKeepAfter);
if(-1==startPos)return null;
return strItem.Substring(startPos+strKeepAfter.Length);
}
public static String KeepAfterLast(String strItem,String strKeepAfter)
{
if(null==strItem)return null;
int startPos=strItem.LastIndexOf(strKeepAfter);
if(-1==startPos)return null;
return strItem.Substring(startPos+strKeepAfter.Length);
}
public static String Find(String strItem,String search,char delimeter)
{
if(null==strItem)return null;
bool foundDelimeter=false;
StringBuilder sb=new StringBuilder();
int startPos=strItem.LastIndexOf(search);
if(-1==startPos)return null;
startPos+=search.Length;
for(;startPos<strItem.Length;startPos++)
{
char ch=strItem[startPos];
if(ch.Equals(delimeter))
{
foundDelimeter=true;
break;
}
sb.Append(ch);
}
if(!foundDelimeter)return null;
return sb.ToString();
}
public static String FindFirst(String strItem,String search,char delimeter)
{
if(null==strItem)return null;
bool foundDelimeter=false;
StringBuilder sb=new StringBuilder();
int startPos=strItem.IndexOf(search);
if(-1==startPos)return null;
startPos+=search.Length;
for(;startPos<strItem.Length;startPos++)
{
char ch=strItem[startPos];
if(ch.Equals(delimeter))
{
foundDelimeter=true;
break;
}
sb.Append(ch);
}
if(!foundDelimeter)return null;
return sb.ToString();
}
public static String AddQuotes(String item)
{
return "\"" + item + "\"";
}
public static long DateToLong(DateTime date)
{
int year = date.Year;
int month = date.Month;
int day = date.Day;
return (year * 10000) + (month * 100) + day;
}
public static DateTime LongToDate(long longDate)
{
int year = (int)(longDate / 10000);
int month = ((int)longDate / 100) - year * 100;
int day = (int)(longDate - ((int)(longDate / 100)) * 100);
return new DateTime(year, month, day);
}
public static String DateTimeToStringHHMMSS(DateTime dateTime)
{
if (Utility.IsEpoch(dateTime)) return "";
return dateTime.ToString("HH:mm:ss");
}
public static String DateTimeToStringMMSDDSYYYY(DateTime dateTime)
{
if (Utility.IsEpoch(dateTime)) return "";
return dateTime.ToString("MM/dd/yyyy");
}
public static String DateTimeToStringMMSYYYY(DateTime dateTime)
{
if (Utility.IsEpoch(dateTime)) return "";
return dateTime.ToString("MM/yyyy");
}
public static String DateTimeToStringMMSYY(DateTime dateTime)
{
if (Utility.IsEpoch(dateTime)) return "";
return dateTime.ToString("MM/yy");
}
public static String DateTimeToStringMMSDDSYYYYHHMMSS(DateTime dateTime)
{
if (Utility.IsEpoch(dateTime)) return "";
return dateTime.ToString("MM/dd/yyyy hh:mm:ss");
}
public static String DateTimeToStringMMHDDHYYYY(DateTime dateTime)
{
if (Utility.IsEpoch(dateTime)) return "";
return dateTime.ToString("MM-dd-yyyy");
}
public static String DateTimeToStringYYYYHMMHDD(DateTime dateTime)
{
if (Utility.IsEpoch(dateTime)) return "";
return dateTime.ToString("yyyy-MM-dd");
}
public static String DateTimeToStringYYYYHMMHDDHHMMSS(DateTime dateTime)
{
if (Utility.IsEpoch(dateTime)) return "";
return dateTime.ToString("yyyy-MM-dd HH:MM:ss");
}
public static String DateTimeToStringYYYYMMDD(DateTime dateTime)
{
if (Utility.IsEpoch(dateTime)) return "";
return dateTime.ToString("yyyyMMdd");
}
public static String AsteriskForString(String str)
{
StringBuilder sb = new StringBuilder();
int length = str.Length;
for (int index = 0; index < length; index++) sb.Append("*");
return sb.ToString();
}
public static String FormatNumber(double number)
{
StringBuilder sb=new StringBuilder();
if (double.NaN.Equals(number))sb.Append("N/A");
else sb.Append(String.Format("{0:0.000}", number));
return sb.ToString();
}
public static String FormatNumberConstrain(double value,int places=1,bool commas=false)
{
String strValue=null;
if(value>=1000)
{
value/=1000;
strValue=Utility.FormatNumber(value,places,commas)+"K";
}
else if(value>=1000000)
{
value/=1000000;
strValue=Utility.FormatNumber(value,places,commas)+"M";
}
else if(value>=1000000000)
{
value/=1000000000;
strValue=Utility.FormatNumber(value,places,commas)+"B";
}
else
{
strValue=Utility.FormatNumber(value,places,commas);
}
return strValue;
}
public static String FormatNumber(double number,int places,bool commas=false)
{
StringBuilder sb = new StringBuilder();
StringBuilder formatString=new StringBuilder();
if (commas&&number>=1000.00) formatString.Append("{0:0,0.");
else formatString.Append("{0:0.");
for(int index=0;index<places;index++)formatString.Append("0");
formatString.Append("}");
if (double.NaN.Equals(number)) sb.Append("N/A");
else sb.Append(String.Format(formatString.ToString(), number));
return sb.ToString();
}
public static String FormatCurrency(double number)
{
StringBuilder sb=new StringBuilder();
if (double.NaN.Equals(number))sb.Append("N/A");
else sb.Append(String.Format("{0:C}", number));
return sb.ToString();
}
public static String FormatCurrency(double number,int decimals)
{
StringBuilder sb=new StringBuilder();
String currencyFormat="{0:C"+decimals+"}";
if (double.NaN.Equals(number))sb.Append("N/A");
else sb.Append(String.Format(currencyFormat, number));
return sb.ToString();
}
public static String FormatPercent(double number)
{
StringBuilder sb = new StringBuilder();
if (double.NaN.Equals(number)) sb.Append("N/A");
else sb.Append(String.Format("{0:P}", number));
return sb.ToString();
}
public static String ConformDate(String strDate)
{
String[] elements=strDate.Split(' ');
if(elements.Length<3)return strDate;
return elements[0]+" "+elements[1]+" "+elements[2];
}
public static DateTime ParseDate(String strDate)
{
System.Globalization.CultureInfo cultureInfo = new System.Globalization.CultureInfo("en-US");
String[] formats = new[] {"dddd, MMMM dd","MMM dd yyyy","yyyy-MM","ddd, MMM. d","ddd, MMM. dd", "yyyy/MM/dd","M-d-yyyy", "dd-MM-yyyy", "MM-dd-yyyy", "M.d.yyyy", "dd.MM.yyyy", "MM.dd.yyyy","yyyyMMdd" }.Union(cultureInfo.DateTimeFormat.GetAllDateTimePatterns()).ToArray();
strDate = strDate.Trim();
DateTime dateTime=DateTime.ParseExact(strDate, formats, new System.Globalization.CultureInfo("en-US"), DateTimeStyles.AssumeLocal);
return dateTime;
}
public static double ParsePercent(String strPercent)
{
if (null == strPercent) return double.NaN;
strPercent = strPercent.Replace("%", null);
try { return double.Parse(strPercent)/100.00; }
catch (Exception) { return double.NaN; }
}
public static double ParseCurrency(String strNumber)
{
if (null == strNumber) return double.NaN;
if(Constants.CONST_DASHES.Equals(strNumber))return double.NaN;
strNumber = strNumber.Replace("$", null);
strNumber = strNumber.Replace(",", null);
strNumber = strNumber.Replace("(", "-");
strNumber = strNumber.Replace(")", null);
if (strNumber.Equals("")) return double.NaN;
try { return double.Parse(strNumber); }
catch (Exception) { return double.NaN; }
}
public static String FormatCurrencyWithQuotes(double number)
{
return AddQuotes(FormatCurrency(number));
}
public static String FormatDates(DateTime d1, DateTime d2)
{
StringBuilder sb=new StringBuilder();
sb.Append(Utility.DateTimeToStringMMSDDSYYYY(d1)).Append("-");
sb.Append(Utility.DateTimeToStringMMSDDSYYYY(d2));
return sb.ToString();
}
public static String TrimToSpace(String strString)
{
if (null == strString) return strString;
StringBuilder sb = new StringBuilder();
for (int index = 0; index < strString.Length; index++)
{
char ch=strString[index];
if (' '.Equals(ch)) break;
sb.Append(ch);
}
return sb.ToString();
}
public static String BooleanToYesNoString(bool booleanValue)
{
return booleanValue ? "Yes" : "No";
}
public static bool IsEpoch(DateTime dateTime)
{
return dateTime.Equals(epoch);
}
public static DateTime Epoch
{
get { return epoch; }
}
public static TimeSpan OneDay
{
get{return oneDay;}
}
public static String ListToString(List<String> list,char separator=',')
{
StringBuilder sb=new StringBuilder();
if (null == list || 0 == list.Count) return null;
for(int index=0;index<list.Count;index++)
{
sb.Append(list[index]);
if(index<list.Count-1)sb.Append(separator);
}
return sb.ToString();
}
public static List<String> ToList(String items,char separator=',')
{
List<String> list = items.Split(separator).ToList<String>();
list=(from String s in list select s.Trim()).ToList<String>();
return list;
}
public static String FromList(List<String> items,String postFix=",")
{
StringBuilder sb=new StringBuilder();
for(int index=0;index<items.Count;index++)
{
sb.Append(items[index]);
if(index<items.Count-1)sb.Append(postFix);
}
return sb.ToString();
}
public static byte[] Compress(String strString)
{
MemoryStream outputStream = null;
GZipStream compressionStream = null;
try
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strString);
outputStream = new MemoryStream();
compressionStream = new GZipStream(outputStream, CompressionMode.Compress, true);
compressionStream.Write(bytes, 0, bytes.Length);
compressionStream.Close();
compressionStream = null;
byte[] outputBytes = outputStream.ToArray();
outputStream.Close();
outputStream = null;
return outputBytes;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,exception);
return null;
}
finally
{
if (null != compressionStream)
{
compressionStream.Close();
compressionStream = null;
}
if (null != outputStream)
{
outputStream.Close();
outputStream = null;
}
}
}
public static String Decompress(byte[] compressedBytes)
{
MemoryStream compressedStream = new MemoryStream(compressedBytes);
GZipStream decompressionStream = new GZipStream(compressedStream, CompressionMode.Decompress,true);
MemoryStream outputStream=new MemoryStream();
try
{
byte[] decompressedBytesBuffer = new byte[4096];
int count = 0;
while (true)
{
count = decompressionStream.Read(decompressedBytesBuffer, 0, decompressedBytesBuffer.Length);
if (count > 0) outputStream.Write(decompressedBytesBuffer, 0, count);
else break;
}
decompressionStream.Close();
compressedStream.Close();
String strDecompressed = System.Text.Encoding.UTF8.GetString(outputStream.ToArray());
outputStream.Close();
outputStream = null;
compressedStream = null;
decompressionStream = null;
return strDecompressed;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,exception);
return null;
}
finally
{
if (null != outputStream)
{
outputStream.Close();
outputStream = null;
}
if (null != decompressionStream)
{
decompressionStream.Close();
decompressionStream = null;
}
if (null != compressedStream)
{
compressedStream.Close();
compressedStream = null;
}
}
}
public static void LaunchBrowserSearch(String searchTerm)
{
Process.Start("https://www.google.com/search?q="+Uri.EscapeDataString(searchTerm)+"/");
// OpenWebCommand = new Command(async () => await Browser.OpenAsync("https://www.google.com"));
}
public static bool IsZeroOrNaN(double value)
{
return IsNaN(value)||IsZero(value);
}
private static bool IsZero(double value)
{
if(value==0.00)return true;
return false;
}
private static bool IsNaN(double value)
{
return double.IsNaN(value);
}
public static void DeleteFile(String pathFileName)
{
if(!File.Exists(pathFileName))return;
try{File.Delete(pathFileName);}catch(Exception){;}
}
private static DateTime GetRunDate(String strPathFileName)
{
DateTime runDate=DateTime.Now.Date;
DateGenerator dateGenerator=new DateGenerator();
StreamWriter streamWriter=null;
StreamReader streamReader=null;
try
{
if(!File.Exists(strPathFileName))
{
streamWriter=File.CreateText(strPathFileName);
streamWriter.WriteLine(Utility.DateTimeToStringMMHDDHYYYY(runDate));
streamWriter.Flush();
streamWriter.Close();
streamWriter=null;
return runDate;
}
streamReader=File.OpenText(strPathFileName);
String strLine=streamReader.ReadLine();
streamReader.Close();
streamReader=null;
runDate=Utility.ParseDate(strLine);
if(dateGenerator.DaysBetweenActual(runDate,DateTime.Now)>5)
{
File.Delete(strPathFileName);
runDate=DateTime.Now.Date;
streamWriter=File.CreateText(strPathFileName);
streamWriter.WriteLine(Utility.DateTimeToStringMMHDDHYYYY(runDate));
streamWriter.Flush();
streamWriter.Close();
streamWriter=null;
return runDate;
}
return runDate;
}
catch(Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("GetRunDate:{0}",exception.ToString()));
return runDate;
}
finally
{
if(null!=streamWriter)streamWriter.Close();
if(null!=streamReader)streamReader.Close();
}
}
}
}