/// <summary> /// Initializes a new instance of the <see cref="BaseUniverseRule"/> class. /// </summary> /// <param name="tradeBackwardWindowSize"> /// The trade backward window size. /// </param> /// <param name="marketBackwardWindowSize"> /// The market backward window size. /// </param> /// <param name="forwardWindowSize"> /// The forward window size. /// </param> /// <param name="rules"> /// The rules. /// </param> /// <param name="version"> /// The version. /// </param> /// <param name="name"> /// The name. /// </param> /// <param name="ruleContext"> /// The rule context. /// </param> /// <param name="equityFactory"> /// The equity factory. /// </param> /// <param name="fixedIncomeFactory"> /// The fixed income factory. /// </param> /// <param name="runMode"> /// The run mode. /// </param> /// <param name="logger"> /// The logger. /// </param> /// <param name="tradingStackLogger"> /// The trading stack logger. /// </param> protected BaseUniverseRule( TimeSpan tradeBackwardWindowSize, TimeSpan marketBackwardWindowSize, TimeSpan forwardWindowSize, Rules rules, string version, string name, ISystemProcessOperationRunRuleContext ruleContext, IUniverseEquityMarketCacheFactory equityFactory, IUniverseFixedIncomeMarketCacheFactory fixedIncomeFactory, RuleRunMode runMode, ILogger logger, ILogger <TradingHistoryStack> tradingStackLogger) { this.TradeBackwardWindowSize = tradeBackwardWindowSize; this.ForwardWindowSize = forwardWindowSize; this.Rule = rules; this.Version = version ?? string.Empty; this.UniverseEquityIntradayCache = equityFactory?.BuildIntraday(marketBackwardWindowSize, runMode) ?? throw new ArgumentNullException(nameof(equityFactory)); this.FutureUniverseEquityIntradayCache = equityFactory?.BuildIntraday(forwardWindowSize, runMode) ?? throw new ArgumentNullException(nameof(equityFactory)); this.UniverseEquityInterdayCache = equityFactory?.BuildInterday(runMode) ?? throw new ArgumentNullException(nameof(equityFactory)); this.UniverseFixedIncomeIntradayCache = fixedIncomeFactory?.BuildIntraday(marketBackwardWindowSize, runMode) ?? throw new ArgumentNullException(nameof(fixedIncomeFactory)); this.FutureUniverseFixedIncomeIntradayCache = fixedIncomeFactory?.BuildIntraday(forwardWindowSize, runMode) ?? throw new ArgumentNullException(nameof(fixedIncomeFactory)); this.UniverseFixedIncomeInterdayCache = fixedIncomeFactory?.BuildInterday(runMode) ?? throw new ArgumentNullException(nameof(fixedIncomeFactory)); this.TradingHistory = new ConcurrentDictionary <InstrumentIdentifiers, ITradingHistoryStack>(); this.TradingFillsHistory = new ConcurrentDictionary <InstrumentIdentifiers, ITradingHistoryStack>(); this.TradingInitialHistory = new ConcurrentDictionary <InstrumentIdentifiers, ITradingHistoryStack>(); this.DelayedTradingHistory = new ConcurrentDictionary <InstrumentIdentifiers, ITradingHistoryStack>(); this.DelayedTradingFillsHistory = new ConcurrentDictionary <InstrumentIdentifiers, ITradingHistoryStack>(); this.DelayedTradingInitialHistory = new ConcurrentDictionary <InstrumentIdentifiers, ITradingHistoryStack>(); this.RuleCtx = ruleContext ?? throw new ArgumentNullException(nameof(ruleContext)); this.name = name ?? "Unnamed rule"; this.RunMode = runMode; this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); this.tradingStackLogger = tradingStackLogger ?? throw new ArgumentNullException(nameof(tradingStackLogger)); }
/// <summary> /// The base clone. /// </summary> public void BaseClone() { this.UniverseEquityIntradayCache = (IUniverseEquityIntraDayCache)this.UniverseEquityIntradayCache.Clone(); this.UniverseEquityInterdayCache = (IUniverseEquityInterDayCache)this.UniverseEquityInterdayCache.Clone(); this.FutureUniverseEquityIntradayCache = (IUniverseEquityIntraDayCache)this.FutureUniverseEquityIntradayCache.Clone(); this.UniverseFixedIncomeInterdayCache = (IUniverseFixedIncomeInterDayCache)this.UniverseFixedIncomeInterdayCache.Clone(); this.UniverseFixedIncomeIntradayCache = (IUniverseFixedIncomeIntraDayCache)this.UniverseFixedIncomeIntradayCache.Clone(); this.FutureUniverseFixedIncomeIntradayCache = (IUniverseFixedIncomeIntraDayCache)this.FutureUniverseFixedIncomeIntradayCache.Clone(); this.TradingHistory = new ConcurrentDictionary <InstrumentIdentifiers, ITradingHistoryStack>(this.TradingHistory); this.TradingFillsHistory = new ConcurrentDictionary <InstrumentIdentifiers, ITradingHistoryStack>(this.TradingFillsHistory); this.TradingInitialHistory = new ConcurrentDictionary <InstrumentIdentifiers, ITradingHistoryStack>(this.TradingInitialHistory); this.DelayedTradingHistory = new ConcurrentDictionary <InstrumentIdentifiers, ITradingHistoryStack>(this.DelayedTradingHistory); this.DelayedTradingFillsHistory = new ConcurrentDictionary <InstrumentIdentifiers, ITradingHistoryStack>(this.DelayedTradingFillsHistory); this.DelayedTradingInitialHistory = new ConcurrentDictionary <InstrumentIdentifiers, ITradingHistoryStack>(this.DelayedTradingInitialHistory); }
public EquityIntraDayMarketCacheStrategy(IUniverseEquityIntraDayCache cache) { this._cache = cache ?? throw new ArgumentNullException(nameof(cache)); }
public void Setup() { this._interdayCache = A.Fake <IUniverseEquityInterDayCache>(); this._intradayCache = A.Fake <IUniverseEquityIntraDayCache>(); }
/// <summary> /// The evaluate high profits. /// </summary> /// <param name="history"> /// The history. /// </param> /// <param name="intradayCache"> /// The intraday cache. /// </param> protected void EvaluateHighProfits(ITradingHistoryStack history, IUniverseEquityIntraDayCache intradayCache) { if (!this.RunRuleGuard(history)) { return; } var orderUnderAnalysis = this.UniverseEvent.UnderlyingEvent as Order; var activeTrades = history.ActiveTradeHistory(); var liveTrades = activeTrades.Where(at => at.OrderStatus() == OrderStatus.Filled).ToList(); if (orderUnderAnalysis == null) { orderUnderAnalysis = activeTrades.LastOrDefault(); } if (!liveTrades.Any()) { this.SetNoLiveTradesJudgement(orderUnderAnalysis); return; } var targetCurrency = new Currency(this.EquitiesParameters.HighProfitCurrencyConversionTargetCurrency); var allTradesInCommonCurrency = liveTrades.Any() && liveTrades.All( x => string.Equals( x.OrderCurrency.Code, targetCurrency.Code, StringComparison.InvariantCultureIgnoreCase)); var costCalculator = this.GetCostCalculator(allTradesInCommonCurrency, targetCurrency); var revenueCalculator = this.GetRevenueCalculator(allTradesInCommonCurrency, targetCurrency); var marketCache = this.MarketClosureRule ? this.MarketDataCacheFactory.InterdayStrategy(this.UniverseEquityInterdayCache) : this.MarketDataCacheFactory.IntradayStrategy(intradayCache); var costTask = costCalculator.CalculateCostOfPosition(liveTrades, this.UniverseDateTime, this.RuleContext); var revenueTask = revenueCalculator.CalculateRevenueOfPosition( liveTrades, this.UniverseDateTime, this.RuleContext, marketCache); var cost = costTask.Result; var revenueResponse = revenueTask.Result; if (revenueResponse.HadMissingMarketData) { this.SetMissingMarketDataJudgement(orderUnderAnalysis); this.HasMissingData = true; return; } var revenue = revenueResponse.Money; if (revenue == null || revenue.Value.Value <= 0) { this.Logger.LogInformation( $"rule had null for revenues for {liveTrades.FirstOrDefault()?.Instrument?.Identifiers} at {this.UniverseDateTime}. Returning."); this.NoRevenueOrCostJudgement(orderUnderAnalysis); return; } if (cost == null || cost.Value.Value <= 0) { this.Logger.LogError( $"something went wrong. We have calculable revenues but not costs for {liveTrades.FirstOrDefault()?.Instrument?.Identifiers} at {this.UniverseDateTime}. Returning."); this.NoRevenueOrCostJudgement(orderUnderAnalysis); return; } if (!revenue.Value.DenominatedInCommonCurrency(cost.Value)) { var convertedCostTask = this.currencyConversionService.Convert(new[] { cost.Value }, revenue.Value.Currency, UniverseDateTime, RuleCtx); var convertedCost = convertedCostTask.Result; if (convertedCost == null) { this.Logger.LogError($"Currency of revenue {revenue.Value.Currency} - currency of costs {cost.Value.Currency} for trade {liveTrades.FirstOrDefault()?.Instrument?.Identifiers} at {this.UniverseDateTime}."); return; } cost = convertedCost.Value; } this.Logger.LogInformation($"Calculating absolute profit Currency of revenue {revenue.Value.Currency} - currency of costs {cost.Value.Currency} for trade {liveTrades.FirstOrDefault()?.Instrument?.Identifiers} at {this.UniverseDateTime}."); var absoluteProfit = revenue.Value - cost.Value; this.Logger.LogInformation($"Calculating profit ratio Currency of revenue {revenue.Value.Currency} - currency of costs {cost.Value.Currency} for trade {liveTrades.FirstOrDefault()?.Instrument?.Identifiers} at {this.UniverseDateTime}."); var profitRatio = revenue.Value.Value / cost.Value.Value - 1; this.Logger.LogInformation($"Calculating success profit ratio Currency of revenue {revenue.Value.Currency} - currency of costs {cost.Value.Currency} for trade {liveTrades.FirstOrDefault()?.Instrument?.Identifiers} at {this.UniverseDateTime}."); var hasHighProfitAbsolute = this.HasHighProfitAbsolute(absoluteProfit); var hasHighProfitPercentage = this.HasHighProfitPercentage(profitRatio); IExchangeRateProfitBreakdown exchangeRateProfits = null; if (this.EquitiesParameters.UseCurrencyConversions && !string.IsNullOrEmpty( this.EquitiesParameters.HighProfitCurrencyConversionTargetCurrency)) { this.Logger.LogInformation( $"is set to use currency conversions and has a target conversion currency to {this.EquitiesParameters.HighProfitCurrencyConversionTargetCurrency}. Calling set exchange rate profits."); exchangeRateProfits = this.SetExchangeRateProfits(liveTrades); } RuleBreachContext ruleBreachContext = null; if (hasHighProfitAbsolute || hasHighProfitPercentage) { this.Logger.LogInformation( $"had a breach for {liveTrades.FirstOrDefault()?.Instrument?.Identifiers} at {this.UniverseDateTime}. High Profit Absolute {hasHighProfitAbsolute} and High Profit Percentage {hasHighProfitPercentage}."); ruleBreachContext = new RuleBreachContext( this.EquitiesParameters.Windows.BackwardWindowSize + this.EquitiesParameters.Windows.FutureWindowSize, new TradePosition(liveTrades), liveTrades.FirstOrDefault(_ => _?.Instrument != null)?.Instrument, this.RuleContext.IsBackTest(), this.RuleContext.RuleParameterId(), this.RuleContext.SystemProcessOperationContext().Id.ToString(), this.RuleContext.CorrelationId(), this.OrganisationFactorValue, this.EquitiesParameters, this.UniverseDateTime); } this.SetJudgementForFullAnalysis( absoluteProfit, profitRatio, hasHighProfitAbsolute, hasHighProfitPercentage, exchangeRateProfits, ruleBreachContext, orderUnderAnalysis); }
public void Setup() { this._cache = A.Fake <IUniverseEquityIntraDayCache>(); }