using System; using System.Text; using System.Collections; using System.Collections.Generic; using System.IO; using HtmlAgilityPack; using MarketData.Utils; using MarketData.MarketDataModel; using MarketDataLib.Utility; namespace MarketData.Helper { public class InsiderTransactionsParser { private static Dictionary transactionCodes=new Dictionary(); private static InsiderTransactionsParser instance=null; private InsiderTransactionsParser() { BuildTransactionCodes(); } public static InsiderTransactionsParser GetInstance() { lock(typeof(InsiderTransactionsParser)) { if(null==instance)instance=new InsiderTransactionsParser(); return instance; } } private String ApplyNameCase(String name) { StringBuilder sb=new StringBuilder(); name=name.ToLower(); String[] parts=name.Split(' '); for(int index=0;index1)sb.Append(item.Substring(0,1).ToUpper()+item.Substring(1)); else sb.Append(item.ToUpper()); if(index sections) { String item=GetFirstSection(sections); if(item.Equals("D"))return "Direct Ownership"; else if(item.Equals("I"))return "Indirect Ownership"; return ""; } private String GetFirstSection(List sections) { if(null==sections || 0==sections.Count)return ""; return sections[0]; } private String CombineSections(List sections) { StringBuilder sb=new StringBuilder(); if(null==sections || 0==sections.Count)return ""; foreach(String section in sections) { sb.Append(section); } return sb.ToString(); } public InsiderTransactions Parse(SECFilings secFilings) { lock(instance) { try { InsiderTransactions insiderTransactions=new InsiderTransactions(); if(null==secFilings || 0==secFilings.Count)return insiderTransactions; foreach(SECFiling secFiling in secFilings) { List> dictionaryList=new List>(); String insiderName=null; String relationshipOfReportingPerson=null; byte[] streamBytes = Encoding.ASCII.GetBytes(secFiling.FormText); MemoryStream memoryStream = new MemoryStream(streamBytes); HtmlDocument htmlDocument = new HtmlDocument(); htmlDocument.Load(memoryStream); HtmlNodeCollection tables=htmlDocument.DocumentNode.SelectNodes("//table"); if(null==tables || tables.Count<5)continue; HtmlNodeCollection nameAndAddressRows = tables[4].SelectNodes(".//tr"); if(nameAndAddressRows.Count<10)continue; insiderName=ApplyNameCase(nameAndAddressRows[1].InnerText); relationshipOfReportingPerson=Utility.RemoveHtml(nameAndAddressRows[9].InnerText); for(int index=0;index dictionary=new Dictionary(); dictionary.Add("Title of Security",dataCollection[0].InnerHtml); dictionary.Add("Transaction Date",dataCollection[1].InnerHtml); dictionary.Add("Transaction Code",dataCollection[3].InnerHtml); dictionary.Add("Securities Acquired or Disposed",dataCollection[5].InnerHtml); dictionary.Add("Acquired or Disposed",dataCollection[6].InnerHtml); dictionary.Add("Price",dataCollection[7].InnerHtml); dictionary.Add("Ownership Form",dataCollection[9].InnerHtml); dictionaryList.Add(dictionary); } } } foreach(Dictionary dictionary in dictionaryList) { String strItem=null; InsiderTransaction insiderTransaction = new InsiderTransaction(); insiderTransaction.Symbol=secFiling.Symbol; insiderTransaction.SECAccessionNumber=secFiling.SECAccessionNumber; insiderTransaction.FormRowNumber=(secFiling.Sequence+1).ToString(); insiderTransaction.Form=secFiling.Form; insiderTransaction.FilingDate=secFiling.FilingDate; insiderTransaction.InsiderName=insiderName; insiderTransaction.Securities=GetFirstSection(Sections.GetSections(dictionary["Title of Security"])); insiderTransaction.OwnershipType=GetOwnershipForm(Sections.GetSections(dictionary["Ownership Form"])); if(String.IsNullOrEmpty(insiderTransaction.OwnershipType))continue; strItem=GetFirstSection(Sections.GetSections(dictionary["Transaction Date"])); if(String.IsNullOrEmpty(strItem))continue; insiderTransaction.TransactionDate=Utility.ParseDate(strItem); insiderTransaction.NatureOfTransaction=transactionCodes.ContainsKey(GetFirstSection(Sections.GetSections(dictionary["Transaction Code"])))?transactionCodes[GetFirstSection(Sections.GetSections(dictionary["Transaction Code"]))]:Constants.CONST_QUESTION; insiderTransaction.NumberOrValueAcquiredDisposed=FeedParser.ParseValue(GetFirstSection(Sections.GetSections(dictionary["Securities Acquired or Disposed"]))); insiderTransaction.Price=FeedParser.ParseValue(CombineSections(Sections.GetSections(dictionary["Price"]))); insiderTransactions.Add(insiderTransaction); } } return insiderTransactions; } catch(Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Parse SECFiling got exception {0}",exception.ToString())); return new InsiderTransactions(); } } } private void BuildTransactionCodes() { transactionCodes.Add("P","Open market or private purchase of non-derivative or derivative security"); transactionCodes.Add("S","Open market or private sale of non-derivative or derivative security"); transactionCodes.Add("V","Transaction voluntarily reported earlier than required"); transactionCodes.Add("A","Grant, award or other acquisition pursuant to Rule 16b-3(d)"); transactionCodes.Add("D","Disposition to the issuer of issuer equity securities pursuant to Rule 16b-3(e)"); transactionCodes.Add("F","Payment of exercise price or tax liability by delivering or withholding securities incident to the receipt, exercise or vesting of a security issued in accordance with Rule 16b-3"); transactionCodes.Add("I","Discretionary transaction in accordance with Rule 16b-3(f) resulting in acquisition or disposition of issuer securities"); transactionCodes.Add("M","Exercise or conversion of derivative security exempted pursuant to Rule 16b-3"); transactionCodes.Add("C","Conversion of derivative security"); transactionCodes.Add("E","Expiration of short derivative position"); transactionCodes.Add("H","Expiration (or cancellation) of long derivative position with value received"); transactionCodes.Add("O","Exercise of out-of-the-money derivative security"); transactionCodes.Add("X","Exercise of in-the-money or at-the-money derivative security"); transactionCodes.Add("G","Bona fide gift"); transactionCodes.Add("L","Small acquisition under Rule 16a-6"); transactionCodes.Add("W","Acquisition or disposition by will or the laws of descent and distribution"); transactionCodes.Add("Z","Deposit into or withdrawal from voting trust"); transactionCodes.Add("J","Other acquisition or disposition (describe transaction)"); transactionCodes.Add("K","Transaction in equity swap or instrument with similar characteristics"); transactionCodes.Add("U","Disposition pursuant to a tender of shares in a change of control transaction"); } } }