public IMarketRuleResultIntent Apply(Fixture fixture, IMarketStateCollection oldState,
            IMarketStateCollection newState)
        {            

            var result = new MarketRuleResultIntent();

            if (oldState == null)
                return result;
            
            var deletedMarkets =
                newState.Markets.Select(marketId => newState[marketId])
                    .Where(marketState => marketState.IsDeleted && oldState.HasMarket(marketState.Id) && !oldState[marketState.Id].IsDeleted)
                    .ToList();

            var newDeletedMarketState = deletedMarkets.Select(CreateSuspendedMarket).ToList();

            if (deletedMarkets.Any())
            {
                newDeletedMarketState.ForEach(m =>
                {
                    _logger.DebugFormat("market rule={0} => {1} of fixtureId={2} was deleted from UDAPI - it will be suspended", Name, m, fixture.Id);
                    result.AddMarket(m, new MarketRuleAddIntent(MarketRuleAddIntent.OperationType.CHANGE_SELECTIONS));
                });
            }
            
            return result;

        }
Ejemplo n.º 2
0
        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;
        }
        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;
        }
        /// <summary>
        /// 
        ///     Remove markets from snapshot/update when: 
        ///     current market state is inactive AND the previous state was inactive too (with no change in status or name)
        /// 
        ///     NB: If there is a change in market's name or status then will not be removed
        /// 
        /// </summary>
        public IMarketRuleResultIntent Apply(Fixture fixture, IMarketStateCollection oldState, IMarketStateCollection newState)
        {
            var result = new MarketRuleResultIntent();

            var inactiveMarkets = fixture.Markets.Where(
                m => (oldState != null && oldState.HasMarket(m.Id) && oldState[m.Id].IsEqualTo(newState[m.Id]))
                        && (!m.IsActive && !oldState[m.Id].IsActive));

            foreach (var market in inactiveMarkets.ToList())
            {
                result.MarkAsRemovable(market);
                _Logger.DebugFormat("market rule={0} => {1} of fixtureId={2} is marked as removable", Name, market, fixture.Id);
            }

            return result;
        }
        public void GivenTheMarketRulesReturnTheFollowingIntents(Table table)
        {
            MarketRulesManager manager = ScenarioContext.Current["MARKETRULEMANAGER"] as MarketRulesManager;
            manager.Should().NotBeNull();

            Fixture fixture = ScenarioContext.Current["FIXTURE"] as Fixture;
            fixture.Should().NotBeNull();

            foreach (var row in table.Rows)
            {
                var name = row["Rule"];
                Mock<IMarketRule> rule = ScenarioContext.Current["RULE-" + name] as Mock<IMarketRule>;
                rule.Should().NotBeNull();

                var mkt_name = row["Market"];
                var result = row["Result"];
                var mkt = fixture.Markets.FirstOrDefault( x => x.Id == mkt_name);
                mkt.Should().NotBeNull();


                if (!ScenarioContext.Current.ContainsKey("INTENT-RULE-" + name))
                {
                    MarketRuleResultIntent rule_intent = new MarketRuleResultIntent();
                    ScenarioContext.Current.Add("INTENT-RULE-" + name, rule_intent);
                    rule.Setup(x => x.Apply(It.IsAny<Fixture>(), It.IsAny<IMarketStateCollection>(), It.IsAny<IMarketStateCollection>())).Returns(rule_intent);
                }

                MarketRuleResultIntent intent = ScenarioContext.Current["INTENT-RULE-" + name] as MarketRuleResultIntent;
                intent.Should().NotBeNull();

                switch (result)
                {
                    case "E":
                        Action<Market> action = x => x.AddOrUpdateTagValue("name",  x.Name + " - E: " + name);
                        MarketRuleEditIntent edit_intent = new MarketRuleEditIntent(action, MarketRuleEditIntent.OperationType.CHANGE_DATA);
                        intent.EditMarket(mkt, edit_intent);
                        break;
                    case "!E":
                        intent.MarkAsUnEditable(mkt);
                        break;
                    case "R":
                        intent.MarkAsRemovable(mkt);
                        break;
                    case "!R":
                        intent.MarkAsUnRemovable(mkt);
                        break;
                    case "CS":
                        Action<Market> edit_seln_action = x => x.Selections.ForEach(y => y.Name = y.Name + name);
                        MarketRuleEditIntent change_seln_edit_intent = new MarketRuleEditIntent(edit_seln_action, MarketRuleEditIntent.OperationType.CHANGE_SELECTIONS);
                        intent.EditMarket(mkt, change_seln_edit_intent);
                        break;
                    case "CD":
                        Action<Market> change_data_action = x => x.AddOrUpdateTagValue("name", x.Name + name);
                        MarketRuleEditIntent change_data_edit_intent = new MarketRuleEditIntent(change_data_action, MarketRuleEditIntent.OperationType.CHANGE_DATA);
                        intent.EditMarket(mkt, change_data_edit_intent);
                        break;
                    case "AS":
                        Action<Market> add_seln_action = x => x.Selections.Add(new Selection { Name = mkt.Name + (x.Selections.Count() + 1) + name, Id = mkt.Name + x.Selections.Count() + name });
                        MarketRuleEditIntent add_seln_intent = new MarketRuleEditIntent(add_seln_action, MarketRuleEditIntent.OperationType.ADD_SELECTIONS);
                        intent.EditMarket(mkt, add_seln_intent);
                        break;
                    case "RS":
                        Action<Market> remove_seln_action = x => x.Selections.Clear();
                        MarketRuleEditIntent remove_seln_intent = new MarketRuleEditIntent(remove_seln_action, MarketRuleEditIntent.OperationType.REMOVE_SELECTIONS);
                        intent.EditMarket(mkt, remove_seln_intent);
                        break;
                    default:
                        throw new Exception("Unknow status");

                }
                
            }
        }
        public IMarketRuleResultIntent Apply(Fixture fixture, IMarketStateCollection oldState, IMarketStateCollection newState)
        {
            var result = new MarketRuleResultIntent();

            if (_includedSports.Contains(newState.Sport.ToLower()))
            {
                
                foreach (var mkt in fixture.Markets)
                {
                    string type = string.Format("{0}.{1}", newState.Sport, mkt.Type).ToLower();

                    if (_excludedMarketTypes.Contains(type))
                    {
                        _Logger.DebugFormat("market rule={0} => {1} of {2} is excluded from rule due its type={3}",
                            Name, mkt, fixture, mkt.Type);

                        continue;
                    }

                    var oldMarketState = oldState != null ? oldState[mkt.Id] : null;
                    var newMarketState = newState[mkt.Id];

                    if (oldMarketState == null)
                    {
                        //must be a snapshot then
                        if (newMarketState.IsActive)
                        {
                            //create market
                            _Logger.DebugFormat("market rule={0} => {1} of {2} is created", Name, mkt, fixture);
                            result.MarkAsUnRemovable(mkt);
                        }
                        else
                        {
                            //dont create market
                            _Logger.DebugFormat("market rule={0} => {1} of {2} is not created", Name, mkt, fixture);
                            result.MarkAsRemovable(mkt);
                        }
                    }
                    else
                    {
                        if (oldMarketState.HasBeenActive) continue;
                        if (newMarketState.IsActive)
                        {
                            //create
                            Action<Market> editMarketAction = (m =>
                            {
                                if (newMarketState.TagsCount == 0)
                                    return;

                                foreach (var tagKey in newMarketState.TagKeys)
                                {
                                    m.AddOrUpdateTagValue(tagKey, newMarketState.GetTagValue(tagKey));
                                }

                                foreach (var sel in m.Selections)
                                {
                                    var selState = newMarketState[sel.Id];
                                    foreach (var tagKey in selState.TagKeys)
                                    {
                                        sel.AddOrUpdateTagValue(tagKey, selState.GetTagValue(tagKey));
                                    }
                                }
                            });

                            var mri = new MarketRuleEditIntent(editMarketAction, MarketRuleEditIntent.OperationType.CHANGE_DATA);
                            _Logger.DebugFormat("market rule={0} => {1} of {2} is created", Name, mkt, fixture);
                            result.EditMarket(mkt, mri);
                        }
                        else
                        {
                            //dont create market
                            _Logger.DebugFormat("market rule={0} => {1} of {2} is not created", Name, mkt, fixture);
                            result.MarkAsRemovable(mkt);
                        }
                    }
                }                
            }

            return result;
        }
        public void PostRuleProcessingTest()
        {

            // This test sets up a dummy market rule that removes
            // all the markets whose Id start with "REMOVE".
            // The test, after calling ApplyRules() on the MarketRuleManager
            // checks if the property "HasBeenProcessed" is set to true
            // for all the markets whose Id don't start with REMOVE.
            //
            // The HasBeenProcessed property is set to true only
            // when a market has been passed at least once to the
            // plugin, or in other words, the outcome of the 
            // MarketRuleManager hasn't remove it from the Fixture object.
            // This property is set on IUpdatableMarketState.ApplyPostRulesProcessing()

            Mock<IMarketRule> aRule = new Mock<IMarketRule>();
            aRule.Setup(x => x.Apply(It.IsAny<Fixture>(), It.IsAny<IMarketStateCollection>(), It.IsAny<IMarketStateCollection>()))
                .Returns((Fixture f, IMarketStateCollection nS, IMarketStateCollection oS) => 
                { 
                    MarketRuleResultIntent intent = new MarketRuleResultIntent();
                    foreach(var mkt in f.Markets)
                    {
                        if(mkt.Id.StartsWith("REMOVE"))
                            intent.MarkAsRemovable(mkt);
                    }

                    return intent;
                }
            );

            var settings = new Mock<ISettings>();
            var plugin = new Mock<IAdapterPlugin>();
            var stateprovider = new StateManager(settings.Object, plugin.Object);

            List<IMarketRule> rules = new List<IMarketRule> { aRule.Object };

            Fixture fixture = new Fixture { Id = "ABC", MatchStatus = "30"};

            Market testMkt = new Market { Id = "1"};
            fixture.Markets.Add(testMkt);

            testMkt = new Market { Id = "REMOVE-1" };
            fixture.Markets.Add(testMkt);

            testMkt = new Market { Id = "2" };
            fixture.Markets.Add(testMkt);

            testMkt = new Market { Id = "REMOVE-2" };
            fixture.Markets.Add(testMkt);

            MarketRulesManager manager = new MarketRulesManager(fixture.Id, stateprovider, rules);

            manager.ApplyRules(fixture);

            manager.CurrentState["1"].Should().NotBeNull();
            manager.CurrentState["1"].HasBeenProcessed.Should().BeTrue();

            manager.CurrentState["2"].Should().NotBeNull();
            manager.CurrentState["2"].HasBeenProcessed.Should().BeTrue();

            manager.CurrentState["REMOVE-1"].Should().NotBeNull();
            manager.CurrentState["REMOVE-1"].HasBeenProcessed.Should().BeFalse();

            manager.CurrentState["REMOVE-2"].Should().NotBeNull();
            manager.CurrentState["REMOVE-2"].HasBeenProcessed.Should().BeFalse();

            manager.CommitChanges();


            manager.CurrentState["1"].Should().NotBeNull();
            manager.CurrentState["1"].HasBeenProcessed.Should().BeTrue();

            manager.CurrentState["2"].Should().NotBeNull();
            manager.CurrentState["2"].HasBeenProcessed.Should().BeTrue();

            manager.CurrentState["REMOVE-1"].Should().NotBeNull();
            manager.CurrentState["REMOVE-1"].HasBeenProcessed.Should().BeFalse();

            manager.CurrentState["REMOVE-2"].Should().NotBeNull();
            manager.CurrentState["REMOVE-2"].HasBeenProcessed.Should().BeFalse();
        }
Ejemplo n.º 8
0
        /// <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);
                }
            }
        }
Ejemplo n.º 9
0
 /// <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);
     }
 }