protected override MarketDataRequest MarketDataRequest(
            string mic,
            InstrumentIdentifiers identifiers,
            DateTime universeDateTime,
            ISystemProcessOperationRunRuleContext ctx,
            DataSource dataSource)
        {
            var tradingHours = this.TradingHoursService.GetTradingHoursForMic(mic);

            if (!tradingHours.IsValid)
            {
                this.Logger.LogError(
                    $"RevenueCurrencyConvertingMarkingCloseCalculator was not able to get meaningful trading hours for the mic {mic}. Unable to proceed with currency conversions.");
                return(null);
            }

            return(new MarketDataRequest(
                       mic,
                       string.Empty,
                       identifiers,
                       tradingHours.ClosingInUtcForDay(universeDateTime).Subtract(TimeSpan.FromMinutes(15)),
                       tradingHours.ClosingInUtcForDay(universeDateTime),
                       ctx?.Id(),
                       dataSource));
        }
示例#2
0
        public PlacingOrderWithNoIntentToExecuteRuleRuleBreach(
            TimeSpan window,
            ITradePosition trades,
            FinancialInstrument security,
            IFactorValue factorValue,
            decimal meanPrice,
            decimal sdPrice,
            IReadOnlyCollection <ProbabilityOfExecution> probabilityForOrders,
            IPlacingOrderWithNoIntentToExecuteRuleEquitiesParameters parameters,
            ISystemProcessOperationRunRuleContext ctx,
            string description,
            string caseTitle,
            DateTime universeDateTime)
        {
            this.Window   = window;
            this.Trades   = trades;
            this.Security = security;

            this.FactorValue = factorValue;
            this.Parameters  = parameters;

            this.MeanPrice = meanPrice;
            this.StandardDeviationPrice = sdPrice;
            this.ProbabilityForOrders   = probabilityForOrders ?? new List <ProbabilityOfExecution>();

            this.RuleParameterId   = parameters.Id;
            this.SystemOperationId = ctx.Id();
            this.CorrelationId     = ctx.CorrelationId();
            this.RuleParameters    = parameters;
            this.Description       = description ?? string.Empty;
            this.CaseTitle         = caseTitle ?? string.Empty;
            this.UniverseDateTime  = universeDateTime;
        }
        /// <summary>
        /// The market data request.
        /// </summary>
        /// <param name="marketIdentifierCode">
        /// The market identifier code.
        /// </param>
        /// <param name="identifiers">
        /// The identifiers.
        /// </param>
        /// <param name="universeDateTime">
        /// The universe date time.
        /// </param>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <param name="dataSource">
        /// The data source.
        /// </param>
        /// <returns>
        /// The <see cref="MarketDataRequest"/>.
        /// </returns>
        protected virtual MarketDataRequest MarketDataRequest(
            string marketIdentifierCode,
            InstrumentIdentifiers identifiers,
            DateTime universeDateTime,
            ISystemProcessOperationRunRuleContext context,
            DataSource dataSource)
        {
            var tradingHours = this.TradingHoursService.GetTradingHoursForMic(marketIdentifierCode);

            if (!tradingHours.IsValid)
            {
                this.Logger.LogError(
                    $"RevenueCurrencyConvertingCalculator was not able to get meaningful trading hours for the mic {marketIdentifierCode}. Unable to proceed with currency conversions.");
                return(null);
            }

            return(new MarketDataRequest(
                       marketIdentifierCode,
                       string.Empty,
                       identifiers,
                       tradingHours.OpeningInUtcForDay(universeDateTime),
                       tradingHours.MinimumOfCloseInUtcForDayOrUniverse(universeDateTime),
                       context?.Id(),
                       dataSource));
        }
示例#4
0
        public bool Filter(IUniverseEvent universeEvent)
        {
            if (universeEvent == null)
            {
                return(false);
            }

            if (universeEvent.StateChange == UniverseStateEvent.EquityInterDayTick)
            {
                EquityInterDay(universeEvent);
            }

            if (universeEvent.StateChange == UniverseStateEvent.Eschaton &&
                _requestData &&
                _ruleRunMode == RuleRunMode.ValidationRun)
            {
                _universeDataRequestsSubscriber.SubmitRequest();
            }

            if (universeEvent.StateChange != UniverseStateEvent.Order &&
                universeEvent.StateChange != UniverseStateEvent.OrderPlaced)
            {
                return(false);
            }

            if (!(universeEvent.UnderlyingEvent is Order mostRecentTrade))
            {
                return(false);
            }

            if (_marketCapFilter?.Type != RuleFilterType.Include)
            {
                return(false);
            }

            var tradingHours = _tradingHoursService.GetTradingHoursForMic(mostRecentTrade.Market?.MarketIdentifierCode);

            if (!tradingHours.IsValid)
            {
                _logger.LogError($"Request for trading hours was invalid. MIC - {mostRecentTrade.Market?.MarketIdentifierCode}");
                return(true);
            }

            var universeDateTime  = universeEvent.EventTime;
            var marketDataRequest = new MarketDataRequest(
                mostRecentTrade.Market?.MarketIdentifierCode,
                mostRecentTrade.Instrument.Cfi,
                mostRecentTrade.Instrument.Identifiers,
                tradingHours.OpeningInUtcForDay(universeDateTime),
                tradingHours.MinimumOfCloseInUtcForDayOrUniverse(universeDateTime),
                _operationRunRuleContext?.Id(),
                DataSource.AnyInterday);

            var securityResult = _universeEquityInterdayCache.Get(marketDataRequest);

            if (securityResult.HadMissingData && _ruleRunMode == RuleRunMode.ValidationRun)
            {
                _requestData = true;
            }

            if (securityResult.HadMissingData)
            {
                _logger.LogInformation($"Missing data for {marketDataRequest}.");
                return(true);
            }

            var security  = securityResult.Response;
            var marketCap = security.DailySummaryTimeBar.MarketCap;

            if (marketCap == null)
            {
                this._logger.LogInformation($"Missing data for market cap from daily summary time bar {marketDataRequest}.");
                return(true);
            }

            var marketCapInUsd = this.currencyConverterService.Convert(
                new[] { marketCap.Value },
                new Currency("USD"),
                universeDateTime,
                this._operationRunRuleContext).Result;

            if (marketCapInUsd == null)
            {
                this._logger.LogInformation($"Missing data for market cap currency conversion into USD at {universeEvent} from daily summary time bar {marketDataRequest}.");
                return(true);
            }

            var min = this._marketCapFilter.Min ?? marketCap.Value.Value;
            var max = this._marketCapFilter.Max ?? marketCap.Value.Value;

            return(!(marketCap.Value.Value >= min && marketCap.Value.Value <= max));
        }
        public async Task <Money?> Convert(
            IReadOnlyCollection <Money> monies,
            Currency targetCurrency,
            DateTime dayOfConversion,
            ISystemProcessOperationRunRuleContext ruleCtx)
        {
            if (monies == null || !monies.Any())
            {
                this._logger.LogInformation(
                    $"received null or empty currency amounts. Returning 0 currency amount in target currency of {targetCurrency} for rule {ruleCtx?.Id()}");
                return(new Money(0, targetCurrency));
            }

            if (string.IsNullOrWhiteSpace(targetCurrency.Code))
            {
                this._logger.LogError("asked to convert to a null or empty currency");
                return(monies.Aggregate((i, o) => new Money(i.Value + o.Value, i.Currency)));
            }

            if (monies.All(ca => Equals(ca.Currency, targetCurrency)))
            {
                this._logger.LogInformation(
                    "inferred all currency amounts matched the target currency. Aggregating trades and returning.");
                return(monies.Aggregate((i, o) => new Money(i.Value + o.Value, i.Currency)));
            }

            this._logger.LogInformation($"about to fetch exchange rates on {dayOfConversion}");
            var rates = await this.ExchangeRates(dayOfConversion, ruleCtx);

            if (rates == null || !rates.Any())
            {
                this._logger.LogError(
                    $"unable to change rates to {targetCurrency.Code} on {dayOfConversion.ToShortDateString()} due to missing rates");
                ruleCtx.EventException(
                    $"unable to change rates to {targetCurrency.Code} on {dayOfConversion.ToShortDateString()} due to missing rates");

                return(null);
            }

            var convertedToTargetCurrency = monies.Select(
                currency => this.Convert(rates, currency, targetCurrency, dayOfConversion, ruleCtx)).ToList();

            var totalInConvertedCurrency = convertedToTargetCurrency.Where(cc => cc.HasValue).Select(cc => cc.Value)
                                           .Sum(cc => cc.Value);

            this._logger.LogInformation($"returning {totalInConvertedCurrency} ({targetCurrency})");
            return(new Money(totalInConvertedCurrency, targetCurrency));
        }