Open firatbaran opened 8 months ago
Thank you for bringing this to my attention. I have quickly put together a fix. Update your package to v1.2.5 and let me know if there are any further issues.
Hi again Brandon.
Virtual Data sounds great. There's no problem. But within a few minutes, I get the following error. I tried many times but the same error always appears.
internal void AddOrUpdateLevelByDepth(int depth, PriceSize level) { if(depth >= 0 && depth < _byRank.Count) { var price = _byRank.Keys[depth]; _byPrice[price] = level; _byRank[price] = level; } else { _byRank.Add(level.Price, level); _byPrice.Add(level.Price, level); } }
(at PriceLadder.cs)
An item with the same key has already been added. Key: 1,01 (Parameter 'key')
I can't seem to reproduce the error. Under what circumstances did this exception occur? Could you provide a reproducible example so I can investigate? I couldn't replicate your StreamingMarketFilter
as this would result in subscribing to too many markets, which causes an exception.
Here is the code I ran and did not get any issues (note, I have streamlined the subscription for the latest version, and I am hoping to do something similar for some of the other operations as well):
var client = new BetfairClient(apiKey);
var session = await client.Login.CertificateLogin(username, password, certPath);
await client.Streaming
.CreateStream(session.SessionToken)
.WithAutoReconnection(3_000, 120_000)
.ForEventTypeIds("7")
.ForCountryCodes("GB", "IE")
.ForMarketTypes("WIN")
.ReturningMarketDataFor(3, MarketDataFilterEnum.EX_BEST_OFFERS_DISP)
.OnMarketChange(snap => Console.WriteLine(snap.Timestamp))
.OnException(ex => Console.WriteLine(ex))
.Subscribe();
EventType: Football, Basketball
----------------------------------
Market Type: "MATCH_ODDS",
"HALF_TIME",
"HALF_TIME_FULL_TIME",
"OVER_UNDER_05",
"OVER_UNDER_15",
"OVER_UNDER_25",
"OVER_UNDER_35",
"OVER_UNDER_45",
"OVER_UNDER_55",
"OVER_UNDER_65",
"FIRST_HALF_GOALS_15",
"FIRST_HALF_GOALS_25",
"DOUBLE_CHANCE",
"BOTH_TEAMS_TO_SCORE",
"ASIAN_HANDICAP",
"ODD_OR_EVEN",
"OVER_UNDER_85_CORNR",
"OVER_UNDER_105_CORNR",
"OVER_UNDER_135_CORNR",
"CORNER_MATCH_BET",
"PENALTY_TAKEN",
"SENDING_OFF",
"TEAM_A_WIN_TO_NIL",
"TEAM_B_WIN_TO_NIL",
"CLEAN_SHEET",
"WIN_BOTH_HALVES",
--------------------------------
List<string> eventLeagueIDs = new(){
eventLeagueIDs.Add("194215"); // Football
eventLeagueIDs.Add("10932509");// Football
eventLeagueIDs.Add("59"); // Football
eventLeagueIDs.Add("117"); // Football
eventLeagueIDs.Add("81"); // Football
eventLeagueIDs.Add("55"); // Football
eventLeagueIDs.Add("9404054"); // Football
eventLeagueIDs.Add("89979"); // Football
eventLeagueIDs.Add("99"); // Football
eventLeagueIDs.Add("129"); // Football
eventLeagueIDs.Add("10547864"); // NBA
eventLeagueIDs.Add("10534437"); // EuroLeague
}
marketFilter.CompetitionIds = eventLeagueIDs;
----------------------------------
marketFilter.MarketStartTime = next 5 days
----------------------------------
If possible, you can try above filters, first 200 MarketID's (30 basketball, 170 football) This is the filter that gives me error
Thank you, I have isolated the issue, which was a wider problem with the depth-based ladders. I hope that the issue is now fixed, I will push a pre-release version of the package.
Here is the code I ran with the latest fix, and the exception was not thrown:
var marketTypes = new List<string>
{
"MATCH_ODDS",
"HALF_TIME",
"HALF_TIME_FULL_TIME",
"OVER_UNDER_05",
"OVER_UNDER_15",
"OVER_UNDER_25",
"OVER_UNDER_35",
"OVER_UNDER_45",
"OVER_UNDER_55",
"OVER_UNDER_65",
"FIRST_HALF_GOALS_15",
"FIRST_HALF_GOALS_25",
"DOUBLE_CHANCE",
"BOTH_TEAMS_TO_SCORE",
"ASIAN_HANDICAP",
"ODD_OR_EVEN",
"OVER_UNDER_85_CORNR",
"OVER_UNDER_105_CORNR",
"OVER_UNDER_135_CORNR",
"CORNER_MATCH_BET",
"PENALTY_TAKEN",
"SENDING_OFF",
"TEAM_A_WIN_TO_NIL",
"TEAM_B_WIN_TO_NIL",
"CLEAN_SHEET",
"WIN_BOTH_HALVES",
};
var competitionIds = new List<string>
{
"194215", // Football
"10932509", // Football
"59", // Football
"117", // Football
"81", // Football
"55", // Football
"9404054", // Football
"89979", // Football
"99", // Football
"129", // Football
"10547864", // NBA
"10534437", // EuroLeague
};
var markets = await client.Betting.ListMarketCatalogue(
new() { CompetitionIds = competitionIds, MarketTypeCodes = marketTypes},
new List<MarketProjectionEnum> { MarketProjectionEnum.EVENT },
MarketSortEnum.FIRST_TO_START,
maxResults: 200
);
await client.Streaming
.CreateStream(session.SessionToken)
.WithAutoReconnection(3_000, 120_000)
.ForMarketIds(markets.Select(m => m.MarketId).ToArray())
.ReturningMarketDataFor(3, MarketDataFilterEnum.EX_BEST_OFFERS_DISP)
.OnMarketChange(snap => Console.WriteLine(snap.Timestamp))
.OnException(ex => Console.WriteLine(ex))
.Subscribe();
Thank you. I'll try when I get the new release. :)
Should be v1.2.6 on NuGet
You're the rock! Looks great, I haven't gotten any errors.
Virtual Back Equal Virtual Lay
Hello Brandon. At the same price, both back and lay price are equal. Can you check it?
(Also, in this scenario (BestOffer Virtual), can be Virtual Back/Lay price count be more than 3 ?)
Same snapshot, another runner:
This occurs only MarketDataFilterEnum.EX_BEST_OFFERS_DISP
markets.
Edit: Sorry, occurs even MarketDataFilterEnum.EX_BEST_OFFERS
!
Cancel this comment: There is no problem at MarketDataFilterEnum.EX_BEST_OFFERS
Last; RunnerSnapshop
need to be Handicap
property at:
-ProcessRunnersImage
-ProcessRunnersDelta
I have just pushed a commit to try and address this, however the issue with there being more prices than ladder levels specified persists. I have added a test case for this which is failing:
[Fact]
public void DepthBasedPriceLadder_UpdatesPriceAndSize_WhenLevelExists()
{
// Arrange
var ladder = new PriceLadder(SideEnum.BACK)
{
[0] = new(3.5, 100),
[1] = new(2.5, 100),
[2] = new(1.5, 100),
};
// Act
ladder[0] = new(2.5, 100);
ladder[1] = new(2.0, 150);
// Assert
ladder.Depth.Should().Be(3);
ladder[0]?.Size.Should().Be(100);
ladder[0]?.Price.Should().Be(2.5);
ladder[1]?.Size.Should().Be(150);
ladder[1]?.Price.Should().Be(2.0);
ladder[2]?.Size.Should().Be(100);
ladder[2]?.Price.Should().Be(1.5);
}
This is due to stale prices not being removed from the SortedList<double, PriceSize>
in the PriceLadder
class. The offending code is here:
public PriceSize? this[int index]
{
get
{
return index >= 0 && index < _byRank.Values.Count
? _byRank.Values.ElementAt(index)
: default;
}
internal set
{
if (value != null && (value.Price == 0 || value.Size == 0) && (index < _byRank.Values.Count))
{
var key = _byRank.Keys.ElementAt(index);
_byRank.RemoveAt(index);
_byPrice.Remove(key);
}
else if(value != null && _byRank.ContainsKey(value.Price))
{
var key = _byRank.Keys.ElementAt(index);
_byRank[key] = value;
_byPrice[key] = value;
}
else if (value is { Price: > 0, Size: > 0 })
{
_byRank[value.Price] = value;
_byPrice[value.Price] = value;
}
}
}
It is proving quite tricky to iron out, but I will push a fix as soon as I can.
You can arrange the Ladder from the beginning and instead of removing section, you can fill the Ladder sections that do not have data as 0.0.
Hi Brandon.
My code is:
`var streamConfiguration = new StreamConfiguration() { SessionToken = betfairSessionToken, RecoveryThresholdMs = 3_000, MaxRecoveryWaitMs = 120_000 };
StreamingMarketDataFilter marketDataFilter = new() { LadderLevels = 3, Fields = new List() { MarketPriceFilterEnum.EX_BEST_OFFERS_DISP
}
};
StreamingMarketFilter marketFilter = new() { MarketIds = new List(),
BettingTypes = new List()
{
MarketBettingTypeEnum.ODDS,
MarketBettingTypeEnum.ASIAN_HANDICAP_DOUBLE_LINE,
MarketBettingTypeEnum.ASIAN_HANDICAP_SINGLE_LINE,
MarketBettingTypeEnum.LINE
}
};`
When I change field to "MarketPriceFilterEnum.EX_ALL_OFFERS", I got the data without VirtualBets.