Exception error with C#
Hi, love the sample, but I'm stuck when I run it in C#.
Print("*** Logout ***");
BFGlobal.LogoutReq oLogoutReq;
oLogoutReq = new BFGlobal.LogoutReq();
BFGlobal.LogoutResp oLogoutResp;
oLogoutResp = new BFGlobal.LogoutResp();
oLogoutReq.header = oHeaderGL;
oLogoutResp = BetfairGL.logout(oLogoutReq);//Call the API
When calling the API I get
Nullreference exception
Object reference not set to an instance of an object.
The header has a session token in it, so I don't know what the problem is.
Oops, my bad, ignore this message, I forgot to put in:
BetfairGL = new BetFair.BFGlobal.BFGlobalService();
For anyone else who might be using C#, I found the following code handy during this tutorial (because you can't use ReDim in C#):
int?[] tempReDim = new int?[1];
//For horse racing
tempReDim[0] = 7;
string[] tempReDim2 = new string[2];
tempReDim2[0] = "GBR";
tempReDim2[1] = "ZAF";
oMarketsReq.eventTypeIds = tempReDim;
oMarketsReq.countries = tempReDim2;
As a final point to anyone programming this in C#:
private void bPrices_Click(object sender, EventArgs e)
{
Print("*** Prices ***");
BetFairUK = new BetFair.BFUK.BFExchangeService();
BFUK.GetMarketPricesReq MpricesReq2;
MpricesReq2 = new BFUK.GetMarketPricesReq();
MpricesReq2 = MpricesReq();
ShowMprices(BetFairUK.getMarketPrices(MpricesReq2) );
}
Also see http://forum.bdp.betfair.com/showthread.php?t=173
Using VB2008 to acccess the Betfair API: A tutorial
Collapse
This topic is closed.
X
X
-
I'm such a bonehead. I left .Value off the end.
I need a rest. I've been working on this project for two months.
Leave a comment:
-
JayBee,
Try:
Dim layOdds as Decimal
layOdds = SelectedGrid.Item("Back", e.RowIndex).Value
Leave a comment:
-
Casting types in datagridview cells
I would like to be able to pass the value of a datagridview cell to your PlaceBet function for speed rather than fiddling with nudges and text boxes.
However, as Betfair require odds to be decimals, I am finding it impossible to pass the value in a cell to the PlaceBet function.
eg. layOdds = SelectedGrid.Item("Back", e.RowIndex)
Attempts I make at type casting gives me errors.
Any ideas?
Leave a comment:
-
Fixed
Also just to let you know I have fixed the session issue.
It was purely because I was calling the Logout function when I shouldn't have been!
Thanks
Leave a comment:
-
Backend Logic
Okay cheers for your help I will debug the session values some more as it must just be a bug somewhere.
Regarding the "ideal solution" I know there is never going to be a one size fits all solution and the API is so big that you can do so many actions in any order and I am not expecting you to provide me with one.
What would be nice though (and this might be pie in the sky thinking as well) but obviously betfairs own website has a certain logical order to the actions that are needed to be carried out when you say place a bet or cancel a bet and it would be nice to find out the correct steps for each somehow.
For example my bot placed a bet earlier today which was unmatched however as it got nearer to the race my logic decreed that it would cancel the bet and then reset the price so that it had more chance of being taken.
On cancelling the bet the size matched was > 0 which meant that only a partial cancellation was carried out. This is a similar issue to partial matches and it would be nice to know how to handle these types of situations as with partial matches both the Cancelled part of the bet and the Matched part have the same BetID (same with settled and cancelled).
I have found that using a GetBetStatus function and passing in the betID will return a status of Settled once the race is over but I have not managed to find the status returned with a partial cancellation before the race ( although I expect it was C as my database record had that status code stored)
I guess I am not really asking for help with the front end logic as your API tutorial does a good job of explaining all those parts but I am wondering if you know of any guides or documentation that have been written or publicly available that specifically look at the backend database structure that would be ideal for a betfair application.
Something that would detail the entity relationships between bet objects e.g ONE BET can have MANY BET PARTS and so on.
Also on another point a lot of UK races were abandoned today (like the last couple of weeks) due to frozen ground and I had a lot of voided bets.
As I am storing the selectionID and marketID in my DB on the earliest possible opportunity so that I don't have to keep unpacking markets it means I have lots of pending bets that are trying to be placed on cancelled markets. I know that once a market has been cancelled the marketID will be 0 but I don't want to have to look up selections and markets on each job as 99% of the time it will just be pointless requests that mean I keep reaching the API throttle limit.
I am thinking about having a new job just to check the market is still active that would be run once an hour or so but I was wondering if there was another quicker way to check whether a market was still available which I could use by passing in my existing market ID.
Thanks for all your help
Leave a comment:
-
Your Trading App
MonkeyMagix,
Looks like I’m the only one who will talk to you, but I’m still not exactly sure what you are seeking.
Bet placement is an important part of your strategy. The API provides the tools to place, modify, monitor and delete bets. It’s up to you to decide how to go about this. There is no “standard”, or “ideal” procedure. It’s your call!
Your thoughts on session token persistence seem to be a bit wide of the mark. I (and presumably other users) have no problem with this. If I don’t log out, my session token usually remains current for a day or so. It looks like you’ve got a classic bug.
Leave a comment:
-
Market Stabs, Sessions and Security
Hi Mumbles
Sorry for posting c# code here but I have tried starting a couple of C# threads but haven't received a single reply e.g
http://forum.bdp.betfair.com/showthread.php?t=1056
http://forum.bdp.betfair.com/showthread.php?t=1038
You are correct in that I am having "stabs" at the market and maybe I don't need to when placing the LAY part of a trade bet. The reason I cancel after the WIN part is so that I set the LAY bets boundaries up correctly as there is no point in trading if both parts don't cover each over and I have been stung a couple of times because of partial matches on the WIN bet which meant the corresponding LAY bet boundaries (e.g size) was set incorrectly.
I am trying to make my front end console app into a "dumb" front end as all the business logic that handles selections, bet types and prices is done in the back end. I just want the front end to literally pick up a list of bets to either check the status of or place and then do the job correctly updating the DB once the action is complete. In this regards it would be very nice to come up with an ideal logical flow for placing, cancelling and managing bets and it does seem that Betfair is lacking slightly in this regards which is why your tutorial is really my only port of call.
Regarding the Session issue I am using the following test harness.
And I get this debugCode:public void TestSession() { // this will load up the session value from the text file BetfairBot betfair = new BetfairBot(); // using your standard keep alive function (see code I attached last time) betfair.KeepAlive(); try { double balance = betfair.GetAccountBalance(); Program.ShowMsg("Got Account Balance using last session value: " + balance.ToString()); } catch (Exception e) { Program.ShowMsg("Failed to get Account Balance with last session value - login now"); string betfairPassword = GetPassword("myencrypedpassword"); string betfairLogon = DecodeFrom64("myencrypedlogin"); Program.ShowMsg("Login for account: " + betfairLogon + " - password: " + betfairPassword); // login if (betfair.Login(betfairLogon, betfairPassword)) { Program.ShowMsg("Logged In"); } else { Program.ShowMsg("Not Logged In"); return; } } finally { Program.ShowMsg("Save Session and Logout"); betfair.SaveSession(); betfair.Logout(); } Program.ShowMsg("Completed Test"); } public double GetAccountBalance() { double AccountBalance = 0; BFUK.GetAccountFundsReq AccountReq = new BFUK.GetAccountFundsReq(); BFUK.GetAccountFundsResp AccountResp = new BFUK.GetAccountFundsResp(); // check header is still valid AccountReq.header = oHeaderUK(); AccountResp = BetfairUK.getAccountFunds(AccountReq); // check for valid response (fails without a session) CheckHeader(AccountResp.header); // this doesnt run with no session if (AccountResp.errorCode == BFUK.GetAccountFundsErrorEnum.OK) { AccountBalance = AccountResp.availBalance; Program.ShowMsg("Successfully got available balance: " + AccountBalance.ToString()); } return AccountBalance; }
Start BetfairBot
Start Betfair Bot Job: TEST
Test Session
Set session value to U2q6Hx/Bvz+U8is3lu9WJL/rREdrUEDWbyuH6rrZSos= saved from last visit
KeepAlive
HeaderCode = NO_SESSION
Got Account Balance using last session value: 0
Save Session and Logout
Error saving session value to text file: Object reference not set to an instance of an object.
Logout
HeaderCode = NO_SESSION
ErrorCode = API_ERROR
Completed Test
Test Session Complete
End BetfairBot
Note that the Catch in the Try/Catch doesn't actually get run as no error is raised in the GetAccountBalance method. However as there is no session the amount returned is 0 and you can see the HeaderCode = NO_SESSION error message that is returned by the API when I try to check the AccountReq.header value.
Also notice the Object reference not set error which happens when I try to save the session value back to the text file.
I guess I am going wrong somewhere but cannot spot where at the moment.
Just thinking aloud here >> It wouldn't be some kind of internal security Betfair has implemented to prevent XSS hacks and session hijacking would it? Maybe they can spot that I am using a console application and not a browser and preventing session re-use for those reasons? If you can literally take a string and then use it to re-open a previous session then there could be serious issues regarding security as if I could obtain someone else's session value somehow I could access their betfair account without their knowledge.
Thanks for your help.
Leave a comment:
-
Limiting Data Request
Thank you very much Mumbles0
If I understand correctly, what you do is select the varialbe MarketNo market position within the collection, right?
And if you want to refresh 6 markets every second?
Do not give me the solution I will try it and you wonder if the solution is correct!
Another question, how I can remove from the collection a market that has been closed?
Let me explain:
When the application is monitoring the market is removed from the collection (mymarkets) if the last matched price of any horse has reached 1.01, but sometimes the last matched price does not reach the 1.01 and remains at 1.05 or 1.03 or 1.10 etc ...
I use this code, when the market is closed, but the .marketid is equals to zero and I do not know how to identify the market to close
Code:[COLOR="Gray"]Private Sub BetfairUK_getMarketTradedVolumeCompressedCompleted(ByVal sender As Object, ByVal e As BFUK.getMarketTradedVolumeCompressedCompletedEventArgs) Handles BetFairUk.getMarketTradedVolumeCompressedCompleted Try If Not e.Cancelled Then With e.Result CheckHeader(.header) If .errorCode = BFUK.GetMarketTradedVolumeCompressedErrorEnum.OK Then Dim oTradedVolume As New UnpackMarketTradedVolumeCompressed(.tradedVolume) 'Unpack the traded volumes Dim Key As String = .marketId 'The key for this market If MyMarkets.Contains(Key) Then 'The MarketForm is open Dim Market As MarketForm = MyMarkets(Key) 'A reference to the form for this market Market.TradedVolumeReceived(oTradedVolume) 'Process the volume response End If [COLOR="Black"]ElseIf .errorCode = BFUK.GetMarketTradedVolumeCompressedErrorEnum.EVENT_CLOSED Then If MyMarkets.Contains(.marketId) Then 'The MarketForm is open MyMarkets.Remove(.marketId) End If[/COLOR] Else Print("ErrorCode = " & .errorCode.ToString) End If End With End If Catch ex As ApplicationException 'If problem Print(ex.Message) End Try End Sub[/COLOR]
Any suggestions?
Thank you very much for your help
Leave a comment:
-
Limiting data requests
Monairda,
Putting the main thread to sleep is no good. I think it’s better to do it this way.
I have made a few changes to Sub GetMarketData. Instead of updating all markets every 5 sec, try updating each market in turn every 1 sec. Change your timer’s Interval to 1000 to call Sub GetMarketData every second.
This Sub now makes the API calls for each market in turn. When all markets are done the cycle repeats. This means that if, for example, 3 markets are selected, each market is updated every 3 sec.Code:[COLOR="Gray"]Friend MyMarkets As New Collection 'The markets of interest [COLOR="Black"]Private MarketNo As Integer 'The market index[/COLOR] Private Sub GetMarketData() Dim Market As MarketForm [COLOR="Black"]If MyMarkets.Count > 0 Then 'There are markets selected MarketNo += 1 'Next market If MarketNo > MyMarkets.Count Then MarketNo = 1 'All markets done, start again Market = MyMarkets(MarketNo)[/COLOR] Market.CallCount = 0 'Clear the call counter Dim oMPCreq As New BFUK.GetMarketPricesCompressedReq With oMPCreq .header = oHeaderUK() .marketId = Market.MarketId End With StateCount += 1 BetFairUK.getMarketPricesCompressedAsync(oMPCreq, StateCount) 'Call the API Dim oMTVCReq As New BFUK.GetMarketTradedVolumeCompressedReq 'The request object With oMTVCReq .header = oHeaderUK() .marketId = Market.MarketId End With StateCount += 1 BetFairUK.getMarketTradedVolumeCompressedAsync(oMTVCReq, StateCount) 'Call the API [COLOR="Black"]End If[/COLOR] End Sub[/COLOR]
Doing it this way means that getMarketPricesCompressed and getMarketTradedVolumeCompressed are each called 60 time per sec, so you shouldn’t get EXCEEDED_THROTTLE. Also, only 2 API calls are made each second, well within the 20 calls/sec limit.
Leave a comment:
-
Hi Mumbles0Originally posted by Mumbles0 View PostMonairda,
That's a very brutal approach. You are freezing your program for 1 sec if you open more than 15 markets. Does this work?
I would be interested to know a bit more about your project:- Are you using the Free or Full API?
- Is the code you've posted being called from a timer Tick? If so, what is the time interval?
I use the free API, I followed all the steps you've taken in the tutorial and there is a timer that has a refresh interval of 5 seconds. I am understanding what I do is to distribute the calls in those 5 seconds, right?
What makes the application is to cover the entire collection mymarkets every 5 seconds, but the problem is that if the collection has more than 10 markets over the limit of 20 calls per second.Code:Friend MyMarkets As New Collection 'The Markets of Interest
Thanks!!
Leave a comment:
-
Limiting data requests
Monairda,
That's a very brutal approach. You are freezing your program for 1 sec if you open more than 15 markets. Does this work?
I would be interested to know a bit more about your project:- Are you using the Free or Full API?
- Is the code you've posted being called from a timer Tick? If so, what is the time interval?
Leave a comment:
-
How to control the number of data requests ?
As always thank you very much Mumbles0
So not to exceed the limit of 20 calls per second, could put a counter between calls, and if it reaches 15 wait a second?
Sorry if this solution is not goodCode:Dim Market As MarketForm Dim counter As Int16 = 0 For Each Market In MyMarkets counter + = 1 If counter > 15 Then System.Threading.Thread.Sleep(1000) counter= 0 End If Market.CallCount = 0 'Clear the call counter Dim oMPCreq As New BFUK.GetMarketPricesCompressedReq With oMPCreq .header = oHeaderUK() .marketId = Market.MarketId End With StateCount += 1 BetFairUk.getMarketPricesCompressedAsync(oMPCreq, StateCount) 'Call the API Dim oMTVCReq As New BFUK.GetMarketTradedVolumeCompressedReq 'The request object With oMTVCReq .header = oHeaderUK() .marketId = Market.MarketId End With StateCount += 1 BetFairUk.getMarketTradedVolumeCompressedAsync(oMTVCReq, StateCount) 'Call the API Next
Thanks!
Leave a comment:
-
Data request charges
Monairda,
While it is possible to exceed the 20 calls/second limit with the Free API, the problem mainly affects users of the Full Access API. The charges are explained here if you can understand this.
The main point is you may be charged if you exceed 20 API calls per second, also if you place or edit more than 1000 bets in an hour. If you don’t like this it’s up to you to ensure that your application stays below these limits.
Let’s say you have a multi-market app and, for each market, you make calls to getMarketPricesCompressed and getMarketTradedVolumeCompressed at regular intervals from a timer Tick event, i.e. 2 API calls per market.
If your sampling time interval is 1 sec, then you can look at up to 10 markets at once
i.e. 10 markets x 2 calls each = 20 calls in 1 sec
If your sampling time interval is 2 sec, then you can look at up to 20 markets at once
i.e. 20 markets x 2 calls each = 40 calls in 2 sec
etc...
If you are operating close to the limit you should also leave a bit of headroom for other calls (placeBets, etc).
The StateCount variable is used for something else (it prevents an async call error). You could implement a simple call limiting scheme using a call counter, but I don’t think it would be very satisfactory.
Leave a comment:


Leave a comment: