public IMarketRuleResultIntent Apply(Fixture fixture, IMarketStateCollection oldState, IMarketStateCollection newState) { var result = new MarketRuleResultIntent(); if (!fixture.IsMatchOver || oldState == null) { return(result); } var markets = fixture.Markets.ToDictionary(m => m.Id); // get list of markets which are either no longer in snapshot or are in the snapshot and are not resulted // markets which were already priced (activated) should be ignored var marketsNotPresentInTheSnapshot = new List <IMarketState>(); foreach (var mkt in newState.Markets) { IMarketState mkt_state = newState[mkt]; if (!mkt_state.IsResulted && (!markets.ContainsKey(mkt_state.Id) || !markets[mkt_state.Id].IsResulted)) { marketsNotPresentInTheSnapshot.Add(mkt_state); } } foreach (var mkt_state in marketsNotPresentInTheSnapshot) { if (mkt_state.HasBeenActive) { _logger.DebugFormat("market rule={0} => marketId={1} of {2} was priced during the fixture lifetime but has NOT been settled on match over.", Name, mkt_state.Id, fixture); continue; } if (!mkt_state.HasBeenProcessed) { _logger.DebugFormat("market rule={0} => marketId={1} of {2} was never passed to the plugin.", Name, mkt_state.Id, fixture); continue; } var market = fixture.Markets.FirstOrDefault(m => m.Id == mkt_state.Id); if (market == null) { _logger.DebugFormat("market rule={0} => marketId={1} of {2} is marked to be voided", Name, mkt_state.Id, fixture); result.AddMarket(CreateSettledMarket(mkt_state), new MarketRuleAddIntent(MarketRuleAddIntent.OperationType.SETTLE_SELECTIONS)); } else { _logger.DebugFormat("market rule={0} => marketId={1} of {2} that was in the snapshot but wasn't resulted is marked to be voided", Name, market.Id, fixture); Action <Market> action = x => x.Selections.ForEach(s => s.Status = SelectionStatus.Void); MarketRuleEditIntent edit = new MarketRuleEditIntent(action, MarketRuleEditIntent.OperationType.CHANGE_SELECTIONS); result.EditMarket(market, edit); } } return(result); }
public static MarketStateEntity Create(IMarketState source) { return(new MarketStateEntity { Ask = PriceStateEntity.Create(source.Ask), Bid = PriceStateEntity.Create(source.Bid) }); }
/// <summary> /// This execution of the delta rule can only remove markets from the fixture. /// This is different from ApplyDeltaRule_RemovingSelections where selections can /// be removed from markets. /// /// A market is then removed from a fixture if either its tags and all its selections /// haven't changed since last time. /// /// If only a selection has changed, then entire market, with the remaining selections, /// remains untouched by the delta rule. /// </summary> /// <param name="fixture"></param> /// <param name="mkt"></param> /// <param name="state"></param> /// <param name="intent"></param> private void ApplyDeltaRule_RemovingMarkets(Fixture fixture, Market mkt, IMarketState state, MarketRuleResultIntent intent) { if (state.IsEquivalentTo(mkt, true, true)) { intent.MarkAsRemovable(mkt); _logger.DebugFormat("market rule={0} => {1} of {2} marked as removable", Name, mkt, fixture); } }
public bool IsEqualTo(IMarketState marketState) { if (marketState == null) { throw new ArgumentNullException("marketState"); } if (ReferenceEquals(this, marketState)) { return(true); } if (marketState.Id != this.Id) { throw new Exception("Cannot compare two markets with different Ids"); } if (marketState.Name != this.Name) { return(false); } var isStatusEqual = this.IsPending == marketState.IsPending && this.IsResulted == marketState.IsResulted && this.IsSuspended == marketState.IsSuspended && this.IsActive == marketState.IsActive && this.IsDeleted == marketState.IsDeleted && this.IsForcedSuspended == marketState.IsForcedSuspended && this.IsVoided == marketState.IsVoided; if (isStatusEqual) { if (this.HasTag("line") && marketState.HasTag("line")) { isStatusEqual = string.Equals(this.GetTagValue("line"), marketState.GetTagValue("line")); } if (IsRollingMarket) { isStatusEqual &= Line == marketState.Line; } isStatusEqual = isStatusEqual && marketState.Selections.All(s => _selectionStates.ContainsKey(s.Id) && _selectionStates[s.Id].IsEqualTo(s)); } return(isStatusEqual); }
private static Market CreateSuspendedMarket(IMarketState MarketState) { var market = new Market(MarketState.Id) {IsSuspended = true}; if (MarketState.HasTag("line")) { market.AddOrUpdateTagValue("line", MarketState.GetTagValue("line")); } foreach (var stateSelection in MarketState.Selections) market.Selections.Add(new Selection { Id = stateSelection.Id, Status = SelectionStatus.Pending, Tradable = false, Price = 0 }); return market; }
private static Market CreateMarket(IMarketState marketState, bool isSuspended = true) { var market = new Market(marketState.Id) { IsSuspended = isSuspended }; foreach (var seln in marketState.Selections) { market.Selections.Add(new Selection { Id = seln.Id, Status = SelectionStatus.Pending, Tradable = !isSuspended }); } return(market); }
private static QuoteMessage TryCreateMidQuote(string assetPairId, IMarketState marketState, int assetPairAccuracy) { if (marketState.Bid != null && marketState.Ask != null) { return(new QuoteMessage { AssetPair = assetPairId, Price = Math.Round((marketState.Ask.Price + marketState.Bid.Price) / 2, assetPairAccuracy), Timestamp = marketState.Ask.Moment >= marketState.Bid.Moment ? marketState.Ask.Moment : marketState.Bid.Moment }); } return(null); }
private static Market CreateSettledMarket(IMarketState MarketState) { var market = new Market(MarketState.Id); if (MarketState.HasTag("line")) { market.AddOrUpdateTagValue("line", MarketState.GetTagValue("line")); } foreach (var seln in MarketState.Selections) { market.Selections.Add(new Selection { Id = seln.Id, Status = SelectionStatus.Void, Price = 0 }); } return(market); }
/// <summary> /// This execution of the delta rule CAN remove single selections /// from a market if they haven't changes since last time. /// </summary> /// <param name="fixture"></param> /// <param name="mkt"></param> /// <param name="state"></param> /// <param name="intent"></param> private void ApplyDeltaRule_RemovingSelections(Fixture fixture, Market mkt, IMarketState state, MarketRuleResultIntent intent) { List <Selection> seln_changed = new List <Selection>(); foreach (var seln in mkt.Selections) { // if we don't have the selection state, we can't // determine what has changed within the selection, // so we assume that everything has changed if (state.HasSelection(seln.Id) && state[seln.Id].IsEquivalentTo(seln, true)) { continue; } _logger.DebugFormat("market rule={0} => {1} of {2} has changed", Name, seln, mkt); seln_changed.Add(seln); } if (seln_changed.Count == 0) { if (state.IsEquivalentTo(mkt, true, false)) { _logger.DebugFormat("market rule={0} => {1} of {2} marked as removable", Name, mkt, fixture); intent.MarkAsRemovable(mkt); } else { Action <Market> action = x => x.Selections.Clear(); MarketRuleEditIntent edit = new MarketRuleEditIntent(action, MarketRuleEditIntent.OperationType.REMOVE_SELECTIONS); intent.EditMarket(mkt, edit); } } else { if (seln_changed.Count() != mkt.Selections.Count()) { Action <Market> action = x => x.Selections.RemoveAll(y => !seln_changed.Contains(y)); MarketRuleEditIntent edit = new MarketRuleEditIntent(action, MarketRuleEditIntent.OperationType.REMOVE_SELECTIONS); intent.EditMarket(mkt, edit); } } }
private static Market CreateSuspendedMarket(IMarketState MarketState) { var market = new Market(MarketState.Id) { IsSuspended = true }; if (MarketState.HasTag("line")) { market.AddOrUpdateTagValue("line", MarketState.GetTagValue("line")); } foreach (var stateSelection in MarketState.Selections) { market.Selections.Add(new Selection { Id = stateSelection.Id, Status = SelectionStatus.Pending, Tradable = false, Price = 0 }); } return(market); }
public IMarketRuleResultIntent Apply(Fixture fixture, IMarketStateCollection oldState, IMarketStateCollection newState) { MarketRuleResultIntent intent = new MarketRuleResultIntent(); // only apply delta rule on a full snapshot if (fixture.Tags == null || !fixture.Tags.Any() || oldState == null) { return(intent); } foreach (var mkt in fixture.Markets) { if (oldState.HasMarket(mkt.Id)) { IMarketState state = oldState[mkt.Id]; // do not apply the delta rule on markets which have // been put in a forced suspended state if (state.IsForcedSuspended) { continue; } if (Severity == DeltaRuleSeverity.REMOVE_SELECTIONS) { ApplyDeltaRule_RemovingSelections(fixture, mkt, state, intent); } else if (Severity == DeltaRuleSeverity.REMOVE_MARKETS) { ApplyDeltaRule_RemovingMarkets(fixture, mkt, state, intent); } } } return(intent); }
private void BuildDefaultStrategies() { DoNothingStrategy = x => { }; SuspendFixtureStrategy = x => _plugin.Suspend(x.FixtureId); SuspendFixtureIfInPlayStrategy = x => { if (x.FixtureStatus == MatchStatus.InRunning) { _plugin.Suspend(x.FixtureId); } }; SuspendAllMarketsStrategy = x => { IEnumerable <IMarketState> includedMarketStates; var fixture = GetFixtureWithSuspendedMarkets(x, out includedMarketStates); _logger.DebugFormat("Sending suspension command through the plugin for fixtureId={0}", x.FixtureId); _plugin.ProcessStreamUpdate(fixture); _logger.InfoFormat("Marking markets for fixtureId={0} as suspended", x.FixtureId); ((IUpdatableMarketStateCollection)x).OnMarketsForcedSuspension(includedMarketStates); }; SuspendAllMarketsAndSetMatchStatusDeleted = x => { IEnumerable <IMarketState> includedMarketStates; var fixture = GetFixtureWithSuspendedMarkets(x, out includedMarketStates); fixture.MatchStatus = ((int)MatchStatus.Deleted).ToString(); _logger.DebugFormat("Sending suspension command through the plugin for fixtureId={0} and setting its MatchStatus as deleted", x.FixtureId); _plugin.ProcessStreamUpdate(fixture); _logger.InfoFormat("Marking markets for fixtureId={0} as suspended", x.FixtureId); ((IUpdatableMarketStateCollection)x).OnMarketsForcedSuspension(includedMarketStates); }; SuspendFixtureAndSetMatchStatusDeleted = x => { var fixture = new Fixture { Id = x.FixtureId, MatchStatus = ((int)MatchStatus.Deleted).ToString(), Sequence = x.FixtureSequence }; _logger.DebugFormat("Sending suspension command through the plugin for fixtureId={0} and setting its MatchStatus as deleted", x.FixtureId); _plugin.ProcessStreamUpdate(fixture); _logger.InfoFormat("Marking markets for fixtureId={0} as suspended", x.FixtureId); }; SuspendInPlayMarketsStrategy = x => { List <IMarketState> includedMarketStates = new List <IMarketState>(); var fixture = new Fixture { Id = x.FixtureId, MatchStatus = ((int)x.FixtureStatus).ToString(), Sequence = x.FixtureSequence }; foreach (var mkt_id in x.Markets) { // we take a conservative approach here. // If, for any reason, the traded_in_play // is not present, we assume it is. Better // to suspend more markets, than less IMarketState state = x[mkt_id]; if (state.HasTag("traded_in_play") && string.Equals(state.GetTagValue("traded_in_play"), "false", StringComparison.OrdinalIgnoreCase)) { _logger.DebugFormat("marketId={0} of fixtureId={1} will not be suspended as it is not traded in play", mkt_id, fixture.Id); continue; } if (!state.HasBeenActive) { _logger.DebugFormat("marketId={0} of fixtureId={1} will not be suspended as it has not been active before", mkt_id, fixture.Id); continue; } includedMarketStates.Add(state); fixture.Markets.Add(CreateMarket(x[mkt_id])); } _logger.DebugFormat("Sending suspension command through the plugin for in-play markets of fixtureId={0}", x.FixtureId); _plugin.ProcessStreamUpdate(fixture); _logger.InfoFormat("Marking markets for fixtureId={0} as suspended", x.FixtureId); ((IUpdatableMarketStateCollection)x).OnMarketsForcedSuspension(includedMarketStates); }; }
private static Market CreateMarket(IMarketState marketState,bool isSuspended = true) { var market = new Market(marketState.Id) { IsSuspended = isSuspended }; foreach (var seln in marketState.Selections) market.Selections.Add(new Selection { Id = seln.Id, Status = SelectionStatus.Pending, Tradable = !isSuspended }); return market; }
private static Market CreateSettledMarket(IMarketState MarketState) { var market = new Market (MarketState.Id); if (MarketState.HasTag("line")) { market.AddOrUpdateTagValue("line", MarketState.GetTagValue("line")); } foreach (var seln in MarketState.Selections) market.Selections.Add(new Selection { Id = seln.Id, Status = SelectionStatus.Void, Price = 0 }); return market; }
/// <summary> /// This execution of the delta rule CAN remove single selections /// from a market if they haven't changes since last time. /// </summary> /// <param name="fixture"></param> /// <param name="mkt"></param> /// <param name="state"></param> /// <param name="intent"></param> private void ApplyDeltaRule_RemovingSelections(Fixture fixture, Market mkt, IMarketState state, MarketRuleResultIntent intent) { List<Selection> seln_changed = new List<Selection>(); foreach (var seln in mkt.Selections) { // if we don't have the selection state, we can't // determine what has changed within the selection, // so we assume that everything has changed if (state.HasSelection(seln.Id) && state[seln.Id].IsEquivalentTo(seln, true)) continue; _logger.DebugFormat("market rule={0} => {1} of {2} has changed", Name, seln, mkt); seln_changed.Add(seln); } if (seln_changed.Count == 0) { if (state.IsEquivalentTo(mkt, true, false)) { _logger.DebugFormat("market rule={0} => {1} of {2} marked as removable", Name, mkt, fixture); intent.MarkAsRemovable(mkt); } else { Action<Market> action = x => x.Selections.Clear(); MarketRuleEditIntent edit = new MarketRuleEditIntent(action, MarketRuleEditIntent.OperationType.REMOVE_SELECTIONS); intent.EditMarket(mkt, edit); } } else { if (seln_changed.Count() != mkt.Selections.Count()) { Action<Market> action = x => x.Selections.RemoveAll(y => !seln_changed.Contains(y)); MarketRuleEditIntent edit = new MarketRuleEditIntent(action, MarketRuleEditIntent.OperationType.REMOVE_SELECTIONS); intent.EditMarket(mkt, edit); } } }
public bool IsEqualTo(IMarketState marketState) { if (marketState == null) throw new ArgumentNullException("marketState"); if (ReferenceEquals(this, marketState)) return true; if (marketState.Id != this.Id) throw new Exception("Cannot compare two markets with different Ids"); if (marketState.Name != this.Name) return false; var isStatusEqual = this.IsPending == marketState.IsPending && this.IsResulted == marketState.IsResulted && this.IsSuspended == marketState.IsSuspended && this.IsActive == marketState.IsActive && this.IsDeleted == marketState.IsDeleted && this.IsForcedSuspended == marketState.IsForcedSuspended && this.IsVoided == marketState.IsVoided; if (isStatusEqual) { if (this.HasTag("line") && marketState.HasTag("line")) { isStatusEqual = string.Equals(this.GetTagValue("line"), marketState.GetTagValue("line")); } if (IsRollingMarket) { isStatusEqual &= Line == marketState.Line; } isStatusEqual = isStatusEqual && marketState.Selections.All(s => _selectionStates.ContainsKey(s.Id) && _selectionStates[s.Id].IsEqualTo(s)); } return isStatusEqual; }