def arbitrage(obj): obj.current_strategy = 'Arbitrage' temp_settings = obj.strategy_settings['arbitrage'] min_price = temp_settings['min_price'] max_price = temp_settings['max_price'] min_profit = temp_settings['min_profit'] min_percentage_of_price = temp_settings['min_percentage_of_price'] players = temp_settings['players'] remove_keys = [ 'min_price', 'max_price', 'min_profit', 'min_percentage_of_price', 'players' ] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} multi_log(obj, 'Conducting Arbitrage...', level='title') players_to_arbitrage = [] # Go through player lists for player in players: futbin = info.get_price(player, obj, False, False, 'futbin') futhead = info.get_price(player, obj, False, False, 'futhead') if futbin != 0 and futhead != 0: potential = int(round((futbin * 0.95) - futhead)) percent = abs(int(round((potential / futbin) * 100))) if potential > min_profit and percent > min_percentage_of_price: players_to_arbitrage.append( (player, futhead, futbin, potential)) sleep(0.25) if len(players_to_arbitrage) == 0: multi_log(obj, 'No players to arbitrage') return None for player in players_to_arbitrage: search_price = player[2] tier = info.get_tier(search_price) search_price = info.round_down(search_price, Global.rounding_tiers[tier]) sell_price = info.round_down(player[2] - (0.2 * player[3]), Global.rounding_tiers[tier]) if search_price > 0: if obj.get_credits( ) > search_price and min_price <= search_price <= max_price: snipe_criteria = { 'search_type': 'Players', 'player': player[0], 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } common_snipe(obj, name=info.get_player_info( snipe_criteria['player'], False)['name'], snipe_criteria=snipe_criteria, price=search_price, sell_price=sell_price, strategy='arbitrage', **settings)
def common_fight(obj, strategy, use_buy_percent=None, min_profit=100): def get_bids(price_to_get): bids = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Active Bids')]", gp_type='xpath', get_price=price_to_get) to_fight = [] for b in bids: if not b['expired'] and b['time_left'] > 5: to_fight.append(b) return to_fight multi_log(obj, 'Fighting for bids...', level='header') obj.go_to('transfer_targets') fight_bids = get_bids(True) prices = {} for bid in fight_bids: prices[bid['resource_id']] = info.get_price(bid['resource_id'], obj, False) min_expire = 9999999 while len(fight_bids) > 0: fight_bids = get_bids(False) for bid in fight_bids[:]: if bid['time_left'] < min_expire: min_expire = bid['time_left'] if not bid['expired'] and bid[ 'bid_status'] == 'outbid' and 3 < bid['time_left'] <= 60: tier = info.get_tier(bid['current_bid']) profit_buy_percent = obj.bin_settings[tier]['buy_percent'] max_bin = prices[bid['resource_id']] if strategy != 'acquire': if not use_buy_percent: max_buy = info.round_down( (max_bin * 0.95 * dynamic_profit(obj) - min_profit * obj.bin_settings[tier]['sell_percent']), Global.rounding_tiers[tier]) else: max_buy = info.round_down( (max_bin * profit_buy_percent * dynamic_profit(obj)), Global.rounding_tiers[tier]) else: max_buy = max_bin my_bid = bid['current_bid'] + Global.rounding_tiers[tier] if my_bid <= max_buy: obj.bid(item=bid, amount=my_bid) common_process_transfer_targets(obj, strategy) obj.keep_alive(5) multi_log(obj, 'There are 0 remaining bids to fight for. Processing...') common_process_transfer_targets(obj, strategy)
def process_items(items): for item in items: if item['item_type'] == 'player': price = item['futbin_price'] tier = info.get_tier(price) bin_price = max(250, info.round_down(price * obj.bin_settings[tier]['sell_percent'], Global.rounding_tiers[tier])) if bin_price > 350: start_price = bin_price - obj.bin_settings[tier]['spread'] actions.sell(obj, item, start_price, bin_price) else: actions.send_to_club(obj, item, strategy='bpm') elif item['item_type'] == 'fitness' and 'squad' in item['item_name'].lower(): if settings['keep_squad_fitness']: actions.send_to_club(obj, item, strategy='bpm') else: actions.sell(obj, item, 500, 800) elif item['item_type'] == 'healing': if any(s in item['item_name'].lower() for s in ['all', 'upper', 'foot', 'leg', 'knee', 'arm']): if 'all' in item['item_name'].lower(): actions.sell(obj, item, 250, 500) else: actions.sell(obj, item, 150, 200) else: actions.send_to_club(obj, item, strategy='bpm') elif min_sell_types and item['item_type'] in min_sell_types: actions.sell(obj, item, 150, 200) elif club_types and item['item_type'] in club_types: if item['item_type'] == 'fitness' and 'squad' in item['item_name'].lower(): actions.sell(obj, item, 300, 500) elif item['quality'] != 'bronze' and item['item_type'] != 'staff': actions.sell(obj, item, 150, 200) else: actions.send_to_club(obj, item, strategy='bpm') elif quick_sell_types and item['item_type'] in quick_sell_types: if item['item_type'] == 'training' and 'all' in item['item_name'].lower(): actions.sell(obj, item, 200, 400) else: multi_log(obj, 'Will quick sell {} at the end'.format(item['item_name'])) elif item['item_type'].lower != 'coins' : item['element'].click() obj.driver.find_element_by_xpath(".//*[contains(text(), 'Redeem')]").click() else: multi_log(obj, 'NEW ITEM IN BPM: {}'.format(item), level='warn', notify=True, icon_url=item['image']) obj.keep_alive(Global.micro_max) try: obj.keep_alive(Global.small_max) obj.driver.find_element_by_xpath(".//*[contains(text(), 'Quick Sell') and (contains(text(), 'Item'))]").click() multi_log(obj, 'Quick selling remaining items') obj.keep_alive(Global.small_max) modal = obj.__get_class__('ui-dialog-type-message', as_list=False) modal.find_element_by_xpath(".//*[contains(text(), 'Ok')]").click() obj.location = 'store' except Exception as e: multi_log(obj, e, level='error') obj.keep_alive(Global.small_max)
def coin_transfer_list(obj, lose_coins, players): # List player for 80-90% of max with a bid random few steps below and for 1 day run_transfer_finish = False for i, player in enumerate(players): name = info.get_player_info(player)['name'] tier = info.get_tier(38000) step = Global.rounding_tiers[tier] start_price = info.round_down(int(38000 + (rand(-10, 10) * step)), Global.rounding_tiers[tier]) bin_price = info.round_down(start_price + (rand(6, 10) * step), Global.rounding_tiers[tier]) result = find_player(obj, player) if len(result) == 1: run_transfer_finish = True obj.sell(result[0], start_price, bin_price, duration='1 Day') # Record min bid and bin and time to expire expires = datetime.now() + timedelta(days=1) with open(obj.config_file) as config: new_config = yaml.load(config) new_player = { 'asset_id': player, 'start_price': start_price, 'bin_price': bin_price, 'expires': expires, 'lose_coins': lose_coins } try: new_config['coin_transfer']['players'].append(new_player) except AttributeError: new_config['coin_transfer']['players'] = [] new_config['coin_transfer']['players'].append(new_player) with open(obj.config_file, 'w') as update: yaml.dump(new_config, update) else: multi_log(obj, 'Error finding player {} for coin transfer'.format(name), level='error', notify=True, title='Coin Transfer Error') if run_transfer_finish: # Start buy script that runs in background coin_transfer_finish_prep.prep(obj.bot_number, lose_coins) multi_log(obj, 'Waiting for coin transfer to finish in the background.') obj.location = 'home' else: multi_log(obj, 'Something went wrong with coin transferring and there were no players to list.', level='error', notify=True, title='Coin Transfer Error')
def check_transfer_targets(return_data): if obj.location != 'transfer_targets': obj.go_to('transfer_targets') multi_log(obj, 'Waiting on last bid to expire') while True: max_expire = 0 watched_items = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Watched Items')]", gp_type='xpath', get_price=False) if len(watched_items) == 0: break for item in watched_items: if item['time_left'] > max_expire: max_expire = item['time_left'] obj.keep_alive(max_expire + 5) expired_bids = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Expired Items')]", gp_type='xpath', get_price=False) expired = {} for expired_bid in expired_bids: if expired_bid['asset_id'] in settings['players']: if expired_bid['asset_id'] not in list(expired.keys()): expired[expired_bid['asset_id']] = { 'bid_amounts': 0, 'num_results': 0 } expired[expired_bid['asset_id']]['bid_amounts'] += expired_bid[ 'current_bid'] expired[expired_bid['asset_id']]['num_results'] += 1 for asset, data in expired.items(): return_data[asset]['average_bid'] = info.round_down( data['bid_amounts'] / data['num_results'], rounding) for return_asset, return_info in return_data.items(): name = info.get_player_info(return_asset, False)['name'] multi_log( obj, '{}\'s Average Bid: {}'.format(name, return_info['average_bid'])) database.save_market_data(obj, name, return_info['asset_id'], return_info['average_bid'], return_info['minimum_bin']) obj.clear_expired() return {}, 0
def silver_flip(obj): def check_transfer_targets(): if obj.location != 'transfer_targets': obj.go_to('transfer_targets') multi_log(obj, 'Waiting on last bid to expire') while True: max_expire = 0 watched_items = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Watched Items')]", gp_type='xpath', get_price=False) if len(watched_items) == 0: break for item in watched_items: if item['time_left'] > max_expire: max_expire = item['time_left'] obj.keep_alive(max_expire + 5) expired_bids = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Expired Items')]", gp_type='xpath', get_price=False) expired = {} for expired_bid in expired_bids: if expired_bid['asset_id'] not in list(expired.keys()): expired[expired_bid['asset_id']] = { 'bid_amounts': 0, 'num_results': 0 } expired[expired_bid['asset_id']]['bid_amounts'] += expired_bid[ 'current_bid'] expired[expired_bid['asset_id']]['num_results'] += 1 return_players = [] for asset, data in expired.items(): futbin_price = info.get_price(asset) tier = info.get_tier(futbin_price) rounding = Global.rounding_tiers[tier] average_bid = info.round_down( data['bid_amounts'] / data['num_results'], rounding) coins_from_sale = futbin_price * 0.95 potential_profit = coins_from_sale - average_bid if settings[ 'use_buy_percent'] and potential_profit >= coins_from_sale - ( futbin_price * obj.bin_settings['buy_percent']): return_players.append({ 'asset_id': asset, 'name': info.get_player_info(asset, False)['name'], 'bid': average_bid, 'futbin': futbin_price }) elif potential_profit >= settings['min_profit']: return_players.append({ 'asset_id': asset, 'name': info.get_player_info(asset, False)['name'], 'bid': average_bid, 'futbin': futbin_price }) for player_data in return_players: name = info.get_player_info(player_data['asset_id'], False)['name'] multi_log( obj, '{}\'s Average Bid: {} | Futbin price: {}'.format( name, player_data['bid'], player_data['futbin'])) obj.clear_expired() return return_players obj.current_strategy = 'Silver Flip' temp_settings = obj.strategy_settings['silver_flip'] min_price = temp_settings['min_price'] max_price = temp_settings['max_price'] max_results = temp_settings['max_results'] market_monitor = temp_settings['market_monitor'] players = temp_settings['players'] remove_keys = [ 'max_iterations', 'min_price', 'max_price', 'market_monitor', 'players', 'max_results' ] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} multi_log(obj, 'Silver Flipping...', level='title') # Get market information bid_players = [] if len(players) == 0 or market_monitor['refresh']: obj.strategy_settings['silver_flip']['players'] = [] for league in market_monitor['leagues']: iterations = 0 multi_log(obj, 'Getting market data for {}.'.format(league)) while iterations < market_monitor['iterations']: full = False bid_results = obj.search(search_type='Players', quality='Silver', league=league, min_buy=min_price, max_buy=max_price) iterations += 1 for bid_result in bid_results: if bid_result['time_left'] <= market_monitor[ 'max_time_left'] and bid_result[ 'current_bid'] != bid_result['start_price']: bid_result['element'].click() obj.keep_alive(Global.micro_min) err = obj.__check_for_errors__() if err == 'limit': full = True break side_panel = obj.__get_class__('DetailView', as_list=False) try: side_panel.find_element_by_class_name( 'watch').click() err = obj.__check_for_errors__() if err == 'limit': full = True break except (ElementNotVisibleException, TimeoutException, NoSuchElementException): pass while not full: try: nav_bar = obj.__get_class__('pagingContainer', as_list=False) except (ElementNotVisibleException, NoSuchElementException, TimeoutException): nav_bar = obj.__get_class__('mainHeader', as_list=False) try: next_btn = nav_bar.find_element_by_class_name('next') obj.__click_element__(next_btn) bid_results = obj.__get_items__() least_time_left = 99999999 for bid_result in bid_results: if bid_result['time_left'] <= market_monitor[ 'max_time_left'] and bid_result[ 'current_bid'] != bid_result[ 'start_price']: bid_result['element'].click() obj.keep_alive(Global.micro_max) err = obj.__check_for_errors__() if err == 'limit': full = True break side_panel = obj.__get_class__('DetailView', as_list=False) try: side_panel.find_element_by_class_name( 'watch').click() err = obj.__check_for_errors__() if err == 'limit': full = True break except (ElementNotVisibleException, TimeoutException, NoSuchElementException): pass if bid_result['time_left'] < least_time_left: least_time_left = bid_result['time_left'] except (ElementNotVisibleException, NoSuchElementException, TimeoutException): break if full or least_time_left > market_monitor[ 'max_time_left']: break temp_players = check_transfer_targets() for temp_player in temp_players: if temp_players not in players: bid_players.append(temp_player) else: with open(obj.config_file) as config: old_config = yaml.load(config) bid_players = old_config['strategy_settings']['silver_flip'][ 'players'] # Get BIN info if futbin update is too late for bid_player in bid_players: max_bin, update = info.get_price(bid_player['asset_id'], obj, return_updated=True) tier = info.get_tier(max_bin) rounding = Global.rounding_tiers[tier] now = datetime.now() last_update = bid_player.get('last_update', None) if last_update: difference = (now - last_update).seconds else: difference = (now - now - timedelta(hours=99)).seconds if update > settings['max_futbin_update'] and update < difference: multi_log( obj, 'Price data for {} out of date. Getting current price...'. format(info.get_player_info(bid_player['asset_id'])['name'])) num_results = 0 total_bins = 0 bin_with_results = [] while num_results < 3: bin_results = obj.search(search_type='Players', player=bid_player['asset_id'], max_bin=max_bin) if len(bin_results) > max_results: if total_bins == 0: min_bin = 999999 for bin_result in bin_results: if bin_result['buy_now_price'] < min_bin: min_bin = bin_result[ 'buy_now_price'] - Global.rounding_tiers[ tier] max_bin = min_bin continue else: for bin_result in bin_results: if bin_result[ 'buy_now_price'] not in bin_with_results: total_bins += bin_result['buy_now_price'] num_results += 1 if len(bin_results) > 0: bin_with_results.append(max_bin) elif len(bin_results) == 0: max_bin += rounding * 2 else: for bin_result in bin_results: if bin_result['buy_now_price'] not in bin_with_results: total_bins += bin_result['buy_now_price'] num_results += 1 max_bin += rounding if len(bin_results) > 0: bin_with_results.append(max_bin) minimum_bin = info.round_down(total_bins / num_results, rounding) bid_player['minimum_bin'] = minimum_bin bid_player['last_update'] = datetime.now() else: bid_player['minimum_bin'] = max_bin coins_from_sale = bid_player['minimum_bin'] * 0.95 potential_profit = coins_from_sale - bid_player['bid'] current_players = [] if bid_player['asset_id'] not in current_players: current_players.append(bid_player['asset_id']) if settings['use_buy_percent']: if potential_profit >= coins_from_sale - ( bid_player['minimum_bin'] * obj.bin_settings['buy_percent']): players.append(bid_player) else: if potential_profit >= settings['min_profit']: players.append(bid_player) with open(obj.config_file) as config: new_config = yaml.load(config) new_config['strategy_settings']['silver_flip']['players'] = players with open(obj.config_file, 'w') as update: yaml.dump(new_config, update) total_bids = 0 # Search and bid for player in players: futbin_price = player['minimum_bin'] if futbin_price > 0: if obj.get_credits( ) > futbin_price and min_price <= futbin_price <= max_price: hunt_criteria = { 'search_type': 'Players', 'player': player['asset_id'], 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } num_bids = common_hunt(obj=obj, name=info.get_player_info( hunt_criteria['player'], False)['name'], price=futbin_price, hunt_criteria=hunt_criteria, strategy='silver_flip', **settings) if num_bids == 'limit': common_wait_to_expire(obj=obj, strategy='hunt') else: total_bids += num_bids if total_bids > 0: if not settings['use_max_buy']: common_fight(obj=obj, strategy='silver_flip', settings=settings) else: common_wait_to_expire(obj=obj, strategy='silver_flip')
def price_fix(obj): obj.current_strategy = 'Price Fix' settings = obj.strategy_settings['price_fix'] snipe_settings = settings['snipe'] hunt_settings = settings['hunt'] players = settings['players'] multi_log(obj, 'Price-fixing Players...', level='title') bids = 0 for num, player in players.items(): name = info.get_player_info(player['asset_id'], False)['name'] futbin_price = info.get_price(player['asset_id'], obj, False) if futbin_price > player['sell_price']: multi_log( obj, '{} price of {} is too low. Their Futbin price is {}'.format( name, player['sell_price'], futbin_price), level='warn') continue max_bin = player['sell_price'] tier = info.get_tier(max_bin) if settings['use_buy_percent']: max_bin = min( futbin_price, info.round_down( max_bin * obj.bin_settings[tier]['buy_percent'], Global.rounding_tiers[tier])) else: max_bin = info.round_down( (player['sell_price'] * 0.95) - settings['min_profit'], Global.rounding_tiers[tier]) sell_price = player['sell_price'] snipe_criteria = { 'search_type': 'Players', 'player': player['asset_id'], 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, } common_snipe(obj=obj, snipe_criteria=snipe_criteria, name=name, strategy='price_fix', price=max_bin, sell_price=sell_price, **snipe_settings) if obj.get_credits() > max_bin: num_bids = common_hunt(obj=obj, name=name, hunt_criteria=snipe_criteria, strategy='price_fix', price=max_bin, **hunt_settings) if num_bids == 'limit': common_wait_to_expire(obj=obj, strategy='price_fix', sell_price=sell_price) else: bids += num_bids if bids > 0: common_wait_to_expire(obj=obj, strategy='price_fix', sell_price=sell_price) bids = 0
def market_monitor(obj): def check_transfer_targets(return_data): if obj.location != 'transfer_targets': obj.go_to('transfer_targets') multi_log(obj, 'Waiting on last bid to expire') while True: max_expire = 0 watched_items = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Watched Items')]", gp_type='xpath', get_price=False) if len(watched_items) == 0: break for item in watched_items: if item['time_left'] > max_expire: max_expire = item['time_left'] obj.keep_alive(max_expire + 5) expired_bids = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Expired Items')]", gp_type='xpath', get_price=False) expired = {} for expired_bid in expired_bids: if expired_bid['asset_id'] in settings['players']: if expired_bid['asset_id'] not in list(expired.keys()): expired[expired_bid['asset_id']] = { 'bid_amounts': 0, 'num_results': 0 } expired[expired_bid['asset_id']]['bid_amounts'] += expired_bid[ 'current_bid'] expired[expired_bid['asset_id']]['num_results'] += 1 for asset, data in expired.items(): return_data[asset]['average_bid'] = info.round_down( data['bid_amounts'] / data['num_results'], rounding) for return_asset, return_info in return_data.items(): name = info.get_player_info(return_asset, False)['name'] multi_log( obj, '{}\'s Average Bid: {}'.format(name, return_info['average_bid'])) database.save_market_data(obj, name, return_info['asset_id'], return_info['average_bid'], return_info['minimum_bin']) obj.clear_expired() return {}, 0 check_sleep(obj) obj.current_strategy = 'Market Monitor' settings = obj.strategy_settings['market_monitor'] multi_log(obj, 'Monitoring Market...', level='title') obj.clear_expired() cumulative_bids = 0 return_data = {} for player in settings['players']: return_data[player] = { 'asset_id': player, 'minimum_bin': 0, 'average_bid': 0 } num_results = 0 total_bins = 0 player_info = info.get_player_info(player, include_futbin_price=True) name = player_info['name'] futbin_price = player_info['futbin_price'] tier = info.get_tier(futbin_price) rounding = Global.rounding_tiers[tier] max_bin = futbin_price - (rounding * 2) search_criteria = { 'search_type': 'Players', 'player': player, } multi_log( obj, 'Getting market data for {}. Futbin price: {}'.format( name, futbin_price)) # Get bin info bin_with_results = [] while num_results < settings['min_results']: bin_results = actions.search(obj=obj, max_bin=max_bin, **search_criteria) if len(bin_results) > settings['max_results']: if total_bins == 0: min_bin = 999999 for bin_result in bin_results: if bin_result['buy_now_price'] < min_bin: min_bin = bin_result[ 'buy_now_price'] - Global.rounding_tiers[tier] max_bin = min_bin continue else: for bin_result in bin_results: if bin_result['buy_now_price'] not in bin_with_results: total_bins += bin_result['buy_now_price'] num_results += 1 if len(bin_results) > 0: bin_with_results.append(max_bin) else: for bin_result in bin_results: if bin_result['buy_now_price'] not in bin_with_results: total_bins += bin_result['buy_now_price'] num_results += 1 if len(bin_results) > 0: bin_with_results.append(max_bin) max_bin += rounding minimum_bin = info.round_down(total_bins / num_results, rounding) multi_log(obj, '{}\'s Average Minimum BIN: {}'.format(name, minimum_bin)) return_data[player]['minimum_bin'] = minimum_bin # Get bid info max_buy = max(minimum_bin + (5 * rounding), futbin_price + (3 * rounding)) num_results = 0 bid_results = actions.search(obj=obj, max_buy=max_buy, **search_criteria) for bid_result in bid_results: if bid_result['time_left'] <= 300 and ( bid_result['current_bid'] != bid_result['start_price'] or bid_result['current_bid'] <= (futbin_price - (5 * rounding))) and num_results < settings['min_results']: try: bid_result['element'].click() except WebDriverException: try: obj.__click_xpath__(".//*[contains(text(), 'OK')]") except TimeoutException: pass check_transfer_targets(return_data) obj.keep_alive(Global.micro_min) side_panel = obj.__get_class__('DetailView', as_list=False) try: side_panel.find_element_by_class_name('watch').click() num_results += 1 cumulative_bids += 1 except (ElementNotVisibleException, TimeoutException, NoSuchElementException): pass except WebDriverException: obj.__click_xpath__(".//*[contains(text(), 'OK')]") check_transfer_targets(return_data) elif num_results >= settings['min_results']: break check_transfer_targets(return_data)
def relist_individually(obj, at_market=False, duration='1 Hour'): obj.current_strategy = 'Relist Individually' settings = obj.strategy_settings['relist_individually'] if settings['above_bin'] and settings['below_bin']: multi_log(obj, 'Cannot relist players. Settings file has both below_bin and above_bin set to True.', level='error') return 1 if obj.location != 'transfer_list': obj.go_to('transfer_list') while True: expired = obj.__get_items__(p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Unsold Items')]", gp_type='xpath', get_price=True) if len(expired) == 0: break for item in expired: if item['item_type'] == 'player': if at_market: futbin_price = item['futbin_price'] tier = info.get_tier(futbin_price) level = 'green' if settings['below_bin']: futbin_price = info.round_down(futbin_price * obj.bin_settings[tier]['sell_percent'], Global.rounding_tiers[tier]) level = 'warn' elif settings['above_bin']: new_price = (item['buy_now_price'] + futbin_price) / 2 tier = info.get_tier(new_price) futbin_price = max(futbin_price, info.round_down(new_price, Global.rounding_tiers[tier])) level = 'warn' tier = info.get_tier(futbin_price) start_price = futbin_price - obj.bin_settings[tier]['spread'] multi_log(obj=obj, message='Relisting {} for {}. Was previously {}'.format(item['item_name'], futbin_price, item['buy_now_price']), level=level) else: futbin_price = item['buy_now_price'] start_price = item['start_price'] try: obj.relist_item(item, start_price, futbin_price, duration) except TimeoutException: pass else: obj.relist_item(item, item['start_price'], item['buy_now_price'], duration) obj.keep_alive(Global.micro_min) break try: obj.rate_limit() obj.__click_xpath__("//*[contains(text(), 'Re-list All')]", timeout=Global.small_min * 2) obj.__click_xpath__("//*[contains(text(), 'Yes')]", timeout=Global.small_min * 2) multi_log(obj, 'Items re-listed') obj.go_to('transfers') except TimeoutException: pass if duration == '1 Hour' and obj.settings['night_mode']['need_relist']: from ruamel.yaml import YAML yaml = YAML() yaml.explicit_start = True yaml.indent(mapping=4) yaml.preserve_quotes = True need_relisting = False active_transfers = obj.__get_items__(p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Active Transfers')]", gp_type='xpath', get_price=False) for active in active_transfers: if active['time_left'] > 3601: need_relisting = True break if not need_relisting: with open(obj.config_file) as config: new_config = yaml.load(config) new_config['settings']['night_mode']['need_relist'] = False with open(obj.config_file, 'w') as update: yaml.dump(new_config, update)
def bid_on_results(results, num_bids, max_buy): if len(results) > 0: to_bid = [] for r in results: if min_time_left <= r['time_left'] <= max_time_left and (r['current_bid'] + Global.rounding_tiers[tier] <= max_buy or (r['current_bid'] == r['start_price'] and r['start_price'] <= max_buy)) and \ (hunt_criteria['search_type'].lower() != 'players' or ((not include and hunt_criteria['player'] == r['resource_id']) or (r['resource_id'] in include))): to_bid.append(r) if len(to_bid) == 0: multi_log(obj, 'Nothing worth bidding on', level='yellow') else: if use_max_buy: sorted_bids = sorted(to_bid, key=itemgetter('time_left')) else: sorted_bids = sorted(to_bid, key=itemgetter('current_bid')) for item in sorted_bids: try: futbin_price, updated = info.get_price( item['resource_id'], return_updated=True) if updated > max_futbin_update: continue result_tier = info.get_tier(futbin_price) result_buy_percent = obj.bin_settings[result_tier][ 'buy_percent'] if strategy != 'acquire' and strategy != 'price_fix': if not use_buy_percent: max_buy = info.round_down( (futbin_price * 0.95 * dynamic_profit(obj) * obj.bin_settings[result_tier] ['sell_percent']) - min_profit, Global.rounding_tiers[result_tier]) else: max_buy = info.round_down( (futbin_price * result_buy_percent * dynamic_profit(obj)), Global.rounding_tiers[result_tier]) except (KeyError, TypeError): continue if num_bids < max_item_bids: if use_max_buy: my_bid = max_buy elif strategy == 'acquire' and not use_max_buy: my_bid = max_buy - ( 2 * obj.bin_settings[result_tier]['spread']) else: my_bid = min( max_buy, item['current_bid'] + Global.rounding_tiers[result_tier]) if item['current_bid'] + Global.rounding_tiers[ result_tier] <= my_bid or ( item['current_bid'] == item['start_price'] and item['current_bid'] <= my_bid): try: bid_result = obj.bid(item, my_bid) if bid_result == 'limit': return 'limit' elif bid_result: num_bids += 1 if num_bids >= max_item_bids: break except StaleElementReferenceException: pass except Exception as e: multi_log(obj, '[{}]: Hunt BID error: {}'.format( strategy, e), level='error') continue else: multi_log( obj, 'HUNT PRICING ERROR: STRATEGY: {} | r[bnp]: {} | max: {} | len(res): {} |\ crit[type]: {} | player: {} | result: {}' .format(strategy, item['buy_now_price'], my_bid, len(search_results), hunt_criteria['search_type'], hunt_criteria['player'], item['resource_id']), level='debug') return num_bids
def common_hunt(obj, name, hunt_criteria, strategy, price=0, max_item_bids=10, max_futbin_update=259200, min_time_left=30, max_time_left=420, use_buy_percent=True, min_profit=250, fight=False, use_max_buy=True, max_prp=None, sell_acquired_if_full=True, prices_dict=None): """ hunt_criteria = { 'search_type': 'Players', 'player': player_id, 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } """ def bid_on_results(results, num_bids, max_buy): if len(results) > 0: to_bid = [] for r in results: if min_time_left <= r['time_left'] <= max_time_left and (r['current_bid'] + Global.rounding_tiers[tier] <= max_buy or (r['current_bid'] == r['start_price'] and r['start_price'] <= max_buy)) and \ (hunt_criteria['search_type'].lower() != 'players' or ((not include and hunt_criteria['player'] == r['resource_id']) or (r['resource_id'] in include))): to_bid.append(r) if len(to_bid) == 0: multi_log(obj, 'Nothing worth bidding on', level='yellow') else: if use_max_buy: sorted_bids = sorted(to_bid, key=itemgetter('time_left')) else: sorted_bids = sorted(to_bid, key=itemgetter('current_bid')) for item in sorted_bids: try: futbin_price, updated = info.get_price( item['resource_id'], return_updated=True) if updated > max_futbin_update: continue result_tier = info.get_tier(futbin_price) result_buy_percent = obj.bin_settings[result_tier][ 'buy_percent'] if strategy != 'acquire' and strategy != 'price_fix': if not use_buy_percent: max_buy = info.round_down( (futbin_price * 0.95 * dynamic_profit(obj) * obj.bin_settings[result_tier] ['sell_percent']) - min_profit, Global.rounding_tiers[result_tier]) else: max_buy = info.round_down( (futbin_price * result_buy_percent * dynamic_profit(obj)), Global.rounding_tiers[result_tier]) except (KeyError, TypeError): continue if num_bids < max_item_bids: if use_max_buy: my_bid = max_buy elif strategy == 'acquire' and not use_max_buy: my_bid = max_buy - ( 2 * obj.bin_settings[result_tier]['spread']) else: my_bid = min( max_buy, item['current_bid'] + Global.rounding_tiers[result_tier]) if item['current_bid'] + Global.rounding_tiers[ result_tier] <= my_bid or ( item['current_bid'] == item['start_price'] and item['current_bid'] <= my_bid): try: bid_result = obj.bid(item, my_bid) if bid_result == 'limit': return 'limit' elif bid_result: num_bids += 1 if num_bids >= max_item_bids: break except StaleElementReferenceException: pass except Exception as e: multi_log(obj, '[{}]: Hunt BID error: {}'.format( strategy, e), level='error') continue else: multi_log( obj, 'HUNT PRICING ERROR: STRATEGY: {} | r[bnp]: {} | max: {} | len(res): {} |\ crit[type]: {} | player: {} | result: {}' .format(strategy, item['buy_now_price'], my_bid, len(search_results), hunt_criteria['search_type'], hunt_criteria['player'], item['resource_id']), level='debug') return num_bids check_sleep(obj) include = hunt_criteria.get('include', []) if not include: include = [] if (hunt_criteria.get('player', False) and int(hunt_criteria['player']) <= 300000) and (hunt_criteria['quality'] and hunt_criteria['quality'].lower() == 'special'): special_ids = info.get_special_ids(hunt_criteria['player']) for s in list(special_ids.values()): if int(s) >= 300000: include.append(s) include.append(info.get_base_id(hunt_criteria['player'])) include.append(hunt_criteria.get('player', None)) else: bids = 0 if hunt_criteria.get('player', False) and price == 0: price_data = info.get_price(hunt_criteria['player'], obj=obj, return_updated=True, return_prp=True) if price_data == 0: return 0 price = price_data[0] updated = price_data[1] prp = price_data[2] else: updated = None prp = None if obj.get_credits() > price and (not updated or updated <= max_futbin_update) and ( not max_prp or prp <= max_prp): tier = info.get_tier(price) profit_buy_percent = obj.bin_settings[tier]['buy_percent'] if hunt_criteria.get('max_buy', None): price = hunt_criteria['max_buy'] hunt_criteria = { k: v for k, v in hunt_criteria.items() if k != 'max_buy' } else: price = info.round_down(price, Global.rounding_tiers[tier]) if strategy != 'acquire' and strategy != 'price_fix' and 'consumable' not in strategy: if not use_buy_percent: max_buy = info.round_down( (price * 0.95 * dynamic_profit(obj) * obj.bin_settings[tier]['sell_percent']) - min_profit, Global.rounding_tiers[tier]) else: max_buy = info.round_down( (price * profit_buy_percent * dynamic_profit(obj)), Global.rounding_tiers[tier]) else: max_buy = price multi_log( obj, '[{}]: Hunting for {} at {}.'.format(strategy.title(), name, max_buy)) longest_time_left = 0 hunt_criteria = { k: v for k, v in hunt_criteria.items() if k != 'max_buy' } search_results = obj.search(max_buy=max_buy, **hunt_criteria) while longest_time_left < min_time_left: if len(search_results) == 0: multi_log(obj, 'Nothing worth bidding on', level='yellow') break else: longest_time_left = search_results[-1]['time_left'] if longest_time_left < min_time_left: try: nav_bar = obj.__get_class__('pagingContainer', as_list=False) except (ElementNotVisibleException, NoSuchElementException, TimeoutException): nav_bar = obj.__get_class__('mainHeader', as_list=False) try: next_btn = nav_bar.find_element_by_class_name('next') obj.__click_element__(next_btn) obj.keep_alive(Global.micro_max) search_results = obj.__get_items__(get_price=True) except (ElementNotVisibleException, NoSuchElementException, TimeoutException, StaleElementReferenceException): break else: break bids = bid_on_results(search_results, bids, max_buy) if bids == 'limit': return 'limit' elif type(bids) is str: return bids while bids < max_item_bids and longest_time_left <= max_time_left: try: nav_bar = obj.__get_class__('pagingContainer', as_list=False) except (ElementNotVisibleException, NoSuchElementException, TimeoutException): nav_bar = obj.__get_class__('mainHeader', as_list=False) try: next_btn = nav_bar.find_element_by_class_name('next') errors = obj.__check_for_errors__() if errors == 'limit': return 'limit' obj.__click_element__(next_btn) obj.keep_alive(Global.micro_max) search_results = obj.__get_items__(get_price=True) least_time_left = search_results[0]['time_left'] longest_time_left = search_results[-1]['time_left'] if least_time_left > max_time_left: break amt_bids = bid_on_results(search_results, bids, max_buy) if amt_bids == 'limit': return 'limit' else: try: bids += amt_bids except TypeError: pass if longest_time_left > max_time_left: break except (ElementNotVisibleException, NoSuchElementException, TimeoutException): break print(' ') if fight: common_fight(obj, strategy, use_buy_percent, min_profit) return bids
def buy_results(search_results, bought, let_items_refresh, price, max_bin): if 0 < len(search_results) <= max_results: if len(search_results) > 0 and strategy == 'acquire': sorted_results = sorted(search_results, key=itemgetter('buy_now_price')) search_results = sorted_results else: sorted_results = search_results[::-1] search_results = sorted_results for result in search_results: if prices_dict: try: price = prices_dict[result['resource_id']] except KeyError: break if not use_buy_percent: max_bin = info.round_down( (price * 0.95 * dynamic_profit(obj) * obj.bin_settings[tier]['sell_percent']) - min_profit, Global.rounding_tiers[tier]) else: max_bin = info.round_down( (price * profit_buy_percent * dynamic_profit(obj)), Global.rounding_tiers[tier]) if bought < max_item_buys and result['buy_now_price'] <= max_bin and len(search_results) <= max_results \ and (snipe_criteria['search_type'].lower() != 'players' or ((not include and snipe_criteria['player'] == result['resource_id']) or (include and result['resource_id'] in include)) or (not include and not snipe_criteria['player'])): # Buy try: if not sell_price: result_bought = obj.buy_now( result, strategy=strategy, expected_profit=( (price * 0.95 * obj.bin_settings[tier]['sell_percent']) - result['buy_now_price'])) else: result_bought = obj.buy_now( result, strategy=strategy, expected_profit=( (sell_price * 0.95 * obj.bin_settings[tier]['sell_percent']) - result['buy_now_price'])) if result_bought: bought += 1 let_items_refresh = obj.settings[ 'pause_after_successful_snipe'] if bought % 5 == 0: sell_players(obj, bought) else: if let_items_refresh == 0: let_items_refresh = obj.settings[ 'pause_after_unsuccessful_snipe'] multi_log(obj, '[{}]: Got out-sniped for: {}'.format( strategy, result['item_name']), level='warn') except Exception as e: multi_log(obj, '[{}]: Snipe BUY error: {}'.format( strategy, e), level='error') continue else: multi_log( obj, 'SNIPE PRICING ERROR: STRATEGY: {} | bought: {} | max: {} | r[bnp]: {} | max: {} | len(res): {} |\ crit[type]: {} | player: {} | result: {}'. format(strategy, bought, max_item_buys, result['buy_now_price'], max_bin, len(search_results), snipe_criteria['search_type'], snipe_criteria['player'], result['resource_id']), level='debug') return bought, let_items_refresh
def sell_players(o, b): if prices_dict: o.go_to('unassigned') finished_items = o.__get_items__(get_price=True) for item in finished_items: if sell_acquired_if_full: if strategy != 'acquire': # Sell bought players if b > 0: if snipe_criteria['player']: if item['resource_id'] == str( snipe_criteria['player'] ) and item['bid_status'] == 'won': if not sell_price: sell_tier = info.get_tier( item['futbin_price']) bin_price = info.round_down( item['futbin_price'] * o.bin_settings[sell_tier] ['sell_percent'], Global.rounding_tiers[tier]) else: bin_price = sell_price player_tier = info.get_tier(bin_price) start_price = bin_price - o.bin_settings[ player_tier]['spread'] sell_result = o.sell(item, start_price, bin_price) if sell_result == 'full': common_deal_with_full_transfer_list( o, strategy) elif (not include or item['resource_id'] in include) and item['bid_status'] == 'won': player_tier = info.get_tier(item['futbin_price']) if not sell_price: bin_price = info.round_down( item['futbin_price'] * o.bin_settings[player_tier] ['sell_percent'], Global.rounding_tiers[tier]) else: bin_price = sell_price start_price = bin_price - o.bin_settings[ player_tier]['spread'] sell_result = o.sell(item, start_price, bin_price) if sell_result == 'full': common_deal_with_full_transfer_list( o, strategy) else: if item['bid_status'] == 'won': send_result = o.send_to_club(item=item, strategy='acquire') if send_result == 'owned': futbin_price = info.get_price( item['resource_id'], o) player_tier = info.get_tier(futbin_price) bin_price = info.round_down( item['futbin_price'] * o.bin_settings[player_tier]['sell_percent'], Global.rounding_tiers[tier]) spread = o.bin_settings[player_tier]['spread'] sell_result = o.sell(item=item, start_price=bin_price - spread, bin_price=bin_price) if sell_result == 'full': common_deal_with_full_transfer_list( o, strategy) o.keep_alive(Global.micro_min) return bought elif snipe_criteria['player'] and item['resource_id'] == str( snipe_criteria['player']) and item['bid_status'] == 'won': obj.send_to_transfer_list(item) o.keep_alive(Global.micro_max)
def common_snipe(obj, name, snipe_criteria, strategy, price=0, max_item_buys=10, max_tries=10, max_futbin_update=60 * 60 * 24 * 3, max_results=5, use_buy_percent=False, min_profit=300, sell_price=None, max_prp=None, sell_acquired_if_full=True, prices_dict=None): """ snipe_criteria = { 'search_type': 'Players', 'player': player_id, 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } """ def sell_players(o, b): if prices_dict: o.go_to('unassigned') finished_items = o.__get_items__(get_price=True) for item in finished_items: if sell_acquired_if_full: if strategy != 'acquire': # Sell bought players if b > 0: if snipe_criteria['player']: if item['resource_id'] == str( snipe_criteria['player'] ) and item['bid_status'] == 'won': if not sell_price: sell_tier = info.get_tier( item['futbin_price']) bin_price = info.round_down( item['futbin_price'] * o.bin_settings[sell_tier] ['sell_percent'], Global.rounding_tiers[tier]) else: bin_price = sell_price player_tier = info.get_tier(bin_price) start_price = bin_price - o.bin_settings[ player_tier]['spread'] sell_result = o.sell(item, start_price, bin_price) if sell_result == 'full': common_deal_with_full_transfer_list( o, strategy) elif (not include or item['resource_id'] in include) and item['bid_status'] == 'won': player_tier = info.get_tier(item['futbin_price']) if not sell_price: bin_price = info.round_down( item['futbin_price'] * o.bin_settings[player_tier] ['sell_percent'], Global.rounding_tiers[tier]) else: bin_price = sell_price start_price = bin_price - o.bin_settings[ player_tier]['spread'] sell_result = o.sell(item, start_price, bin_price) if sell_result == 'full': common_deal_with_full_transfer_list( o, strategy) else: if item['bid_status'] == 'won': send_result = o.send_to_club(item=item, strategy='acquire') if send_result == 'owned': futbin_price = info.get_price( item['resource_id'], o) player_tier = info.get_tier(futbin_price) bin_price = info.round_down( item['futbin_price'] * o.bin_settings[player_tier]['sell_percent'], Global.rounding_tiers[tier]) spread = o.bin_settings[player_tier]['spread'] sell_result = o.sell(item=item, start_price=bin_price - spread, bin_price=bin_price) if sell_result == 'full': common_deal_with_full_transfer_list( o, strategy) o.keep_alive(Global.micro_min) return bought elif snipe_criteria['player'] and item['resource_id'] == str( snipe_criteria['player']) and item['bid_status'] == 'won': obj.send_to_transfer_list(item) o.keep_alive(Global.micro_max) def buy_results(search_results, bought, let_items_refresh, price, max_bin): if 0 < len(search_results) <= max_results: if len(search_results) > 0 and strategy == 'acquire': sorted_results = sorted(search_results, key=itemgetter('buy_now_price')) search_results = sorted_results else: sorted_results = search_results[::-1] search_results = sorted_results for result in search_results: if prices_dict: try: price = prices_dict[result['resource_id']] except KeyError: break if not use_buy_percent: max_bin = info.round_down( (price * 0.95 * dynamic_profit(obj) * obj.bin_settings[tier]['sell_percent']) - min_profit, Global.rounding_tiers[tier]) else: max_bin = info.round_down( (price * profit_buy_percent * dynamic_profit(obj)), Global.rounding_tiers[tier]) if bought < max_item_buys and result['buy_now_price'] <= max_bin and len(search_results) <= max_results \ and (snipe_criteria['search_type'].lower() != 'players' or ((not include and snipe_criteria['player'] == result['resource_id']) or (include and result['resource_id'] in include)) or (not include and not snipe_criteria['player'])): # Buy try: if not sell_price: result_bought = obj.buy_now( result, strategy=strategy, expected_profit=( (price * 0.95 * obj.bin_settings[tier]['sell_percent']) - result['buy_now_price'])) else: result_bought = obj.buy_now( result, strategy=strategy, expected_profit=( (sell_price * 0.95 * obj.bin_settings[tier]['sell_percent']) - result['buy_now_price'])) if result_bought: bought += 1 let_items_refresh = obj.settings[ 'pause_after_successful_snipe'] if bought % 5 == 0: sell_players(obj, bought) else: if let_items_refresh == 0: let_items_refresh = obj.settings[ 'pause_after_unsuccessful_snipe'] multi_log(obj, '[{}]: Got out-sniped for: {}'.format( strategy, result['item_name']), level='warn') except Exception as e: multi_log(obj, '[{}]: Snipe BUY error: {}'.format( strategy, e), level='error') continue else: multi_log( obj, 'SNIPE PRICING ERROR: STRATEGY: {} | bought: {} | max: {} | r[bnp]: {} | max: {} | len(res): {} |\ crit[type]: {} | player: {} | result: {}'. format(strategy, bought, max_item_buys, result['buy_now_price'], max_bin, len(search_results), snipe_criteria['search_type'], snipe_criteria['player'], result['resource_id']), level='debug') return bought, let_items_refresh check_sleep(obj) include = snipe_criteria.get('include', []) if not include: include = [] if (snipe_criteria['player'] and int(snipe_criteria['player']) <= 300000 ) or (snipe_criteria['quality'] and snipe_criteria['quality'].lower() == 'special'): if include: special_ids = {} for i in include: add_ids = info.get_special_ids(i) for k, v in add_ids.items(): special_ids[k] = v elif snipe_criteria['player']: special_ids = info.get_special_ids(snipe_criteria['player']) for s in list(special_ids.values()): include.append(s) bought = 0 if not prices_dict: if snipe_criteria['player'] and price == 0: price_data = info.get_price(snipe_criteria['player'], obj=obj, return_updated=True, return_prp=True) if price_data == 0: return 0 price = price_data[0] updated = price_data[1] prp = price_data[2] else: # TODO: Update this when implementing non-player searches prp = None updated = None else: if not price: price = max(list(prices_dict.values())) updated = None prp = None max_results = 9999999 if obj.get_credits() > price and (not updated or updated <= max_futbin_update) and ( not max_prp or prp <= max_prp): tier = info.get_tier(price) profit_buy_percent = obj.bin_settings[tier]['buy_percent'] if strategy != 'acquire' and strategy != 'price_fix': if not use_buy_percent: max_bin = info.round_down( (price * 0.95 * dynamic_profit(obj) * obj.bin_settings[tier]['sell_percent']) - min_profit, Global.rounding_tiers[tier]) else: max_bin = info.round_down( (price * profit_buy_percent * dynamic_profit(obj)), Global.rounding_tiers[tier]) else: max_bin = price multi_log( obj, '[{}]: Sniping for {} at {}.'.format(strategy.title(), name, max_bin)) i = max_tries reset = True while i > 0: let_items_refresh = 0 if i == max_tries: search_results = obj.search(max_bin=max_bin, reset=reset, **snipe_criteria) reset = False elif i == 1: search_results = obj.search(max_bin=max_bin, **snipe_criteria) else: search_results = obj.search(max_bin=max_bin, reset=reset, **snipe_criteria) reset = False if not prices_dict: bought, let_items_refresh = buy_results( search_results, bought, let_items_refresh, price, max_bin) else: while True: try: nav_bar = obj.__get_class__('pagingContainer', as_list=False) except (ElementNotVisibleException, NoSuchElementException, TimeoutException): nav_bar = obj.__get_class__('mainHeader', as_list=False) try: next_btn = nav_bar.find_element_by_class_name('next') obj.__click_element__(next_btn) obj.keep_alive(Global.micro_min) except (ElementNotVisibleException, NoSuchElementException, TimeoutException): break search_results = obj.__get_items__(get_price=False) bought, let_items_refresh = buy_results( search_results, bought, let_items_refresh, price, max_bin) while search_results[1]['time_left'] > 58 * 60: try: nav_bar = obj.__get_class__('pagingContainer', as_list=False) except (ElementNotVisibleException, NoSuchElementException, TimeoutException): nav_bar = obj.__get_class__('mainHeader', as_list=False) try: prev_btn = nav_bar.find_element_by_class_name('prev') obj.__click_element__(prev_btn) obj.keep_alive(Global.micro_min) except (ElementNotVisibleException, NoSuchElementException, TimeoutException): break search_results = obj.__get_items__(get_price=False) bought, let_items_refresh = buy_results( search_results, bought, let_items_refresh, price, max_bin) i -= 1 if len(search_results) > max_results: multi_log( obj, 'Too many results returned. Max BIN is probably set too high' ) return 'too many' elif len(search_results) == 0 and i == 0: multi_log(obj, 'No good deals found', level='yellow') if bought > 0: sell_players(obj, bought) if bought >= max_item_buys: return bought if let_items_refresh > 0: multi_log( obj, 'Pausing to ensure we don\'t try bidding on the same items', level='debug') obj.keep_alive( let_items_refresh ) # Making sure server refreshes results so we don't try buying it again. Can throw an error otherwise reset = True print(' ') return bought
def check_transfer_targets(): if obj.location != 'transfer_targets': obj.go_to('transfer_targets') multi_log(obj, 'Waiting on last bid to expire') while True: max_expire = 0 watched_items = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Watched Items')]", gp_type='xpath', get_price=False) if len(watched_items) == 0: break for item in watched_items: if item['time_left'] > max_expire: max_expire = item['time_left'] obj.keep_alive(max_expire + 5) expired_bids = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Expired Items')]", gp_type='xpath', get_price=False) expired = {} for expired_bid in expired_bids: if expired_bid['asset_id'] not in list(expired.keys()): expired[expired_bid['asset_id']] = { 'bid_amounts': 0, 'num_results': 0 } expired[expired_bid['asset_id']]['bid_amounts'] += expired_bid[ 'current_bid'] expired[expired_bid['asset_id']]['num_results'] += 1 return_players = [] for asset, data in expired.items(): futbin_price = info.get_price(asset) tier = info.get_tier(futbin_price) rounding = Global.rounding_tiers[tier] average_bid = info.round_down( data['bid_amounts'] / data['num_results'], rounding) coins_from_sale = futbin_price * 0.95 potential_profit = coins_from_sale - average_bid if settings[ 'use_buy_percent'] and potential_profit >= coins_from_sale - ( futbin_price * obj.bin_settings['buy_percent']): return_players.append({ 'asset_id': asset, 'name': info.get_player_info(asset, False)['name'], 'bid': average_bid, 'futbin': futbin_price }) elif potential_profit >= settings['min_profit']: return_players.append({ 'asset_id': asset, 'name': info.get_player_info(asset, False)['name'], 'bid': average_bid, 'futbin': futbin_price }) for player_data in return_players: name = info.get_player_info(player_data['asset_id'], False)['name'] multi_log( obj, '{}\'s Average Bid: {} | Futbin price: {}'.format( name, player_data['bid'], player_data['futbin'])) obj.clear_expired() return return_players
def filter_snipe(obj): obj.current_strategy = 'Filter Snipe' temp_settings = obj.strategy_settings['filter_snipe'] filters = temp_settings['filters'] max_price = temp_settings['max_price'] remove_keys = ['max_price', 'filters'] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} multi_log(obj, 'Filter Sniping...', level='title') for f in filters: multi_log(obj, 'Getting filter data...') futbin_url = create_futbin_url(obj, f) obj.new_tab(futbin_url) obj.location = 'futbin' # Grab all data from tables, hit next page until it can't any more, turn data into list of player dicts all_results = parse_futbin_tables(obj, futbin_url, True, False) multi_log(obj, 'Done getting filter data') obj.close_tab() obj.driver.switch_to.window(obj.driver.window_handles[0]) obj.location = 'home' include = [] max_bin = 999999999999 for result in all_results: if result['price'] != 0 and result['resource_id'] not in f.get( 'exclude', []): include.append(result['resource_id']) if result['price'] < max_bin: max_bin = result['price'] tier = info.get_tier(max_bin) if not settings['use_buy_percent']: search_price = info.round_down( (max_bin * 0.95 * dynamic_profit(obj) * obj.bin_settings[tier]['sell_percent']) - settings['min_profit'], Global.rounding_tiers[tier]) else: search_price = info.round_down( (max_bin * obj.bin_settings[tier]['buy_percent'] * dynamic_profit(obj)), Global.rounding_tiers[tier]) if obj.get_credits( ) > max_bin and search_price <= max_bin <= max_price: try: snipe_criteria = { 'search_type': 'Players', 'player': None, 'quality': f.get('quality', None), 'position': f.get('position', None), 'chem_style': f.get('chem_style', None), 'nation': f.get('nation', None), 'league': f.get('league', None), 'club': f.get('club', None), 'include': include, 'exclude': f.get('exclude', None), } except ValueError: continue name = list(f.values()) common_snipe(obj, name=name, snipe_criteria=snipe_criteria, strategy='filter_snipe', price=max_bin, **settings)
def common_process_transfer_targets(obj, strategy, remaining_players=None, acquired=None, sell_price=None, sell_acquired_if_full=True): if obj.location != 'transfer_targets': obj.go_to('transfer_targets') winnings = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Won Items')]", gp_type='xpath', get_price=True) for won in winnings: send_result = '' if strategy == 'acquire': acquired.append((won['item_name'], won['current_bid'])) for i, player_id in enumerate(remaining_players): if str(player_id) == str(won['resource_id']): remaining_players.pop(i) break send_result = obj.send_to_club(item=won, strategy='acquire') multi_log(obj=obj, message='Won {} for {}'.format(won['item_name'], won['current_bid']), level='green', notify=True, title='Item won', icon_url=won['image']) if strategy != 'acquire' or send_result == 'owned' and sell_acquired_if_full: if not sell_price: futbin_price = won['futbin_price'] elif type(sell_price) is dict: futbin_price = sell_price[won['item_name']] else: futbin_price = sell_price tier = info.get_tier(futbin_price) if strategy != 'price_fix': futbin_price = info.round_down( futbin_price * obj.bin_settings[tier]['sell_percent'], Global.rounding_tiers[tier]) else: for num, pf_player in obj.strategy_settings['price_fix'][ 'players'].items(): if str(pf_player['resource_id']) == str( won['resource_id']): futbin_price = pf_player['sell_price'] break start_price = futbin_price - obj.bin_settings[tier]['spread'] multi_log(obj=obj, message='Won {} for {}'.format(won['item_name'], won['current_bid']), level='green', notify=True, title='Item won', icon_url=won['image']) database.bought_sold( obj, won, 'bought', strategy, won['current_bid'], expected_profit=((futbin_price * 0.95 * obj.bin_settings[tier]['sell_percent']) - won['current_bid'])) try: sell_result = obj.sell(won, start_price, futbin_price) if sell_result == 'full': common_deal_with_full_transfer_list(obj, strategy) except TimeoutException: try: obj.__get_xpath__( "//*[contains(text(), 'Transfer list full')]") common_deal_with_full_transfer_list(obj, strategy) except TimeoutException: pass elif send_result == 'owned' and not sell_acquired_if_full: obj.send_to_transfer_list(won) obj.clear_expired() return remaining_players, acquired
def acquire(obj, player_list, futbin_multiplier, increase_each_round=False, max_increases=5, sell_acquired_if_full=True, special_only=False): obj.current_strategy = 'Acquire' snipe_settings = obj.strategy_settings['acquire']['snipe'] hunt_settings = obj.strategy_settings['acquire']['hunt'] if type(player_list) is not list: new = [player_list] player_list = new if special_only: quality = 'Special' else: quality = None multi_log(obj, 'Acquiring Players...', level='title') # Go through player lists remaining_players = player_list acquired = [] iteration = 1 while len(remaining_players) > 0: bids = 0 search_list = [] if iteration > 1: snipe_settings['max_results'] = 9999999 print('{:<30} {:<20} {:<20}'.format('Name', 'Futbin Price', 'Asset ID')) for player in remaining_players: player_info = info.get_player_info(player, include_futbin_price=True) print('{:<30} {:<20} {:<20}'.format(player_info['name'], player_info['futbin_price'], player)) search_list.append(player_info) for player in search_list: name = player['name'] futbin_price = player['futbin_price'] tier = info.get_tier(futbin_price) max_bin = max(200, info.round_down(futbin_price * futbin_multiplier, Global.rounding_tiers[tier])) if increase_each_round: max_bin += Global.rounding_tiers[tier] * iteration include = [] if quality and quality.lower() == 'special' and int(player['asset_id']) <= 300000: special_ids = info.get_special_ids(player['asset_id']) for s in list(special_ids.values()): if int(s) >= 300000: include.append(s) include.append(info.get_base_id(player['asset_id'])) include.append(player.get('asset_id', None)) elif int(player['asset_id']) > 300000: include.append(player['asset_id']) include.append(info.get_base_id(player['asset_id'])) snipe_criteria = { 'search_type': 'Players', 'player': player['asset_id'], 'quality': quality, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': include, 'exclude': None, } snipe_result = common_snipe(obj=obj, snipe_criteria=snipe_criteria, name=name, strategy='acquire', price=max_bin, max_item_buys=1, sell_acquired_if_full=sell_acquired_if_full, **snipe_settings) if snipe_result == 'too many': multi_log(obj, 'Lots of results returned. Trying to get this cheaper by bidding...') max_bin -= Global.rounding_tiers[tier] elif snipe_result > 0: acquired.append((name, max_bin)) for i, player_id in enumerate(remaining_players): if str(player_id) == str(player['asset_id'] or str(player_id) in include): remaining_players.pop(i) break continue if obj.get_credits() > player['futbin_price']: num_bids = common_hunt(obj=obj, name=name, hunt_criteria=snipe_criteria, price=max_bin, strategy='acquire', max_item_bids=1, **hunt_settings) if num_bids == 'limit': common_wait_to_expire(obj, 'acquire', remaining_players, acquired, sell_acquired_if_full=sell_acquired_if_full) break elif num_bids == 'owned' or num_bids == 'sniped': acquired.append((name, max_bin)) for i, player_id in enumerate(remaining_players): if str(player_id) == str(player['asset_id']) or str(player_id) in include: remaining_players.pop(i) break else: bids += num_bids if bids > 0: remaining_players, acquired = common_wait_to_expire(obj, 'acquire', remaining_players, acquired, sell_acquired_if_full=sell_acquired_if_full) if increase_each_round and iteration <= max_increases: iteration += 1 if len(remaining_players) > 0: multi_log(obj, message='Increasing search price by {} step(s)'.format(min(iteration, max_increases))) multi_log(obj, message='Got all players!', level='green', notify=True, title='DONE') print('Acquired:') print('-' * 50) print('{:<30} {:<6}'.format('Name', 'Price')) for player in acquired: print('{:<30} {:<6}'.format(player[0], player[1])) return 'done'
def sell_club_players(obj, search='all', min_sell_bronze=300, min_sell_silver=400, min_sell_gold=800, rare_multiplier=1.35, exclude=None): obj.current_strategy = 'Sell Club Players' if not exclude: exclude = [] if obj.location != 'players': obj.go_to('players') if search != 'all': search_button = obj.__get_class__('searchAction', as_list=False) obj.__click_element__(search_button) search = search.title() search_panel = obj.__get_class__('searchContainer', as_list=False) quality_dropdown = search_panel.find_element_by_xpath(".//*[contains(text(), 'Quality')]") obj.__click_element__(quality_dropdown) quality_parent = quality_dropdown.find_element_by_xpath('..') obj.__check_for_errors__() quality_parent.find_element_by_xpath(".//*[contains(text(), '{}')]".format(search)).click() button_bar = obj.__get_class__('layout-flex-bar', as_list=False) obj.__click_element__(button_bar.find_element_by_xpath(".//*[contains(text(), 'Search')]")) obj.location = 'club_search_results' multi_log(obj, 'Getting {} club players. This takes approx. 1 minute per 100 players'.format(search)) while True: obj.keep_alive(Global.small_max) page_players = obj.__get_items__(get_price=False) for player in page_players: futbin_data = info.get_price(player['asset_id'], obj, True) if futbin_data != 0: updated = futbin_data[1] price = futbin_data[0] if updated > 8 * 60 * 60 or price == 0: continue if player['quality'] == 'bronze' and price >= min_sell_bronze and player['asset_id'] not in exclude: min_price = min_sell_bronze if player['rare']: min_price *= rare_multiplier elif player['quality'] == 'silver' and price >= min_sell_silver and player['asset_id'] not in exclude: min_price = min_sell_silver if player['rare']: min_price *= rare_multiplier elif player['quality'] == 'gold' and price >= min_sell_gold and player['asset_id'] not in exclude: min_price = min_sell_gold if player['rare']: min_price *= rare_multiplier else: continue if price > min_price: player_list = obj.driver.find_elements_by_class_name('listFUTItem') for e in player_list: if parse.remove_accents(e.find_element_by_class_name('name').text) == player['item_name'] and not player['loan']: e.click() break panel = obj.__get_class__('DetailView', as_list=False, timeout=Global.micro_min) try: panel.find_element_by_xpath(".//*[contains(text(), 'This item cannot be traded')]") except (NoSuchElementException, TimeoutException): tier = info.get_tier(price) bin_price = int(max(min_price, info.round_down(price * obj.bin_settings[tier]['sell_percent'], Global.rounding_tiers[tier]))) start_price = bin_price - obj.bin_settings[tier]['spread'] result = actions.sell(obj, player, start_price, bin_price) if result == 'full': return obj.keep_alive(Global.micro_max) try: nav_bar = obj.__get_class__('pagingContainer', as_list=False) except (ElementNotVisibleException, NoSuchElementException, TimeoutException): nav_bar = obj.__get_class__('mainHeader', as_list=False) try: next_btn = nav_bar.find_element_by_class_name('next') obj.__click_element__(next_btn) except (ElementNotVisibleException, NoSuchElementException, TimeoutException): multi_log(obj, 'Done selling club players') break