<commit_before>#region S# License
/******************************************************************************************
NOTICE!!!  This program and source code is owned and licensed by
StockSharp, LLC, www.stocksharp.com
Viewing or use of this code requires your acceptance of the license
agreement found at https://github.com/StockSharp/StockSharp/blob/master/LICENSE
Removal of this comment is a violation of the license agreement.

Project: StockSharp.Algo.Derivatives.Algo
File: DerivativesHelper.cs
Created: 2015, 11, 11, 2:32 PM

Copyright 2010 by StockSharp, LLC
*******************************************************************************************/
#endregion S# License
namespace StockSharp.Algo.Derivatives
{
	using System;
	using System.Collections.Generic;
	using System.Globalization;
	using System.Linq;
	using System.Text.RegularExpressions;

	using Ecng.Collections;
	using Ecng.Common;

	using MathNet.Numerics.Distributions;

	using StockSharp.BusinessEntities;
	using StockSharp.Messages;
	using StockSharp.Localization;

	/// <summary>
	/// Extension class for derivatives.
	/// </summary>
	public static class DerivativesHelper
	{
		private static readonly Regex _futureNameRegex = new Regex(@"(?<code>[A-Z,a-z]+)-(?<expiryMonth>[0-9]{1,2})\.(?<expiryYear>[0-9]{1,2})", RegexOptions.Compiled);
		private static readonly Regex _optionNameRegex = new Regex(@"(?<code>\w+-[0-9]{1,2}\.[0-9]{1,2})(?<isMargin>[M_])(?<expiryDate>[0-9]{6,6})(?<optionType>[CP])(?<region>\w)\s(?<strike>\d*\.*\d*)", RegexOptions.Compiled);
		private static readonly Regex _optionCodeRegex = new Regex(@"(?<code>[A-Z,a-z]+)(?<strike>\d*\.*\d*)(?<optionType>[BA])(?<expiryMonth>[A-X]{1})(?<expiryYear>[0-9]{1})", RegexOptions.Compiled);

		private static readonly SynchronizedPairSet<int, char> _futureMonthCodes = new SynchronizedPairSet<int, char>();
		private static readonly SynchronizedPairSet<int, char> _optionCallMonthCodes = new SynchronizedPairSet<int, char>();
		private static readonly SynchronizedPairSet<int, char> _optionPutMonthCodes = new SynchronizedPairSet<int, char>();
		private static readonly Normal _normalDistribution = new Normal();

		static DerivativesHelper()
		{
			// http://www.rts.ru/s193
			_futureMonthCodes.Add(1, 'F');
			_futureMonthCodes.Add(2, 'G');
			_futureMonthCodes.Add(3, 'H');
			_futureMonthCodes.Add(4, 'J');
			_futureMonthCodes.Add(5, 'K');
			_futureMonthCodes.Add(6, 'M');
			_futureMonthCodes.Add(7, 'N');
			_futureMonthCodes.Add(8, 'Q');
			_futureMonthCodes.Add(9, 'U');
			_futureMonthCodes.Add(10, 'V');
			_futureMonthCodes.Add(11, 'X');
			_futureMonthCodes.Add(12, 'Z');

			_optionCallMonthCodes.Add(1, 'A');
			_optionCallMonthCodes.Add(2, 'B');
			_optionCallMonthCodes.Add(3, 'C');
			_optionCallMonthCodes.Add(4, 'D');
			_optionCallMonthCodes.Add(5, 'E');
			_optionCallMonthCodes.Add(6, 'F');
			_optionCallMonthCodes.Add(7, 'G');
			_optionCallMonthCodes.Add(8, 'H');
			_optionCallMonthCodes.Add(9, 'I');
			_optionCallMonthCodes.Add(10, 'J');
			_optionCallMonthCodes.Add(11, 'K');
			_optionCallMonthCodes.Add(12, 'L');

			_optionPutMonthCodes.Add(1, 'M');
			_optionPutMonthCodes.Add(2, 'N');
			_optionPutMonthCodes.Add(3, 'O');
			_optionPutMonthCodes.Add(4, 'P');
			_optionPutMonthCodes.Add(5, 'Q');
			_optionPutMonthCodes.Add(6, 'R');
			_optionPutMonthCodes.Add(7, 'S');
			_optionPutMonthCodes.Add(8, 'T');
			_optionPutMonthCodes.Add(9, 'U');
			_optionPutMonthCodes.Add(10, 'V');
			_optionPutMonthCodes.Add(11, 'W');
			_optionPutMonthCodes.Add(12, 'X');
		}

		private static readonly SynchronizedDictionary<Security, Security> _underlyingSecurities = new SynchronizedDictionary<Security, Security>();

		/// <summary>
		/// To get the underlying asset by the derivative.
		/// </summary>
		/// <param name="derivative">The derivative.</param>
		/// <param name="provider">The provider of information about instruments.</param>
		/// <returns>Underlying asset.</returns>
		public static Security GetUnderlyingAsset(this Security derivative, ISecurityProvider provider)
		{
			if (derivative == null)
				throw new ArgumentNullException(nameof(derivative));

			if (provider == null)
				throw new ArgumentNullException(nameof(provider));

			if (derivative.Type == SecurityTypes.Option)
			{
				derivative.CheckOption();

				return _underlyingSecurities.SafeAdd(derivative, key =>
				{
					var underlyingSecurity = provider.LookupById(key.UnderlyingSecurityId);

					if (underlyingSecurity == null)
						throw new InvalidOperationException(LocalizedStrings.Str704Params.Put(key.UnderlyingSecurityId));

					return underlyingSecurity;
				});
			}
			else
			{
				return provider.LookupById(derivative.UnderlyingSecurityId);
			}
		}

		/// <summary>
		/// To filter options by the strike <see cref="Security.Strike"/>.
		/// </summary>
		/// <param name="options">Options to be filtered.</param>
		/// <param name="strike">The strike price.</param>
		/// <returns>Filtered options.</returns>
		public static IEnumerable<Security> Filter(this IEnumerable<Security> options, decimal strike)
		{
			return options.Where(o => o.Strike == strike);
		}
<commit_msg>DerivativesHelper. GetUnderlyingAsset small fix.<commit_after>#region S# License
/******************************************************************************************
NOTICE!!!  This program and source code is owned and licensed by
StockSharp, LLC, www.stocksharp.com
Viewing or use of this code requires your acceptance of the license
agreement found at https://github.com/StockSharp/StockSharp/blob/master/LICENSE
Removal of this comment is a violation of the license agreement.

Project: StockSharp.Algo.Derivatives.Algo
File: DerivativesHelper.cs
Created: 2015, 11, 11, 2:32 PM

Copyright 2010 by StockSharp, LLC
*******************************************************************************************/
#endregion S# License
namespace StockSharp.Algo.Derivatives
{
	using System;
	using System.Collections.Generic;
	using System.Globalization;
	using System.Linq;
	using System.Text.RegularExpressions;

	using Ecng.Collections;
	using Ecng.Common;

	using MathNet.Numerics.Distributions;

	using StockSharp.BusinessEntities;
	using StockSharp.Messages;
	using StockSharp.Localization;

	/// <summary>
	/// Extension class for derivatives.
	/// </summary>
	public static class DerivativesHelper
	{
		private static readonly Regex _futureNameRegex = new Regex(@"(?<code>[A-Z,a-z]+)-(?<expiryMonth>[0-9]{1,2})\.(?<expiryYear>[0-9]{1,2})", RegexOptions.Compiled);
		private static readonly Regex _optionNameRegex = new Regex(@"(?<code>\w+-[0-9]{1,2}\.[0-9]{1,2})(?<isMargin>[M_])(?<expiryDate>[0-9]{6,6})(?<optionType>[CP])(?<region>\w)\s(?<strike>\d*\.*\d*)", RegexOptions.Compiled);
		private static readonly Regex _optionCodeRegex = new Regex(@"(?<code>[A-Z,a-z]+)(?<strike>\d*\.*\d*)(?<optionType>[BA])(?<expiryMonth>[A-X]{1})(?<expiryYear>[0-9]{1})", RegexOptions.Compiled);

		private static readonly SynchronizedPairSet<int, char> _futureMonthCodes = new SynchronizedPairSet<int, char>();
		private static readonly SynchronizedPairSet<int, char> _optionCallMonthCodes = new SynchronizedPairSet<int, char>();
		private static readonly SynchronizedPairSet<int, char> _optionPutMonthCodes = new SynchronizedPairSet<int, char>();
		private static readonly Normal _normalDistribution = new Normal();

		static DerivativesHelper()
		{
			// http://www.rts.ru/s193
			_futureMonthCodes.Add(1, 'F');
			_futureMonthCodes.Add(2, 'G');
			_futureMonthCodes.Add(3, 'H');
			_futureMonthCodes.Add(4, 'J');
			_futureMonthCodes.Add(5, 'K');
			_futureMonthCodes.Add(6, 'M');
			_futureMonthCodes.Add(7, 'N');
			_futureMonthCodes.Add(8, 'Q');
			_futureMonthCodes.Add(9, 'U');
			_futureMonthCodes.Add(10, 'V');
			_futureMonthCodes.Add(11, 'X');
			_futureMonthCodes.Add(12, 'Z');

			_optionCallMonthCodes.Add(1, 'A');
			_optionCallMonthCodes.Add(2, 'B');
			_optionCallMonthCodes.Add(3, 'C');
			_optionCallMonthCodes.Add(4, 'D');
			_optionCallMonthCodes.Add(5, 'E');
			_optionCallMonthCodes.Add(6, 'F');
			_optionCallMonthCodes.Add(7, 'G');
			_optionCallMonthCodes.Add(8, 'H');
			_optionCallMonthCodes.Add(9, 'I');
			_optionCallMonthCodes.Add(10, 'J');
			_optionCallMonthCodes.Add(11, 'K');
			_optionCallMonthCodes.Add(12, 'L');

			_optionPutMonthCodes.Add(1, 'M');
			_optionPutMonthCodes.Add(2, 'N');
			_optionPutMonthCodes.Add(3, 'O');
			_optionPutMonthCodes.Add(4, 'P');
			_optionPutMonthCodes.Add(5, 'Q');
			_optionPutMonthCodes.Add(6, 'R');
			_optionPutMonthCodes.Add(7, 'S');
			_optionPutMonthCodes.Add(8, 'T');
			_optionPutMonthCodes.Add(9, 'U');
			_optionPutMonthCodes.Add(10, 'V');
			_optionPutMonthCodes.Add(11, 'W');
			_optionPutMonthCodes.Add(12, 'X');
		}

		private static readonly SynchronizedDictionary<Security, Security> _underlyingSecurities = new SynchronizedDictionary<Security, Security>();

		/// <summary>
		/// To get the underlying asset by the derivative.
		/// </summary>
		/// <param name="derivative">The derivative.</param>
		/// <param name="provider">The provider of information about instruments.</param>
		/// <returns>Underlying asset.</returns>
		public static Security GetUnderlyingAsset(this Security derivative, ISecurityProvider provider)
		{
			if (derivative == null)
				throw new ArgumentNullException(nameof(derivative));

			if (provider == null)
				throw new ArgumentNullException(nameof(provider));

			if (derivative.Type == SecurityTypes.Option)
			{
				derivative.CheckOption();

				return _underlyingSecurities.SafeAdd(derivative, key =>
				{
					var underlyingSecurity = provider.LookupById(key.UnderlyingSecurityId);

					if (underlyingSecurity == null)
						throw new InvalidOperationException(LocalizedStrings.Str704Params.Put(key.UnderlyingSecurityId));

					return underlyingSecurity;
				});
			}
			else
			{
				return !derivative.UnderlyingSecurityId.IsEmpty() ? provider.LookupById(derivative.UnderlyingSecurityId) : derivative;
			}
		}

		/// <summary>
		/// To filter options by the strike <see cref="Security.Strike"/>.
		/// </summary>
		/// <param name="options">Options to be filtered.</param>
		/// <param name="strike">The strike price.</param>
		/// <returns>Filtered options.</returns>
		public static IEnumerable<Security> Filter(this IEnumerable<Security> options, decimal strike)
		{
			return options.Where(o => o.Strike == strike);
		}

{'fraction_non_alphanumeric': 0.18140785556515893, 'fraction_numerical': 0.01728608470181504, 'mean_word_length': 5.11150234741784, 'pattern_counts': {'":': 0, '<': 89, '<?xml version=': 0, '>': 93, 'https://': 2, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7541282', 'n_tokens_mistral': 3802, 'n_tokens_neox': 3362, 'n_words': 673}