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();
}
}