/// <summary> /// Adds an option instrument to this builder. /// Option is added to chains for the currently set {@link #Product product} and/or /// {@link #Underlying underlying} to the {@link OptionSeries series} that corresponding /// to all other currently set attributes.This method is safe in the sense that is ignores /// illegal state of the builder.It only adds an option when all of the following conditions are met: /// <ul> /// <li>{@link #CFI CFI code} is set and starts with either "OC" for call or "OP" for put. /// <li>{@link #SetExpiration(int) expiration} is set and is not zero; /// <li>{@link #Strike strike} is set and is not `Double.NaN` nor `Double.isInfinite()`; /// <li>{@link #Product product} or {@link #Underlying underlying symbol} are set; /// </ul> /// All the attributes remain set as before after the call to this method, but /// {@link #Chains() chains} are updated correspondingly. /// </summary> /// <param name="option">option to add.</param> public void AddOption(InstrumentProfile option) { bool isCall = CFI.StartsWith("OC"); if (!isCall && !CFI.StartsWith("OP")) { return; } if (series.Expiration == 0) { return; } if (double.IsNaN(Strike) || double.IsInfinity(Strike)) { return; } if (Product.Length > 0) { GetOrCreateChain(Product).AddOption(series, isCall, Strike, option); } if (Underlying.Length > 0) { GetOrCreateChain(Underlying).AddOption(series, isCall, Strike, option); } }
/// <summary> /// Compares this option series to another one by its attributes. /// Expiration takes precedence in comparison. /// </summary> /// <param name="other">another option series to compare with.</param> /// <returns>result of comparison.</returns> public int CompareTo(OptionSeries other) { if (Expiration < other.Expiration) { return(-1); } if (Expiration > other.Expiration) { return(1); } if (LastTrade < other.LastTrade) { return(-1); } if (LastTrade > other.LastTrade) { return(1); } int i = Multiplier.CompareTo(other.Multiplier); if (i != 0) { return(i); } i = SPC.CompareTo(other.SPC); if (i != 0) { return(i); } i = AdditionalUnderlyings.CompareTo(other.AdditionalUnderlyings); if (i != 0) { return(i); } i = MMY.CompareTo(other.MMY); if (i != 0) { return(i); } i = OptionType.CompareTo(other.OptionType); if (i != 0) { return(i); } i = ExpirationStyle.CompareTo(other.ExpirationStyle); if (i != 0) { return(i); } i = SettlementStyle.CompareTo(other.SettlementStyle); if (i != 0) { return(i); } return(CFI.CompareTo(other.CFI)); }
private void SetCodePageAndFont(SCFL sfcl) { curCodePage = string.Empty; curFontCharSet = string.Empty; MCF1 map1 = aeContainer.GetStructure <MCF1>(); // MCF2 is not supported yet... if (map1 != null) { // Get mapping info with the ID specified in the SCFL field MCF1.MCF1Data mcfData = map1.MappedData.FirstOrDefault(m => m.ID == sfcl.FontId); if (mcfData != null) { // If it already has a code page/font character set specified, use that. if (!string.IsNullOrWhiteSpace(mcfData.CodePageName) && !string.IsNullOrWhiteSpace(mcfData.FontCharacterSetName)) { curCodePage = mcfData.CodePageName; curFontCharSet = mcfData.FontCharacterSetName; } else { // Otherwise, we need to load it from the coded font resource Resource codedFont = afpFile.Resources.OfTypeAndName(Resource.eResourceType.CodedFont, mcfData.CodedFontName); if (codedFont.IsLoaded) { CFI cfi = codedFont.Fields.OfType <CFI>().FirstOrDefault(); if (cfi != null && cfi.FontInfoList.Any()) { curCodePage = cfi.FontInfoList[0].CodePageName; curFontCharSet = cfi.FontInfoList[0].FontCharacterSetName; } } } } } if (!string.IsNullOrWhiteSpace(curFontCharSet)) { curFontCharSetResource = afpFile.Resources.OfTypeAndName(Resource.eResourceType.FontCharacterSet, curFontCharSet); } }
/// <summary> /// Returns a hash code value for this option series. /// </summary> /// <returns>a hash code value.</returns> public override int GetHashCode() { int result; long temp; result = Expiration; result = 31 * result + LastTrade; temp = Multiplier != +0.0d ? BitConverter.DoubleToInt64Bits(Multiplier) : 0L; result = 31 * result + (int)((ulong)temp ^ ((ulong)temp >> 32)); temp = SPC != +0.0d ? BitConverter.DoubleToInt64Bits(SPC) : 0L; result = 31 * result + (int)((ulong)temp ^ ((ulong)temp >> 32)); result = 31 * result + AdditionalUnderlyings.GetHashCode(); result = 31 * result + MMY.GetHashCode(); result = 31 * result + OptionType.GetHashCode(); result = 31 * result + ExpirationStyle.GetHashCode(); result = 31 * result + SettlementStyle.GetHashCode(); result = 31 * result + CFI.GetHashCode(); return(result); }
/// <summary> /// Indicates whether some other object is equal to this option series by its attributes. /// </summary> /// <param name="o"></param> /// <returns>another object to compare with.</returns> public override bool Equals(object o) { if (this == o) { return(true); } if (!(o is OptionSeries)) { return(false); } OptionSeries that = (OptionSeries)o; return(Expiration == that.Expiration && LastTrade == that.LastTrade && Multiplier.CompareTo(that.Multiplier) == 0 && SPC.CompareTo(that.SPC) == 0 && AdditionalUnderlyings.Equals(that.AdditionalUnderlyings) && ExpirationStyle.Equals(that.ExpirationStyle) && MMY.Equals(that.MMY) && OptionType.Equals(that.OptionType) && CFI.Equals(that.CFI) && SettlementStyle.Equals(that.SettlementStyle)); }
private void RefreshGraphicCharactersCache() { // Do nothing if the images are already cached if (fontCaches.Any()) { return; } curCodePage = ""; curFontCharSet = ""; // On every page, store a unique list of every used code point, as well as associated font information foreach (Container pc in pageContainers) { foreach (PTX ptx in pc.GetStructures <PTX>()) { foreach (PTXControlSequence cs in ptx.ControlSequences) { // Store active code page and coded font if (cs.GetType() == typeof(SCFL)) { // Lookup info from MCF1 data on this page MCF1.MCF1Data mcfData = pc.GetStructure <MCF1>()?.MappedData.First(m => m.ID == ((SCFL)cs).FontId); // If we have a coded font, we need to load that resource. Otherwise, get the values from here if (mcfData != null) { Resource codedFontResource = afpFile.Resources.OfTypeAndName(Resource.eResourceType.CodedFont, mcfData.CodedFontName); CFI resourceCFI = codedFontResource != null && codedFontResource.IsLoaded ? codedFontResource.Fields.OfType <CFI>().FirstOrDefault() : null; if (resourceCFI != null && resourceCFI.FontInfoList.Any()) { // Get the code page and font char set from the resource curCodePage = resourceCFI.FontInfoList[0].CodePageName; curFontCharSet = resourceCFI.FontInfoList[0].FontCharacterSetName; } else { // Store mcf's code page and font char set specifiers curCodePage = mcfData.CodePageName; curFontCharSet = mcfData.FontCharacterSetName; } } } else if (cs.GetType() == typeof(TRN)) { foreach (byte b in cs.Data) { // Add a new font cache item if this exact combo (byte/code page/char set) does not yet exist if (!fontCaches.Any(f => f.CodePoint == b && f.CodePage == curCodePage && f.FontCharSet == curFontCharSet)) { fontCaches.Add(new FontCache(b, curCodePage, curFontCharSet)); } } } } } } // For each byte/code point/font, generate a bitmap by looking up its resource curCodePage = ""; curFontCharSet = ""; Dictionary <byte, string> cpMappings = CodePages.C1252; Resource fontResource = null; Container foc = null; float emInchSize = 0; byte vsc = 0; foreach (FontCache fc in fontCaches.OrderBy(f => f.CodePage).ThenBy(f => f.FontCharSet)) { // Generate new code page mappings if needed if (fc.CodePage != curCodePage) { cpMappings = new Dictionary <byte, string>(); // If the code page is a resource, generate from scratch Resource cp = afpFile.Resources.OfTypeAndName(Resource.eResourceType.CodePage, fc.CodePage); if (cp != null && cp.IsLoaded) { foreach (CPI.Info info in cp.Fields.OfType <CPI>().First().CPIInfos) { cpMappings.Add(info.CodePoints[0], info.GID); } // Is variable space char if the byte equals the one specified by the code page descriptor vsc = cp.Fields.OfType <CPC>().First().VariableSpaceCharacter; } // Else, get by looking up last 4 page digits else { // Get probably name of static field in Code Pages lookups string sectionedCodePage = string.Empty; if (fc.CodePage.Length >= 4) { sectionedCodePage = $"C{fc.CodePage.Substring(fc.CodePage.Length - 4)}"; } // Find the matching lookup method in our code page helper class FieldInfo field = typeof(CodePages).GetField(sectionedCodePage); if (field != null) { cpMappings = (Dictionary <byte, string>)field.GetValue(null); } // Is variable space character if the byte GID equals SP010000 vsc = cpMappings.First(c => c.Value == "SP010000").Key; } curCodePage = fc.CodePage; } // Lookup new font character set if needed if (fc.FontCharSet != curFontCharSet) { fontResource = afpFile.Resources.OfTypeAndName(Resource.eResourceType.FontCharacterSet, fc.FontCharSet); curFontCharSet = fc.FontCharSet; foc = fontResource.Fields[0].LowestLevelContainer; emInchSize = foc.GetStructure <FND>().EmInches; } // Generate a bitmap for this code point by looking up the raster pattern of the FCS by current code page string gid = cpMappings.ContainsKey(fc.CodePoint) ? cpMappings[fc.CodePoint] : string.Empty; if (!string.IsNullOrEmpty(gid) && fontResource != null && fontResource.IsLoaded && afpFile.ParsedFontPatterns.ContainsKey(foc)) { // Get raster pattern info of GID KeyValuePair <FNI.Info, bool[, ]> pattern = afpFile.ParsedFontPatterns[foc].FirstOrDefault(p => p.Key.GCGID == gid); // Build bitmap if (pattern.Key != null) { // Set font and variable space info here fc.FontInfo = pattern.Key; fc.IsVariableSpaceChar = fc.CodePoint == vsc; fc.EmInchSize = emInchSize; Bitmap bmp = new Bitmap(pattern.Value.GetUpperBound(0) + 1, pattern.Value.GetUpperBound(1) + 1); for (int y = 0; y < bmp.Height; y++) { for (int x = 0; x < bmp.Width; x++) { if (pattern.Value[x, y]) { bmp.SetPixel(x, y, Color.Black); // Set to black - we remap colors later } } } // Since we know how many inches 1 em is, we can determine inch width and height of each character float heightInches = emInchSize * ((pattern.Key.AscenderHeight + pattern.Key.DescenderDepth) / 1000f); float dpi = (float)Math.Round(bmp.Height / heightInches); bmp.SetResolution(dpi, dpi); // Assign to font cache fc.Pattern = bmp; } } } }