def handle_IndexError(betfairClient, exchangeId, marketId): """IndexError caught check the market status is active. Return false if it is not active, else true """ logger.warning('IndexError caught, check marketStatus is ACTIVE') market_price = qwertymarket.getMarketPricesCompressed(betfairClient, exchangeId, marketId) market_status = qwertymarket.marketStatus(market_price) if market_status != 'ACTIVE': time.sleep(5) market_price = qwertymarket.getMarketPricesCompressed(betfairClient, exchangeId, marketId) market_status = qwertymarket.marketStatus(market_price) if market_status != 'ACTIVE': cleanUp.clean_up(betfairClient, marketId) return False else: return True
def placeBetCall(betfairClient, exchange, placeBet): counter=0 while True: if counter <= 5: try: bet = betfairClient.placeBets(exchange, bets=[placeBet]) return bet.betResults[0] except bfpy.bferror.BfNetworkError: betlogger.error("Network timed out...retrying...") time.sleep(1) continue except bfpy.bferror.BfServiceError: betlogger.exception("Error placing bet, event may be closed or suspended. \ Will try again if suspended...") if qwertymarket.getMarketPricesCompressed(betfairClient, exchange, placeBet.marketId).marketPrices.marketStatus == 'CLOSED': betlogger.error("Market closed.") return 1 time.sleep(0.5) counter += 1 continue else: break
def updateBet(betfairClient, exchange, betId, selectionId, oldPrice, oldSize, newPrice, newSize, betType, oldBetPersistenceType, newBetPersistenceType): updateBet = betfairClient.createUpdateBets() updateBet.betId = betId updateBet.newBetPersistenceType = newBetPersistenceType updateBet.newPrice = newPrice updateBet.newSize = newSize updateBet.oldBetPersistenceType = oldBetPersistenceType updateBet.oldPrice = oldPrice updateBet.oldSize = oldSize counter=0 while True: if counter <= 5: try: betResponse = betfairClient.updateBets(exchange, bets=[updateBet]) return betResponse.betResults[0] except bfpy.bferror.BfNetworkError: betlogger.error("Network timed out...retrying...") time.sleep(1) continue except bfpy.bferror.BfServiceError: betlogger.exception("Error placing bet, event may be closed or suspended. \ Will try again if suspended...") if qwertymarket.getMarketPricesCompressed(betfairClient, exchangeId, marketId).marketPrices.marketStatus == 'CLOSED': betlogger.error("Market closed.") break time.sleep(0.5) counter += 1 continue except Exception, e: betlogger.exception('Error updating bets... going to try cancel') betResponse = cancelBet(betfairClient, exchange, betId) return 0 else: break
def collectData(betfairClient, exchangeId, marketId): global Datastore horses = None previousTimeFromStart = None runnerKeys = 'runnerKeys' market_price = qwertymarket.getMarketPricesCompressed(betfairClient, exchangeId, marketId) collectlogger.debug('Collected data....') if marketId not in Datastore.keys(): #openTime is calculated if the marketId does not exist in Datastore. collectlogger.debug('New market found') openTime = market_price.header.timestamp timeId = 0 IDgap = 0 timeDelta = 0 else: timeFromStart = market_price.header.timestamp - Datastore[marketId]['openTime'] timeDelta = int(round(timeFromStart.seconds + timeFromStart.microseconds / 1e6)) timeId = Datastore[marketId]['timeId'] Datastore[marketId]['timeDelta'] = timeDelta collectlogger.debug('TimeDelta: %s. timeId: %s', Datastore[marketId]['timeDelta'], timeId) if timeDelta > timeId and timeDelta > 0 and timeDelta < 80000: IDgap = timeDelta - timeId else: IDgap = 0 Datastore[marketId]['IDgap'] = IDgap collectlogger.debug('IDgap = 0, skipping data. Timestamp: %s', market_price.header.timestamp) return IDgap timeId = timeDelta collectlogger.debug('Importing new data TimeId: %s at %s', timeId, market_price.header.timestamp) BP1 = 'BP1'; BV1 = 'BV1' BP2 = 'BP2'; BV2 = 'BV2' LP1 = 'LP1'; LV1 = 'LV1' LP2 = 'LP2'; LV2 = 'LV2' totalAmountMatched = 'totalAmountMatched' lastPriceMatched = 'lastPriceMatched' for runnerPrices in market_price.marketPrices.runnerPrices: #check we have values for all bets and lays while True: if len(runnerPrices.bestPricesToLay) < 2: price = bfutil.Factory.Price() price.price = 1000 price.amountAvailable = 1 runnerPrices.bestPricesToLay.append(price) else: break while True: if len(runnerPrices.bestPricesToBack) < 2: price = bfutil.Factory.Price() price.price = 1.01 price.amountAvailable = 1 runnerPrices.bestPricesToBack.append(price) else: break try: horses = dict([(runnerPrices.selectionId,dict([(timeId,dict([('BP1',runnerPrices.bestPricesToBack[0].price), ('BV1',runnerPrices.bestPricesToBack[0].amountAvailable), ('BP2',runnerPrices.bestPricesToBack[1].price), ('BV2',runnerPrices.bestPricesToBack[1].amountAvailable), ('LP1',runnerPrices.bestPricesToLay[0].price), ('LV1',runnerPrices.bestPricesToLay[0].amountAvailable), ('LP2',runnerPrices.bestPricesToLay[1].price), ('LV2',runnerPrices.bestPricesToLay[1].amountAvailable), ('totalAmountMatched',runnerPrices.totalAmountMatched)]))])) for runnerPrices in market_price.marketPrices.runnerPrices]) except IndexError: collectlogger.error('Market depth not available. IndexError') if marketId in Datastore.keys(): Datastore[marketId]['inPlayDelay'] = market_price.marketPrices.delay time.sleep(1) raise IndexError except Exception, e: collectlogger.exception('Horses dictionary failed at timeId %s', timeId) raise e
def main(): """The brains of the bot Finds all the races """ betfairClient = bfclient.BfClient() eventResponse = None race_list = None cardGenTime = 0 login_timer = 0 while True: login_rsp = auth.login(betfairClient) # Generate the list of available races. Limit the result to 100 (race_list, cardGenTime) = gen_race_list(cardGenTime, race_list, betfairClient) # get the exchangeId, marketId for the next race and race_queue # refactor - turn into class, return object. (exchangeId, marketId, race_queue, race_list) = get_next_race(race_list) # determine race status, proceed if it is active. market_price = qwertymarket.getMarketPricesCompressed(betfairClient, exchangeId, marketId) market_status = qwertymarket.marketStatus(market_price) if market_status == 'CLOSED': logger.debug('Oops market is closed, finding the next race/market') time.sleep(2) continue elif market_status == 'SUSPENDED': logger.debug('Market is now suspended, finding the next race/market') time.sleep(5) continue # Great the next race is active, lets find out when it starts market_info = qwertymarket.getMarketInfo(betfairClient, exchangeId, marketId) TTL = qwertymarket.timeTillRaceStarts(market_info) logger.info('Time till live: %s', TTL) if TTL > 240: #if time till race is more than 5 minutes away handle_long_ttl(cardGenTime, race_list, market_info) elif market_price.marketPrices.delay > 0: logger.info("-------------Market is in-play---------------") time.sleep(10) continue # nested while true, why? Because we don't want it to change races if it's active. while True: try: collectData.collectData(betfairClient, exchangeId, marketId) timeId = collectData.Datastore[marketId]['timeId'] IDgap = collectData.Datastore[marketId]['IDgap'] if IDgap == 0: time.sleep(2) logger.debug('IDgap is zero') continue #don't run anything else except IndexError: if handle_IndexError(betfairClient, exchangeId, marketId): continue else: break except ZeroDivisionError: logger.warning('Zero Division Exception caught.') break except bfpy.bferror.BfNetworkError: logger.error("Network timed out...retrying...") continue except Exception, e: logger.exception('Collecting data at timeId: %s', timeId) raise e try: play.inPlay(betfairClient, exchangeId, marketId, timeId) play.pastPlay(betfairClient, exchangeId, marketId, timeId) except play.InPlayClause as e: logger.debug('In Play is greater than 30 seconds, look for the next race') break except Exception as e: logger.exception('Running inPlay or pastPlay') raise e try: for fillInId in range(timeId-IDgap+1, timeId+1): for selectionId in collectData.Datastore[marketId]['runnerKeys']: if fillInId != timeId: collectData.fillInMissingData(marketId, selectionId, fillInId, timeId) if fillInId >= 30: selection.calculateTPS(marketId, selectionId, fillInId) except IndexError: if handle_IndexError(betfairClient, exchangeId, marketId): continue else: break except ZeroDivisionError: logger.warning('Zero Division Exception caught.') break except Exception, e: logger.exception('Filling missing data or calculating TPS at timeId: %s', timeId) raise e try: if timeId > 1: selection.selectionCriteria(marketId, timeId) for selectionId in collectData.Datastore[marketId]['selectedRunnerIds']: if 'max30BP' not in collectData.Datastore[marketId][selectionId][0].keys(): for backCalc in range(0, timeId - IDgap+1): analysis.analyse(marketId, selectionId, backCalc) if backCalc == timeId - IDgap: logger.info('Successful back analysis of %s to timeId %s', collectData.Datastore[marketId][selectionId]['HorseName'], backCalc) collectData.Datastore[marketId][selectionId]['backCalc'] = backCalc for fillInId in range(timeId-IDgap+1, timeId+1): analysis.analyse(marketId, selectionId, fillInId) except IndexError: if handle_IndexError(betfairClient, exchangeId, marketId): continue else: break except ZeroDivisionError: logger.warning('Zero Division Exception caught.') break except Exception, e: logger.exception('Error: Running Analysis or selecting horses at timeId: %s', timeId) logger.exception("timeId: %s", timeId) raise e
analysis.analyse(marketId, selectionId, fillInId) except IndexError: if handle_IndexError(betfairClient, exchangeId, marketId): continue else: break except ZeroDivisionError: logger.warning('Zero Division Exception caught.') break except Exception, e: logger.exception('Error: Running Analysis or selecting horses at timeId: %s', timeId) logger.exception("timeId: %s", timeId) raise e market_price = qwertymarket.getMarketPricesCompressed(betfairClient, exchangeId, marketId) market_status = qwertymarket.marketStatus(market_price) if market_status != 'ACTIVE': time.sleep(10) market_price = qwertymarket.getMarketPricesCompressed(betfairClient, exchangeId, marketId) market_status = qwertymarket.marketStatus(market_price) if market_status != 'ACTIVE': cleanUp.clean_up(betfairClient, marketId) break else: continue if collectData.Datastore[marketId]['selectedRunnerIds']: logger.debug('Selected RunnerIds: %s',
def test_market_status(self): self.status = ['ACTIVE','SUSPENDED','CLOSED'] self.market_price = getMarketPricesCompressed(self.bf_client, self.exchangeId, self.marketId) self.market_status = marketStatus(self.market_price) self.assertIn(self.market_status, self.status)