public static MarketRule<Security, Security> WhenBestAskPriceLess(this Security security, IConnector connector, Unit price)
		{
			return CreateSecurityCondition(security, connector, Level1Fields.BestAskPrice, price, true);
		}
		public static MarketRule<Security, Security> WhenLastTradePriceMore(this Security security, IConnector connector, IMarketDataProvider provider, Unit price)
		{
			return CreateLastTradeCondition(security, connector, provider, price, false);
		}
//-----------------------------------------------------------------------------------------------------------------------------------
		private static SecurityChangedRule CreateSecurityCondition(Security security, IConnector connector, Level1Fields field, Unit offset, bool isLess)
		{
			if (security == null)
				throw new ArgumentNullException(nameof(security));
			if (offset == null)
				throw new ArgumentNullException(nameof(offset));
			if (offset.Value == 0)
				throw new ArgumentException(LocalizedStrings.Str1051, nameof(offset));
			if (offset.Value < 0)
				throw new ArgumentException(LocalizedStrings.Str1052, nameof(offset));
			var price = (decimal?)connector.GetSecurityValue(security, field);
			if (price == null && offset.Type != UnitTypes.Limit)
				throw new InvalidOperationException(LocalizedStrings.Str1053);
			if (isLess)
			{
				var finishPrice = (decimal)(offset.Type == UnitTypes.Limit ? offset : price - offset);
				return new SecurityChangedRule(security, connector, s =>
				{
					var quote = (decimal?)connector.GetSecurityValue(s, field);
					return quote != null && quote < finishPrice;
				});
			}
			else
			{
				var finishPrice = (decimal)(offset.Type == UnitTypes.Limit ? offset : price + offset);
				return new SecurityChangedRule(security, connector, s =>
				{
					var quote = (decimal?)connector.GetSecurityValue(s, field);
					return quote != null && quote > finishPrice;
				});
			}
//-----------------------------------------------------------------------------------------------------------------------------------
		private sealed class SecurityLastTradeRule : SecurityRule<Security>
		{
			private readonly Func<Security, bool> _condition;
			public SecurityLastTradeRule(Security security, IConnector connector, Func<Security, bool> condition)
				: base(security, connector)
			{
				if (condition == null)
					throw new ArgumentNullException(nameof(condition));
				_condition = condition;
				Name = LocalizedStrings.Str1049 + " " + security;
				Connector.SecurityChanged += OnSecurityChanged;
				Connector.NewTrade += OnNewTrade;
			}
			private void OnSecurityChanged(Security security)
			{
				if (CheckLastTrade(security))
					Activate(security);
			}
			private bool CheckLastTrade(Security security)
			{
				if (Security is BasketSecurity basket)
				{
					return basket.Contains(SecurityProvider, security) && _condition(security);
				}
				else
				{
					return security == Security && _condition(Security);
				}
			}
			private void OnNewTrade(Trade trade)
			{
				if (CheckTrades(Security, trade))
					Activate(trade.Security);
			}
			private bool CheckTrades(Security security, Trade trade)
			{
				return security is BasketSecurity basket
					? basket.Contains(SecurityProvider, trade.Security) && _condition(trade.Security)
					: trade.Security == security && _condition(trade.Security);
			}
			protected override void DisposeManaged()
			{
				Connector.NewTrade -= OnNewTrade;
				Connector.SecurityChanged -= OnSecurityChanged;
				base.DisposeManaged();
			}
		}