def get_account_balance(appkey, sessiontoken): """Returns dictionary of account details (balance/exposure limit etc). Parameters: appkey (str): Betfair Application Key sessiontoken (str): Betfair session token Returns: success: True/False indicating if request was successful. Details: dictionary/str. Dictionary including account details Fields include the available balance, exposure, exposure limit and discount rate for the account.""" data_type = "getAccountFunds" params = {} result = helpers.data_req(appkey, sessiontoken, data_type, params, "Account") if result.status_code == 200: if 'result' in result.json(): success = True data = result.json()['result'] details ={} details = {'AvailableBalance':data['availableToBetBalance'], 'Exposure':data['exposure'], 'ExposureLimit':data['exposureLimit'], 'Discount':data['discountRate']} else: success = False details = helpers.extract_error(result) else: success = False details = "Request for account balance failed, status code: {0}".format(str(result.status_code)) return success, details
def placeOrder(appkey, sessiontoken, marketid, selectionid, side, amount, limitprob): """Places a limit order with order type LAPSE (lapse the order when market goes in play). Parameters: appkey (str): Betfair Application Key sessiontoken (str): Betfair session token marketid (str/int): Market ID for order selectionid (str/int): Selection ID for order side (BACK/LAY): Side for order amount: Amount in account currency to bet limitprob (float): The probability you are buying/selling (e.g. 0.05 if you are buying 20.0) Returns: success (boolean): True if bet placement is successful, else false details (Dataframe/string): If success is true then a dataframe with bet details including betid/placeddate/status/size matched/average price matched.""" limitpx = round(helpers.odds_inverter(limitprob), 1) data_type = "placeOrders" instructions = [{ "selectionId": selectionid, "handicap": 0, "side": side, "orderType": "LIMIT", "limitOrder": { "size": amount, "price": limitpx, "persistenceType": "LAPSE" } }] params = {"marketId": marketid, "instructions": instructions} result = helpers.data_req(appkey, sessiontoken, data_type, params) if result.status_code == 200: data = result.json() if 'result' in data: if 'status' in data['result']: if data['result']['status'] == "SUCCESS": success = True betid = data['result']['instructionReports'][0]['betId'] placeddate = helpers.timestamp_todatetime( data['result']['instructionReports'][0]['placedDate']) orderstatus = data['result']['instructionReports'][0][ 'orderStatus'] pxmatched = data['result']['instructionReports'][0][ 'averagePriceMatched'] sizematched = data['result']['instructionReports'][0][ 'sizeMatched'] details = pd.DataFrame({ 'betId': [betid], 'placedDate': [placeddate], 'orderStatus': [orderstatus], 'averagePriceMatched': [pxmatched], 'sizeMatched': [sizematched] }) else: success = False status = data['result']['status'] details = "Bet placement failed, received the following json response: {0}".format( str(data['result'])) else: success = False details = "Bet placement failed, no status sent back in response" else: success = False details = "Failed to place bet, error details: {0}".format( str(data)) return success, details
def list_orders(appkey, sessiontoken, since=None, until=None): """Returns a dictionary of dataframes corresponding to filled/live and cancelled orders. Parameters: appkey (str): Betfair Application Key sessiontoken (str): Betfair session token since *optional* (datetime): Filter for orders from time created until *optional* (datetime): Filter for orders before time created Returns: success (boolean): True if api call is successful, else false details (dictionary/string): If success is true then a dictionary with 3 dataframes. Dictionary keys are live (dataframe of live orders), fills (dataframe of filled orders) and cancelled (dataframe of cancelled orders). If the request failed, returns an error.""" data_type = "listCurrentOrders" params = {"dateRange": {}} if since != None: since = helpers.datetime_totimestamp(since) until = helpers.datetime_totimestamp(until) params["dateRange"].update({"from": since}) params["dateRange"].update({"to": until}) result = helpers.data_req(appkey, sessiontoken, data_type, params) if result.status_code == 200: def try_convert_odds(x): try: return helpers.odds_transformer(float(x)) except: return x def try_convert_timestamp(x): try: return helpers.timestamp_todatetime(x) except: return x if 'result' in result.json(): success = True data = result.json()['result']['currentOrders'] df_dict = {} for fld in [ "betId", "marketId", "selectionId", "side", "status", "orderType", "placedDate", "matchedDate", "averagePriceMatched", "sizeMatched", "sizeCancelled", "sizeVoided", "sizeRemaining" ]: df_dict[fld] = [x.get(fld, "NotFound") for x in data] df_dict["price"] = [ x.get("priceSize", {}).get("price", "NotFound") for x in data ] df_dict["size"] = [ x.get("priceSize", {}).get("size", "NotFound") for x in data ] details = pd.DataFrame(df_dict) details['averagePriceMatched'] = details[ 'averagePriceMatched'].apply(lambda x: try_convert_odds(x)) details['price'] = details['price'].apply( lambda x: try_convert_odds(x)) details['placedDate'] = details['placedDate'].apply( try_convert_timestamp) details['matchedDate'] = details['matchedDate'].apply( try_convert_timestamp) live = helpers.extract_order_type(details, 'live') fills = helpers.extract_order_type(details, 'fills') cancelled = helpers.extract_order_type(details, 'cancelled') details = {'live': live, 'fills': fills, 'cancelled': cancelled} else: success = False details = helpers.extract_error(result) else: success = False details = "Request for order details failed, status code: {0}".format( str(result.status_code)) return success, details
def cancelOrder(appkey, sessiontoken, marketid, betid, sizereduction=None): """Cancel/reduce the size of a live bet. Parameters: appkey (str): Betfair Application Key sessiontoken (str): Betfair session token marketid (str/int): Market ID for order betid (str/int): Bet ID for cancellation sidereduction (float): Amount in account currency you want to reduce the bet Returns: success (boolean): True if bet cancellation is successful, else false details (Dataframe/string): If success is true then a dataframe with cancellation details including the bet id, size cancelled, and cancelled time. If false, an error message.""" data_type = "cancelOrders" if sizereduction == None: instructions = [{"betId": betid}] else: instructions = [{"betId": betid, "sizeReduction": sizereduction}] params = {'marketId': marketid, "instructions": instructions} result = helpers.data_req(appkey, sessiontoken, data_type, params) if result.status_code == 200: data = result.json() if 'result' in data: if 'status' in data['result']: if data['result']['status'] == "SUCCESS": success = True betid = data['result']['instructionReports'][0][ 'instruction']['betId'] sizecancelled = data['result']['instructionReports'][0][ 'sizeCancelled'] datecancelled = helpers.timestamp_todatetime( data['result']['instructionReports'][0] ['cancelledDate']) details = pd.DataFrame({ 'betId': [betid], 'sizeCancelled': [sizecancelled], 'cancelledDate': [datecancelled] }) else: success = False details = "Bet cancellations failed, received following json response: {0}".format( str(data)) else: success = False details = "Bet placement failed, no status sent back in response" else: success = False try: errorcode = data['error']['data']['APINGException'][ 'errorCode'] errordetails = data['error']['data']['APINGException'][ 'errorDetails'] details = "Failed to cancel bet, error code: {0}, error details: {1}".format( errorcode, errordetails) except KeyError: try: error = helpers.extract_error(result) details = "Failed to cancel bet, error details: {0}".format( error) except: details = "Failed to cancel bet, unrecognized error code." return success, details
def get_mkt_book(appkey, sessiontoken, marketids): """Retrieves the market book for a given market ID. Parameters: appkey (str): Betfair Application Key sessiontoken (str): Betfair session token marketids (list): List of market IDs for which odds will be returned. Returns: success (boolean): True if request is successful, else false details (dictionary/string): If success is true then a dictionary 2 fields. One field is metadata which has details on whether the odds are delayed, what the market status is, what the bet delay is, what the total matched is. The second field is a dataframe with 3 layers of market bids (backs) and offers (lays). The odds are returned in implied probabilities (i.e. 0.05 corresponds to 20 on betfair decimal odds. If success==false, an error message.""" data_type = "listMarketBook" params = { 'marketIds': marketids, 'priceProjection': { "priceData": ["EX_ALL_OFFERS"] } } result = helpers.data_req(appkey, sessiontoken, data_type, params) if result.status_code == 200: if 'result' in result.json(): try: data_all = result.json()['result'] except (IndexError, KeyError): return False, "No market book data found for market id {0}".format( str(marketids)) success = True market_data_object = {} for i in range(len(data_all)): #get the data for each market ID. data = data_all[i] marketid = data['marketId'] runners = data['runners'] metadata = { 'Delayed': data.get('isMarketDataDelayed', float("nan")), 'MarketStatus': data.get('status', float("nan")), 'betDelay': data.get('betDelay', float("nan")), 'inplay': data.get('inplay', float("nan")), 'totalmatched': data.get('totalMatched', float("nan")), 'UpdateTime': datetime.datetime.now() } selectionids = [x['selectionId'] for x in runners] status = [x.get('status', float("nan")) for x in runners] lastprice = [ helpers.odds_transformer( x.get('lastPriceTraded', float("nan"))) for x in runners ] totalmatched = [ x.get('totalMatched', float("nan")) for x in runners ] def try_layer_else_0(layers_dict, fieldtype, index): try: mktpacket = layers_dict['ex'][fieldtype][index] return (helpers.odds_transformer(mktpacket['price']), mktpacket['size']) except: return (0, 0) market_df = pd.DataFrame() market_df['SelectionID'] = selectionids market_df['Status'] = status market_df['lastprice'] = lastprice market_df['totalMatched'] = totalmatched for i in range(3): back_data = [ try_layer_else_0(x, 'availableToLay', i) for x in runners ] lay_data = [ try_layer_else_0(x, 'availableToBack', i) for x in runners ] market_df['BACK' + str(i)] = [x[0] for x in back_data] market_df['BACKSIZE' + str(i)] = [x[1] for x in back_data] market_df['LAY' + str(i)] = [x[0] for x in lay_data] market_df['LAYSIZE' + str(i)] = [x[1] for x in lay_data] details = {'Metadata': metadata, "Odds": market_df} market_data_object[marketid] = details details = market_data_object else: success = False details = str(result.json()) else: success = False details = "Request for events failed, details: {0}".format( str(result.json())) return success, details