Announcement

Collapse
No announcement yet.

Why can I login to Rescript but not JsonRpc Client? And Problems Cancelling Bets

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Why can I login to Rescript but not JsonRpc Client? And Problems Cancelling Bets

    I am trying to convert my old SOAP based BOT to the new API.

    Having a few issues such as being able to get account funds, cancelling bets and getting bet details but first off I would like to know why (using the core BDP code they supplied for c# which has almost identical classes for both JSON libraries why I can login with my API Key, Session and URL to the JsonRpcClient but not the RescriptClient?

    I am passing the same URL, AppKey and Session to both classes but the RescriptClient won't let me create a client object whilst the JsonRpcClient will.

    I have a Login method where I set the preferred login method either Rescript or JsonRpc and then I set the backup to the opposite.

    If the preferred login fails I then try the other one.

    I am trying to use rescript as my preferred login but it just won't let me login. I don't know if the end point URL is different between the two e.g for the JsonRescript Client I am currently using https://beta-api.betfair.com

    If I try and change this to https://api.betfair.com

    I get the following error in the Newton.Json DLL which I cannot check as it's compiled

    Unhandled Exception: Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
    at Newtonsoft.Json.JsonTextReader.ParseValue() in c:\Dev\Releases\Working\Netonsoft.Json\Src\Newtons oft.Json\JsonTextReader.cs:line 996
    at Newtonsoft.Json.JsonTextReader.ReadInternal() in c:\Dev\Releases\Working\Newtonsoft.Json\Src\Newton soft.Json\JsonTextReader.cs:line 476

    Anyway I can login into the JsonRpcClient with that endpoint, my appkey and session okay but when I try with the RescriptLogin I don't get any errors (it's in a try/catch) but I just get an empty client object returned which then makes me move on to the next JSON object.

    Some example debug (with sessions/appkeys changed) is below


    Debug code:

    The session from the path is urT4kc39f2pciMW3PmlUg+ZsR/Zsz83bjy6uy9MSN9I=
    Prefered Login Method = rescript
    BackUp Login Method = JsonRpcClient
    In RescriptLogin
    Try Logging in with RescriptLogin = https://beta-api.betfair.com, BjdUERmcEcTrGnis, urT4kc39f2pciMW3PmlUg+ZsR/Zsz83bjy6uy9MSN9I=
    In RescriptClient endPoint = https://beta-api.betfair.com appKey = BjdUERmcEcTrGnis sessionToken = urT4kc39f2pciMW3PmlUg+ZsR/Zsz83bjy6uy9MSN9I=
    this.Client should be populated
    Couldnt get a client object with RescriptClient!
    RETURN False
    Rescript Login Failed so try JsonRpcClientLogin
    In JsonRpcClientLogin
    In RescriptClient endPoint = https://beta-api.betfair.com appKey = BjdUERmcEcTrGnis sessionToken = urT4kc39f2pciMW3PmlUg+ZsR/Zsz83bjy6uy9MSN9I=
    RETURN True
    We can login with this session and AppKey so return session: urT4kc39f2pciMW3PmlUg+ZsR/Zsz83bjy6uy9MSN9I=
    Our sessionID is urT4kc39f2pciMW3PmlUg+ZsR/Zsz83bjy6uy9MSN9I=
    we have logged in and our sessionID is urT4kc39f2pciMW3PmlUg+ZsR/Zsz83bjy6uy9MSN9I=

    The code in both classes is pretty similar e.g for the one I cannot use it's

    Code:
    public RescriptClient(string endPoint, string appKey, string sessionToken)
    {
    	this.EndPoint = endPoint + "/rest/v1/";	
    
    	CustomHeaders = new NameValueCollection();
    	
    	if (appKey != null)
    	{
    		CustomHeaders[APPKEY_HEADER] = appKey;
    	}
    	if (sessionToken != null)
    	{
    		CustomHeaders[SESSION_TOKEN_HEADER] = sessionToken;
    	}
    }

    and the one I can login in

    Code:
    public JsonRpcClient(string endPoint, string appKey, string sessionToken)
    {	
    
    	this.EndPoint = endPoint + "/json-rpc";
    
    	CustomHeaders = new NameValueCollection();
    	
    	if (appKey != null)
    	{
    		CustomHeaders[APPKEY_HEADER] = appKey;
    	}
    	if (sessionToken != null)
    	{
    		CustomHeaders[SESSION_TOKEN_HEADER] = sessionToken;
    	}
    }
    So the end points are different at the end of the URL.

    Both classes extend the same objects e.g

    Rescript


    Code:
    namespace Api_ng_sample_code
    {
        public class RescriptClient : HttpWebClientProtocol, IClient
        {
    and JsonRpc

    Code:
    namespace Api_ng_sample_code
    {
        public class JsonRpcClient  : HttpWebClientProtocol, IClient
        {
    You can get all the C# Api code from their examples page API-ING it's called for C# > https://github.com/betfair/API-NG-sa...sample-code/TO

    Any clues?


    Also whilst I am bitching n moaning I am trying to write my own code for the cancelOrders method.

    I have a test where I set a LAY bet up for £10 at a price of 1.10 so it won't get snapped up. Then I get the BetID from the result of the placeOrders method and try to cancel the full bet.

    I am not sure whether to cancel the full bet I am supposed to supply NOTHING or the value 0 for SizeReduction if I want to cancel the FULL bet. Also if I had a bet of £10 and I wanted to cancel £4 would I supply 6.00 or 4.00 for this? Is the size I want it reduced TO or the amount to deduct from the current bet size?

    https://api.developer.betfair.com/services/webapps/docs/display/1smk3cen4v3lu3yomq5qye0ni/Betting+TypeDefinitions#BettingTypeDefinitions-CancelInstruction



    At the moment I am getting errors when I try and cancel the bet. The bet is placed okay and I can see it in Betfairs website even though the placeOrders method seems to show some errors in it (see debug) but the cancelOrders code just returns errors and doesn't cancel anything at all.

    Notice the code at the end with the response from my call to cancel the bet it says BET_ACTION_ERROR and INVALID_BET_SIZE - I have no idea why.

    If someone could give me the Request URL I should be using that would be great!

    PlaceOrder: 1088797 - LAY - 10 - NONE
    look at Bet Object
    LAY
    NONE
    1.1
    10
    5866287
    111836561
    Instruction SelectionID: 5866287
    Instruction OrderType: LIMIT
    Instruction Side: LAY
    EndPoint = https://beta-api.betfair.com/json-rpc

    Calling: SportsAPING/v1.0/placeOrders With args: {"marketId":"1.111836561","instructions":[{"orderType":"LIMIT","selectionId":5866287,"handic ap":0.0,"side":"LAY","limitOrder":{"size":10.0,"pr ice":1.1,"persistenceType":"LAPSE"}}],"customerRef":"PlaceOrder_BetPK-1088797","locale":null}

    Got Response: {"jsonrpc":"2.0","result":{"status":"SUCCESS","err orCode":"ERROR_IN_MATCHER","marketId":"1.111836561 ","instructionReports":[{"status":"SUCCESS","errorCode":"INVALID_BET_SIZE" ,"instruction":{"orderType":"LIMIT","selectionId": 5866287,"handicap":0.0,"side":"LAY","limitOrder":{ "size":10.0,"price":1.1,"persistenceType":"LAPSE"} },"betId":"31644002430","placedDate":"2013-11-12T10:11:54Z","averagePriceMatched":0.0,"sizeMatch ed":0.0}],"customerRef":"PlaceOrder_BetPK-1088797"},"id":1}
    PlaceOrder Status = SUCCESS
    PlaceOrder Success
    BetID is 31644002430
    This Bet could not be fully matched at this point in time; Bet UnMatched; Any matched amount was £0; Current Match Status: U; Bet ID: 31644002430
    Bet Message = Bet UnMatched
    Bet was placed was okay; BetPK: 1088797; BetID: 31644002430
    Now Cancel it!
    CancelBet - BetID: 31644002430 - SizeReducton: 0;
    IN CancelOrder
    Instruction BetID: 31644002430
    Instruction SizeReduction: 0
    EndPoint = https://beta-api.betfair.com/json-rpc

    Calling: SportsAPING/v1.0/cancelOrders With args: {"marketId":"1.111836561","instructions":[{"betId":"31644002430","sizeReduction":0.0}],"customerRef":"CancelOrder_BetPK-1088797"}

    Got Response: {"jsonrpc":"2.0","result":{"status":"FAILURE","err orCode":"BET_ACTION_ERROR","marketId":"1.111836561 ","instructionReports":[{"status":"FAILURE","errorCode":"INVALID_BET_SIZE" ,"instruction":{"betId":"31644002430","sizeReducti on":0.0}}],"customerRef":"CancelOrder_BetPK-1088797"},"id":1}
    Status = FAILURE
    CancelOrder Failure - error = INVALID_BET_SIZE
    Cancel Remaining Amount = 0
    Cancel Status =
    Cancel Message = INVALID_BET_SIZE
    Bet was not cancelled INVALID_BET_SIZE
    Any help on either of these matters would be great. Thanks!

  • #2
    Hi,

    URLs for betting:

    or


    URLs for account info:

    or


    For cancelOrders: To cancel all the bet do not send "sizeReduction". Because you are sending 0.00 it thinks you want to reduce the size by zero so raises the error INVALID_BET_SIZE. I believe.

    Comment


    • #3
      I still get errors with the CancelBets method

      Hi,

      I have removed the sizeReduction value so I am cancelling the full bet. However if you notice from this debug. Even though the bet (a lay bet for £10 at 1.10) is getting placed AND then cancelled (I check in Betfair) the response still contains error messages.

      The PlaceOrder contains "ERROR_IN_MATCHER" and "INVALID_BET_SIZE" and the CancelOrder contains the same!

      I have also changed the end points but I still cannot login with Rescript whilst I can with Json-rpc e.g

      BackUp Login Method = JsonRpcClient
      In RescriptLogin
      Try Logging in with RescriptLogin = https://api.betfair.com/exchange/betting, XXX , xxxxxxxxxxxxxxxxxx=
      In RescriptClient endPoint before adding /rest/v1.0/ to it is https://api.betfair.com/exchange/betting
      Now its https://api.betfair.com/exchange/betting/rest/v1.0/ appKey = XXX sessionToken = xxxxxxxxxxxxxxxxxx=
      this.Client should be populated
      Couldnt get a client object with RescriptClient!
      RETURN False
      Rescript Login Failed so try JsonRpcClientLogin
      In JsonRpcClientLogin
      In JsonRpcClient endPoint before adding /json-rpc/v1/ to it is https://api.betfair.com/exchange/betting
      Now its https://api.betfair.com/exchange/betting/json-rpc/v1/ appKey = XXX sessionToken = xxxxxxxxxxxxxxxxxx=
      RETURN True
      We can login with this session and AppKey so return session: xxxxxxxxxxxxxxxxxx=
      So I cannot login with Rescript still even though I am using the changed endpoint URL https://api.betfair.com/exchange/betting/rest/v1.0/

      Also here is the place/cancel order which does place/cancel but the JSON contains errors - Betfair BDP say they cannot reproduce it so I have no clue to why it is working but still giving me errors. Especially seeing my code is based on their example C# code API-ING.


      Instruction SelectionID: 5594022
      Instruction OrderType: LIMIT
      Instruction Side: LAY
      EndPoint = https://api.betfair.com/exchange/betting/json-rpc/v1/

      Calling: SportsAPING/v1.0/placeOrders With args: {"marketId":"1.111875578","instructions":[{"orderType":"LIMIT","selectionId":5594022,"handic ap":0.0,"side":"LAY","limitOrder":{"size":10.0,"pr ice":1.1,"persistenceType":"LAPSE"}}],"customerRef":"PlaceOrder_BetPK-10896210"}

      Got Response: {"jsonrpc":"2.0","result":{"status":"SUCCESS","err orCode":"ERROR_IN_MATCHER","marketId":"1.111875578 ","instructionReports":[{"status":"SUCCESS","errorCode":"INVALID_BET_SIZE" ,"instruction":{"orderType":"LIMIT","selectionId": 5594022,"handicap":0.0,"side":"LAY","limitOrder":{ "size":10.0,"price":1.1,"persistenceType":"LAPSE"} },"betId":"31712836514","placedDate":"2013-11-15T16:58:02Z","averagePriceMatched":0.0,"sizeMatch ed":0.0}],"customerRef":"PlaceOrder_BetPK-10896210"},"id":1}
      PlaceOrder Status = SUCCESS
      PlaceOrder Success
      Extract BetID from 31712836514
      This Bet could not be fully matched at this point in time; Bet UnMatched; Any matched amount was 0; Current Match Status: U; Bet ID: 31712836514
      Bet Message = Bet UnMatched
      Bet was placed was okay; BetPK: 10896210; BetID: 31712836514
      Now Cancel it!
      CancelBet - BetID: 31712836514 - SizeReducton: 0;
      IN CancelOrder
      Instruction BetID: 31712836514
      Instruction SizeReduction:
      EndPoint = https://api.betfair.com/exchange/betting/json-rpc/v1/

      Calling: SportsAPING/v1.0/cancelOrders With args: {"marketId":"1.111875578","instructions":[{"betId":"31712836514"}],"customerRef":"CancelOrder_BetPK-10896210"}

      Got Response: {"jsonrpc":"2.0","result":{"status":"SUCCESS","err orCode":"ERROR_IN_MATCHER","marketId":"1.111875578 ","instructionReports":[{"status":"SUCCESS","errorCode":"INVALID_BET_SIZE" ,"instruction":{"betId":"31712836514"},"sizeCancel led":10.0}],"customerRef":"CancelOrder_BetPK-10896210"},"id":1}
      Status = SUCCESS
      CancelOrder Success - SizeCancelled = 10
      Cancel Remaining Amount = 0
      Cancel Status = C
      Cancel Message = Bet Cancelled
      So I don't know if you have any ideas about this or not?

      I am having to write a lot of code to make the account libraries etc. So much work, so little time and so, so, much missing from the Betfair example code!

      Thanks

      Comment


      • #4
        Hello there,

        I'm actually developing an api client in c# and am receiving exactly the same error statuses as you are. Like yourself, I'm using the sample from github. I've started to rely on the status of SUCCESS to drive my decision trees but it feels wrong that I'm ignoring these phantom errors (even tho they appear not to be errors).

        Did you ever reach a resolution with this, whereby you managed to receive confirmation that didn't include the phantom errors??

        Hope you can help as I really want to tidy my code up

        All the best
        jim

        Comment


        • #5
          Hi

          I "think" it was the endpoint I was using.

          Would have to check tomorrow but search all posts for monkeymagix to see if you can see anything I wrote back.

          As for the errors in the responses with a success status it was because the first ENUM in the response class was not "NONE" it was either INVALID_BET_SIZE or ERROR_IN_MATCHER so it defaulted to an error. Add in NONE to those response classes as the first item, to fix that.

          Cannot remember at home was the json rpc issue was at the moment.

          Comment


          • #6
            monkeymagix - I actually found that problem yesterday and meant to report back on that. I actually approached it slightly differently and made the ErrorCodes nullable, therefore, no new faux enum values added to cope with this. My structure ended up:

            public class PlaceExecutionReport==>
            public ExecutionReportErrorCode? ErrorCode { get; set; }

            and

            public class PlaceInstructionReport==>
            public InstructionReportErrorCode? ErrorCode { get; set; }

            hope this adds to the discussion.
            Last edited by jim tollan; 15-04-2014, 06:07 PM.

            Comment


            • #7
              Fix was

              Hi

              As for the Rescript issue I think it was because I was using old endpoints (dev not live) and I was trying to login to both the Client AND Account endpoints at the same time. As my code for the Account interface was not complete yet I was getting an error when I was trying to check that both objects were not null.

              E.G when I run my BOT it constantly saves the session (or re-uses it if it needs a new one) and then logins with the appkey and session to either JSON or ReScript with the other as the backup.

              The code to do the logging in (high up code) was like this (highlighted the erroring code)


              Code:
              private bool JsonRpcClientLogin()
                      {
                              
                          bool success = false;
              
                          // reset
                          this.Client = null;
                          this.Account = null;
              
                          try
                          {
                          
                              this.Client = new JsonRpcClient(BetfairAPI.BetfairAPIURL, BetfairAPI.APPKEY, this.SessionCode);
                             
              
                              this.Account = new JsonRpcClient(BetfairAPI.BetfairAccountURL, BetfairAPI.APPKEY, this.SessionCode);
              
                           
                          }
                          catch (System.Exception ex)
                          {
                          
              
                              return success;
                          }
              
                          // this was failing as this.Account WAS NULL due to me not finishing the code in that class. When it was finished it was ok
                          if (this.Client != null && this.Account != null)
                          {
                              success = true;
                          }
                          else
                          {
                              this.HelperLib.LogMsg("Couldnt get a client object with JsonRpcClient!");
                          }
              
                          HelperLib.LogMsg("RETURN " + success.ToString());
              
                          return success;
                      }
              Don't know if this helps or not as it was quite a specific error.


              As for the enums I just did this.



              Code:
              using System;
              using System.Collections.Generic;
              using System.Linq;
              using System.Text;
              using Newtonsoft.Json;
              using Newtonsoft.Json.Converters;
              
              namespace Api_ng_sample_code.TO
              {
                  public enum CurrentBetStatus 
                  {
                      NONE ,
                      MATCHED , // A matched bet
                      UNMATCHED ,	// An unmatched bet
                      LAPSED,	// Unmatched bet that was cancelled by Betfair (for example at turn in play).
                      CANCELLED , // Unmatched bet that was cancelled by an explicit customer action.
                      SETTLED , // a settled bet
                      PARTIALLYMATCHED , // a partially matched bet
                      PARTIALLYCANCELLED  // a partially cancelled bet
                  }
              }

              and



              Code:
              using System;
              using System.Collections.Generic;
              using System.Linq;
              using System.Text;
              using Newtonsoft.Json;
              using Newtonsoft.Json.Converters;
              
              namespace Api_ng_sample_code.TO
              {
                  [JsonConverter(typeof(StringEnumConverter))]
                  public enum InstructionReportErrorCode
                  {
                      OK,
                      INVALID_BET_SIZE,					
                      INVALID_RUNNER,						
                      BET_TAKEN_OR_LAPSED,				
                      BET_IN_PROGRESS,					
                      RUNNER_REMOVED,						
                      MARKET_NOT_OPEN_FOR_BETTING,		
                      LOSS_LIMIT_EXCEEDED,				
                      MARKET_NOT_OPEN_FOR_BSP_BETTING,	
                      INVALID_PRICE_EDIT,					
                      INVALID_ODDS,						
                      INSUFFICIENT_FUNDS,					
                      INVALID_PERSISTENCE_TYPE,			
                      ERROR_IN_MATCHER,					
                      INVALID_BACK_LAY_COMBINATION,		
                      ERROR_IN_ORDER,						
                      INVALID_BID_TYPE,					
                      INVALID_BET_ID,						
                      CANCELLED_NOT_PLACED,				
                      RELATED_ACTION_FAILED,				
                      NO_ACTION_REQUIRED,					
                  }
              }

              I also added into the Place/CancelExecutionReport.cs this method so it defaults to OK


              public class CancelExecutionReport
              {
              public CancelExecutionReport()
              {
              ErrorCode = ExecutionReportErrorCode.OK;
              }
              So that it always defaulted to OK UNLESS an ERROR DID occur.

              Thanks

              Rob

              Comment


              • #8
                Actually

                Actually I think the 2nd from last bit of code wasn't anything to do with it e.g the BetStatus ENUM

                Comment


                • #9
                  monkeymagix,

                  Be very careful when adding new enums to the TOP of the enum stack as the default first entry is always zero (unless you supply a value). Therefore, you stand a good chance of parsing all your errorcodes shifted by 1 given those changes. This may or may not be an issue as you may have accommodated for this.

                  And thanks for the code snippets, I too cache my session token and only login when required, so I think we're on the same page there. And likewise, I keep my accounts and betting objects as seperate dll's which only share the login token and appid.

                  Nice to chat -cheers again
                  jim

                  Comment

                  Working...
                  X