def get_princeton_graph_tikz_2(skip_under=0): block_nums = [] results = query_db("SELECT SUM(CAST(eth_profit as FLOAT)) as eth_profit,total_fees,mergedprofitabletxs.block_number as block_number,total_fees FROM mergedprofitabletxs LEFT JOIN block_fees ON block_fees.block_number=mergedprofitabletxs.block_number WHERE all_positive='True' GROUP BY mergedprofitabletxs.block_number ORDER BY mergedprofitabletxs.block_number ASC;") for result in results: if int(result['block_number']) < skip_under: continue fees = float(result['total_fees']) eth_revenue = float(result['eth_profit']) block_nums.append(int(result['block_number'])) ratio = eth_revenue/(eth_revenue + fees) bucket = float("{0:.2f}".format(ratio)) if ratio - bucket > .00000001: print("adding") bucket += .01 bucket = round(bucket, 2) bucket = str(bucket) print(ratio,bucket) if not bucket in buckets: buckets[bucket] = 1 else: buckets[bucket] += 1 numtotal = sum(buckets.values()) print(buckets) for bucketlabel in sorted(buckets.keys(), key=float): #print("(%s, %f)" % (bucketlabel, float(buckets[bucketlabel])/float(numtotal))) print("(%s, %f)" % (bucketlabel, buckets[bucketlabel])) print(numtotal, max(block_nums), min(block_nums))
def get_princeton_graph_tikz(desiredsize): results = query_db("SELECT SUM(CAST(eth_profit as FLOAT)) as total_profit,mergedprofitabletxs.block_number as block_number,total_fees,substr(timestamp,0,11) as date FROM mergedprofitabletxs LEFT JOIN block_fees ON block_fees.block_number=mergedprofitabletxs.block_number WHERE all_positive='True' GROUP BY mergedprofitabletxs.block_number ORDER BY CAST(total_profit as FLOAT) DESC LIMIT %d;" % desiredsize) labels = "" profits = "" fees = "" rewards = "" dates = "" datespoints = "" for result in results: label = result['block_number'] date = result['date'] date = date.split("-") date = date[2] + "-" + date[1] + "-" + date[0][2:] if date in dates: date = date + " " # (dirty hack for repeated labels) dates += date + ", " datespoints += "("+ date+ ", 0) " labels += label + ", " profits += "(" + label + ", " + str(result['total_profit']) + ") " fees += "("+ label+ ", "+ str(result['total_fees']) + ") " blocknum = int(result['block_number']) if blocknum < 4370000: reward = 5 elif blocknum < 7280000: reward = 3 else: reward = 2 rewards += "("+ label+ ", "+ str(reward) + ") " print(PRINCETON_TEMPLATE.replace("%labels%", labels).replace("%profits%", profits).replace("%fees%", fees).replace("%rewards%", rewards).replace("%dates%", dates).replace("%datespoints%", datespoints))
def get_pga_winner_graphs(): results = query_db("SELECT *,substr(timestamp,0,11) as date FROM auctions JOIN mergedprofitabletxs ON auctions.hash=mergedprofitabletxs.transaction_hash WHERE all_positive='True' GROUP BY transaction_hash") revenue_file = open('reports/data/revenue.csv', 'w') profit_file = open('reports/data/profit.csv', 'w') cost_file = open('reports/data/cost.csv', 'w') gas_used_file = open('reports/data/gas_used.csv', 'w') gas_prices_file = open('reports/data/gas_prices.csv', 'w') for result in results: revenue = float(result['eth_profit']) gas_price = float(result['gas_price']) gas_used = float(result['receipt_gas_used']) cost = (gas_price * gas_used) / (10 ** 18) profit=revenue-cost revenue_file.write(str(revenue) + "\n") profit_file.write(str(profit) + "\n") cost_file.write(str(cost) + "\n") gas_used_file.write(str(gas_used) + "\n") gas_prices_file.write(str(gas_price) + "\n") print(result['txhash'], revenue, cost, profit)
def get_pga_dynamics_graphs(): good_auctions = set() auction_dates = {} auction_profits = {} good_auctions_res = query_db("SELECT auction_id,eth_profit FROM auctions JOIN profits ON auctions.hash=profits.txhash WHERE all_positive='True' GROUP BY txhash") for auction in good_auctions_res: good_auctions.add(int(auction['auction_id'])) auction_profits[int(auction['auction_id'])] = float(auction['eth_profit']) print(good_auctions) # todo consolidate w auction postprocessing code in read_csv.py; move this there or that here? per_auction_bot_traces = {} for auction_id in sorted(list(good_auctions)): bids = query_db("SELECT * FROM auctions WHERE auction_id='%d'" % auction_id) for result in bids: bot = result['sender'] auction_date = datetime.utcfromtimestamp(int(result['time_seen']) / (10 ** 9)).strftime('%Y-%m-%d') auction_dates[int(result['auction_id'])] = auction_date init_dict(per_auction_bot_traces, auction_id, {}) init_dict(per_auction_bot_traces[auction_id], bot, []) per_auction_bot_traces[auction_id][bot].append(dict(result)) sorted_bot_deltas = {} min_bid_ratios = [] for auction in per_auction_bot_traces: for bot in per_auction_bot_traces[auction]: trace = per_auction_bot_traces[auction][bot] if len(trace) < 5: # no repeated bids; probably noise continue trace = sorted(trace, key=lambda x : float(x['gas_price'])) min_bid = float(trace[0]['gas_price']) * float(trace[0]['gas_limit']) / (10 ** 18) profit = float(auction_profits[int(trace[0]['auction_id'])]) min_bid_profit_ratio = min_bid/profit min_bid_ratios.append(min_bid_profit_ratio) per_auction_bot_traces[auction][bot] = trace init_dict(sorted_bot_deltas, auction, {}) init_dict(sorted_bot_deltas[auction], bot, ([],[])) for i in range(1, len(trace)): try: bid_price_percent_delta = round((float(trace[i]['gas_price']) - float(trace[i-1]['gas_price']))/float(trace[i-1]['gas_price']), 8) * 100 bid_time_delta = (float(trace[i]['time_seen']) - float(trace[i-1]['time_seen'])) / (10 ** 9) except: print(result['auction_id'], "has a failed bid") pass sorted_bot_deltas[auction][bot][0].append(bid_price_percent_delta) sorted_bot_deltas[auction][bot][1].append(bid_time_delta) xs = [] median_raise_ys = [] mean_time_delta_ys = [] raises = [] eth_profit_ys = [] num_raises = [] for auction in sorted_bot_deltas: for bot in sorted_bot_deltas[auction]: #print(auction, bot, np.mean(sorted_bot_deltas[auction][bot][1]), auction_dates[auction]) print(auction, bot, sorted_bot_deltas[auction][bot][0], auction_dates[auction]) raises += sorted_bot_deltas[auction][bot][0] xs.append(auction_dates[auction]) eth_profit_ys.append(auction_profits[auction]) median_raise_ys.append(np.median(sorted_bot_deltas[auction][bot][0])) mean_time_delta_ys.append(np.mean(sorted_bot_deltas[auction][bot][1])) num_raises.append(len(sorted_bot_deltas[auction][bot][1])) print([np.min(raises), np.max(raises), np.median(raises), np.mean(raises), np.var(raises), sum((y < .13 and y >= .12 for y in raises))], len(raises)) median_raise_plots = "" time_delta_plots = "" median_raise_coords = "" time_delta_coords = "" for i in range(len(xs)): median_raise_coords += "(%s,%f) [%f] " % (xs[i], median_raise_ys[i], eth_profit_ys[i]) time_delta_coords += "(%s,%f) [%f] " % (xs[i], mean_time_delta_ys[i], num_raises[i]) median_raise_plots += HIST_COORDS.replace("%coords%", median_raise_coords) time_delta_plots += HIST_COORDS.replace("%coords%", time_delta_coords) open('reports/data/pga_raises.csv', 'w').write(median_raise_plots) median_raise_plots += " \\addplot+[red] coordinates {(%s,15.0) (%s,15.0)}; \\addplot+[green] coordinates {(%s,12.5) (%s,12.5)};" % (xs[0], xs[-1], xs[0], xs[-1]) # draw horizontal lines at model prediction through coords; hack to get around no horizontal lines in pgfplots datelib open('reports/median_raise_scatter.tex', 'w').write(LINE_TEMPLATE.replace("%plots%", median_raise_plots).replace("%legendkeys%", "\\\\y=15\\\\y=12.5\\\\").replace("%title%", "Raise Strategy Evolution").replace("ymode=log,", "").replace("%ylabel%", "Median Raise Percent Over Own Bid").replace("%max%", "75").replace("%legendpos%", "north east").replace("%extraaxisoptions%", open('graph_templates/median_raise_extraaxisoptions.tex').read())) open('reports/latency_scatter.tex', 'w').write(LINE_TEMPLATE.replace("%plots%", time_delta_plots).replace("%legendkeys%", "").replace("%title%", "Bot Latency Evolution").replace("ymode=log,", "").replace("%ylabel%", "Mean Observed Time Between Bids (s)").replace("%max%", "1").replace("%legendpos%", "north east").replace("%extraaxisoptions%", open('graph_templates/latency_extraaxisoptions.tex').read())) min_bid_ratios_file = open('reports/data/min_bid_ratios.csv', 'w') for bid in min_bid_ratios: min_bid_ratios_file.write(str(bid) + "\n")
def get_breadth_graphs_tikz(graphs_to_generate, skip_until='2017-09-01'): prices = {} price_data = query_db("SELECT * FROM eth_data") for price_datum in price_data: prices[price_datum['date']] = price_datum['price(USD)'] results = query_db("SELECT * FROM mergedprofitabletxs WHERE all_positive = 'True' AND CAST(eth_profit as FLOAT) > 0.0;") eth_revenues = {} usd_revenues = {} usd_profits = {} gas_ratios_pertx = {} num_trades_pertx = {} exchange_breakdowns_eth = {} bot_breakdowns_usd = {} bot_breakdowns_usd_profit = {} pertx_ratios = open('reports/data/ratios.csv', 'w') for result in results: date = result['date'] eth_revenue = float(result['eth_profit']) gas_used = float(result['receipt_gas_used']) eth_profit = eth_revenue - ((gas_used * float(result['gas_price'])) / (10 ** 18)) usd_revenue = eth_revenue * float (prices.get(result['date'], 0)) usd_profit = eth_profit * float (prices.get(result['date'], 0)) pertx_ratios.write("%f\n" % (eth_profit/eth_revenue)) revenue_graph = json.loads(result['profit_graph']) num_trades = len(revenue_graph) / 2 # revenue graph contains two edges per trade init_dict(eth_revenues, date, 0) init_dict(usd_revenues, date, 0) init_dict(usd_profits, date, 0) init_dict(gas_ratios_pertx, date, []) init_dict(num_trades_pertx, date, []) eth_revenues[date] += eth_revenue usd_revenues[date] += usd_revenue usd_profits[date] += usd_profit gas_ratios_pertx[date].append(gas_used/num_trades) num_trades_pertx[date].append(num_trades) for edge in revenue_graph: if edge[0][0] == "!": # ! is a special marker for exchange node # each exchange will appear once with a special "!" label, in two edges in the revenue graph # however, it will be the source of only one edge exchange = edge[0][1:] if not exchange in exchange_breakdowns_eth: exchange_breakdowns_eth[exchange] = {} if not date in exchange_breakdowns_eth[exchange]: exchange_breakdowns_eth[exchange][date] = 0 exchange_breakdowns_eth[exchange][date] += ((1.0/num_trades) * eth_revenue) bot = result['from_address'] init_dict(bot_breakdowns_usd, bot, {}) init_dict(bot_breakdowns_usd[bot], date, 0) bot_breakdowns_usd[bot][date] += usd_revenue init_dict(bot_breakdowns_usd_profit, bot, {}) init_dict(bot_breakdowns_usd_profit[bot], date, 0) bot_breakdowns_usd_profit[bot][date] += usd_profit eth_revenue_coords = "" usd_revenue_coords = "" usd_profit_coords = "" gas_usage_coords = "" xs = [] eth_revenue_ys = [] usd_revenue_ys = [] usd_profit_ys = [] sorted_dates = sorted(prices.keys()) sorted_dates = sorted_dates[sorted_dates.index(sorted(eth_revenues.keys())[0]):sorted_dates.index(sorted(eth_revenues.keys())[-3])] # (prune last 3 days for potential data quality issues) if skip_until is not None: sorted_dates = sorted_dates[sorted_dates.index(skip_until):] # trim early non-representative data for date in sorted_dates: eth_revenue_coords += "(%s,%f) [%f] " % (date, eth_revenues.get(date, 0.0), sum(num_trades_pertx.get(date, [0]))) usd_revenue_coords += "(%s,%f) [%f] " % (date, usd_revenues.get(date, 0.0), sum(num_trades_pertx.get(date, [0]))) usd_profit_coords += "(%s,%f) " % (date, usd_profits.get(date, 0.0)) gas_usage_coords += "(%s,%f) [%f] " % (date, np.mean(gas_ratios_pertx.get(date, [0.0])), np.mean(num_trades_pertx.get(date, [0]))) xs.append(date) eth_revenue_ys.append(float(eth_revenues.get(date, 0.0))) usd_revenue_ys.append(float(usd_revenues.get(date, 0.0))) usd_profit_ys.append(float(usd_profits.get(date, 0.0))) ma_eth_coords = "" ma_usd_coords = "" ma_usd_profit_coords = "" ma_eth_revenue=get_moving_average(eth_revenue_ys,14) ma_usd_revenue=get_moving_average(usd_revenue_ys,14) ma_usd_profit=get_moving_average(usd_profit_ys,14) cum_eth_graph_lines = "" ma_botusd_graph_lines = "" ma_botusd_profit_graph_lines = "" price_coords = "" cum_eth_coords = "" cum_usd_coords = "" cum_usd_profit_coords = "" cumulative_eth_revenue=get_cumulative(eth_revenue_ys) cumulative_usd_revenue=get_cumulative(usd_revenue_ys) cumulative_usd_profit=get_cumulative(usd_profit_ys) for i in range(len(xs)): ma_eth_coords += "(%s,%f)" % (xs[i], ma_eth_revenue[i]) ma_usd_coords += "(%s,%f)" % (xs[i], ma_usd_revenue[i]) ma_usd_profit_coords += "(%s,%f)" % (xs[i], ma_usd_profit[i]) price_coords += "(%s,%f) " % (xs[i], float(prices[xs[i]])) cum_eth_coords += "(%s,%f) " % (xs[i], cumulative_eth_revenue[i]) cum_usd_coords += "(%s,%f) " % (xs[i], cumulative_usd_revenue[i]) cum_usd_profit_coords += "(%s,%f) " % (xs[i], cumulative_usd_profit[i]) cum_eth_graph_lines += COORDS_CONSTANT.replace("addplot+", "addplot+[black]").replace("%coords%", cum_eth_coords) + "\n" ma_botusd_graph_lines += COORDS_CONSTANT.replace("addplot+", "addplot+[black]").replace("%coords%", ma_usd_coords) + "\n" ma_botusd_profit_graph_lines += COORDS_CONSTANT.replace("addplot+", "addplot+[black]").replace("%coords%", ma_usd_profit_coords) + "\n" top_5_exchanges = calculate_top(exchange_breakdowns_eth, 6) for exchange in top_5_exchanges: exchange_coords = "" exchange_revenues = [] for i in range(len(xs)): exchange_revenues.append(exchange_breakdowns_eth[exchange].get(xs[i], 0)) cumulative_exchange_revenue = get_cumulative(exchange_revenues) for i in range(len(xs)): exchange_coords += "(%s,%f) " % (xs[i], cumulative_exchange_revenue[i]) cum_eth_graph_lines += COORDS_CONSTANT.replace("%coords%", exchange_coords) + "\n" top_bots = calculate_top(bot_breakdowns_usd, 10) # todo consolidate this + above into method for bot in top_bots: bot_revenue_coords = "" bot_revenues = [] bot_profit_coords = "" bot_profits = [] for i in range(len(xs)): bot_revenues.append(bot_breakdowns_usd[bot].get(xs[i], 0)) bot_profits.append(bot_breakdowns_usd_profit[bot].get(xs[i], 0)) bot_revenue_ma = get_moving_average(bot_revenues, 14) bot_profit_ma = get_moving_average(bot_profits, 14) for i in range(len(xs)): bot_revenue_coords += "(%s,%f) " % (xs[i], bot_revenue_ma[i]) bot_profit_coords += "(%s,%f) " % (xs[i], bot_profit_ma[i]) ma_botusd_graph_lines += COORDS_CONSTANT.replace("%coords%", bot_revenue_coords) + "\n" ma_botusd_profit_graph_lines += COORDS_CONSTANT.replace("%coords%", bot_profit_coords) + "\n" if "pure_revenue_eth" in graphs_to_generate: open('reports/pure_revenue_eth.tex', 'w').write(BREADTH_SCATTER_TEMPLATE.replace("%coords%", eth_revenue_coords).replace("%macoords%", ma_eth_coords).replace("%title%", "Pure Revenue Market Size (ETH)").replace("%ylabel%", "Daily Pure Revenue Captured (ETH)").replace("%cumcoords%", cum_eth_coords).replace("%extra%", "").replace("%max%", str(2*max(cumulative_eth_revenue))).replace("%colorbartitle%", "\\# Trades").replace("%extraaxisoptions%", " point meta max=1000,").replace("%extracolorbar%", "ytick={0,200,400,...,800}, extra y ticks={1000}, extra y tick labels={1000+}")) if "pure_revenue_usd" in graphs_to_generate: open('reports/pure_revenue_usd.tex', 'w').write(BREADTH_SCATTER_TEMPLATE.replace("%coords%", usd_revenue_coords).replace("%macoords%", ma_usd_coords).replace("%title%", "Pure Revenue Market Size (USD)").replace("%ylabel%", "Daily Pure Revenue Captured (USD)").replace("%cumcoords%", cum_usd_coords).replace("%extra%", open('graph_templates/eth_price_line.tex').read().replace("%coords%", price_coords)).replace("%max%", str(2*max(cumulative_usd_revenue))).replace("%colorbartitle%", "\\# Trades")) if "pure_revenue_exch" in graphs_to_generate: open('reports/pure_revenue_exch_breakdown.tex', 'w').write(LINE_TEMPLATE.replace("%plots%", cum_eth_graph_lines).replace("%legendkeys%", "Market Total," + ",".join(top_5_exchanges)).replace("%title%", "Pure Revenue Per Exchange Since 04/18").replace("%ylabel%", "Cumulative Pure Revenue Captured (ETH)").replace("%max%", str(2*max(cumulative_eth_revenue))).replace("%legendpos%", "south east").replace("%extraaxisoptions%", "")) if "pure_revenue_botmas" in graphs_to_generate: open('reports/pure_revenue_bot_revenue.tex', 'w').write(LINE_TEMPLATE.replace("%plots%", ma_botusd_graph_lines).replace("%legendkeys%", "Market Total," + ",".join([x[:8] + ".." for x in top_bots])).replace("%title%", "Pure Revenue Per Bot, 14-Day Moving Average").replace("%ylabel%", "Daily Pure Revenue Captured (USD)").replace("%max%", str(2*max(ma_usd_revenue))).replace("%legendpos%", "outer north east").replace("%extraaxisoptions%", ",enlarge x limits=-1,width=.9\\textwidth, height=0.4\\textwidth,x label style={at={(1.15,-.15)},anchor=south,}")) open('reports/pure_revenue_bot_profit.tex', 'w').write(LINE_TEMPLATE.replace("%plots%", ma_botusd_profit_graph_lines).replace("%legendkeys%", "Market Total," + ",".join([x[:8] + ".." for x in top_bots])).replace("%title%", "Pure Revenue Profit Per Bot, 14-Day Moving Average").replace("%ylabel%", "Daily Pure Revenue Profit (USD)").replace("%max%", str(2*max(ma_usd_profit))).replace("%legendpos%", "outer north east").replace("%extraaxisoptions%", ",enlarge x limits=-1,width=.9\\textwidth, height=0.4\\textwidth,x label style={at={(1.15,-.15)},anchor=south,}")) if "pure_revenue_gas_numtrades" in graphs_to_generate: open('reports/pure_revenue_gas.tex', 'w').write(BREADTH_SCATTER_TEMPLATE.replace("%coords%", gas_usage_coords).replace("%macoords%", "").replace("%title%", "Gas Trends in Pure Revenue").replace("%cumcoords%", "(2018-03-08, 0) (2018-03-08, 300000)").replace("%extra%", "").replace("%max%", "300000").replace("%ylabel%", "Mean Gas Used Per Trade").replace("ymode=log,", "").replace("scatter,", "scatter, only marks,").replace("%colorbartitle%", "Mean Trades/TX"))
def get_versus_graphs(): num_clashes = {} pgas_participated = {} net_profits = {} all_mined_bids = query_db("SELECT block_number,hash,eth_profit,auction_id,from_address,receipt_gas_used,mergedprofitabletxs.gas_price as gas_price FROM mergedprofitabletxs JOIN auctions ON auctions.hash=mergedprofitabletxs.transaction_hash ORDER BY CAST(auction_id as INTEGER) ASC;") auctions = {} first_auction_participated = {} last_auction_participated = {} for bid in all_mined_bids: auction_num = int(bid['auction_id']) if not auction_num in auctions: auctions[auction_num] = [] auctions[auction_num].append(bid) historical_states = {} current_state = {} # mapps bidder pairs to (total advantage, ) # advantage is defined as the number of advantage by this bidder in auctions where the pair was active, # where advantage is defined as revenue minus costs (profit) minus competititor's cost for auction_num in range(0, max(auctions.keys()) + 1): if not auction_num in auctions: continue losers = set() winners = set() for bid in auctions[auction_num]: profit = 0.0 if bid['eth_profit'] is not None: profit = float(bid['eth_profit']) if profit <= 0: losers.add(bid) else: winners.add(bid) #print(auction_num, winners, losers) # we only consider games w 1 winner and 1 loser (2 bot auctions) if len(winners) == 1 and len(losers) == 1: winner = list(winners)[0] winner_gas_used = float(winner['receipt_gas_used']) winner_revenue = float(winner['eth_profit']) winner_profit = winner_revenue - ((winner_gas_used * float(winner['gas_price'])) / (10 ** 18)) # update current_state w results init_dict(current_state, winner['from_address'], 0) current_state[winner['from_address']] += winner_profit init_dict(pgas_participated, winner['from_address'], []) pgas_participated[winner['from_address']].append(auction_num) init_dict(net_profits, winner['from_address'], 0) net_profits[winner['from_address']] += winner_profit for loser in losers: # log pair participation in first/last auction init_dict(first_auction_participated, loser, auction_num) init_dict(first_auction_participated, winner, auction_num) last_auction_participated[winner] = auction_num last_auction_participated[loser] = auction_num loser_cost = (float(loser['receipt_gas_used']) * float(loser['gas_price'])) / (10 ** 18) winner_vs = winner['from_address'] + "-" + loser['from_address'] # winning pair loser_vs = loser['from_address'] + "-" + winner['from_address'] init_dict(first_auction_participated, loser_vs, auction_num) init_dict(first_auction_participated, winner_vs, auction_num) last_auction_participated[winner_vs] = auction_num last_auction_participated[loser_vs] = auction_num init_dict(current_state, winner_vs, 0.0) current_state[winner_vs] += winner_profit init_dict(current_state, loser['from_address'], 0.0) current_state[loser['from_address']] -= loser_cost init_dict(current_state, loser_vs, 0.0) current_state[loser_vs] -= loser_cost canonical_id = sorted([winner_vs, loser_vs])[0] init_dict(num_clashes, canonical_id, 0) num_clashes[canonical_id] += 1 # todo fix this to more accurately track clashes init_dict(pgas_participated, loser['from_address'], []) pgas_participated[loser['from_address']].append(auction_num) init_dict(net_profits, loser['from_address'], 0) net_profits[loser['from_address']] -= loser_cost #print(auction_num, current_state) historical_states[auction_num] = dict(current_state) # make copy of current state for history print("Most common pairs:") for k, v in Counter(num_clashes).most_common(1): break opposite_pair = "-".join(reversed(k.split("-"))) winner = k.split("-")[0] loser = k.split("-")[1] print("auction_num,winner_advantage,loser_advantage,winner_pga_total,loser_pga_total") for auction_num in range(0, auction_num + 1): if not auction_num in historical_states: continue print(auction_num, historical_states[auction_num].get(k, 0), historical_states[auction_num].get(opposite_pair, 0), historical_states[auction_num].get(winner, 0), historical_states[auction_num].get(loser, 0), sep=",") for num_bots in [5,20,50,100]: output_handle = open('reports/versus_%d.csv' % num_bots, 'w') output_handle.write("auctions_elapsed_%d,loser_versus_%d,winner_versus_%d,loser_net_%d,winner_net_%d\n" % tuple([num_bots] * 5)) loser_versus_vectors = [] winner_versus_vectors = [] loser_overall_vectors = [] winner_overall_vectors = [] for k, v in Counter(num_clashes).most_common(num_bots): opposite_pair = "-".join(reversed(k.split("-"))) winner_versus_vector = [] loser_versus_vector = [] winner_overall_vector = [] loser_overall_vector = [] winner = k.split("-")[0] loser = k.split("-")[1] first_vs_auction = min(first_auction_participated[k], first_auction_participated[opposite_pair]) last_vs_auction = max(last_auction_participated[k], last_auction_participated[opposite_pair]) for auction_num in range(first_vs_auction, last_vs_auction + 1): if not auction_num in historical_states: continue if auction_num in pgas_participated[winner] and auction_num in pgas_participated[loser]: winner_versus_vector.append(historical_states[auction_num].get(k, 0)) loser_versus_vector.append(historical_states[auction_num].get(opposite_pair, 0)) if auction_num in pgas_participated[winner]: winner_overall_vector.append(historical_states[auction_num].get(winner, 0)) if auction_num in pgas_participated[loser]: loser_overall_vector.append(historical_states[auction_num].get(loser, 0)) if loser_versus_vector[-1] > winner_versus_vector[-1]: # swap winners/lossers in canonical order loser_versus_vector, winner_versus_vector = winner_versus_vector, loser_versus_vector loser_overall_vector, winner_overall_vector = winner_overall_vector, loser_overall_vector #print(k, historical_states[auction_num].get(k, 0), historical_states[auction_num].get(opposite_pair, 0), historical_states[auction_num].get(winner, 0), historical_states[auction_num].get(loser, 0), sep=",") loser_versus_vectors.append(loser_versus_vector) winner_versus_vectors.append(winner_versus_vector) loser_overall_vectors.append(loser_overall_vector) winner_overall_vectors.append(winner_overall_vector) for auction_index in range(max([len(v) for v in (loser_versus_vectors + winner_versus_vectors + loser_overall_vectors + winner_overall_vectors)])): if not auction_index in historical_states: continue winner_versus_advantages = [] loser_versus_advantages = [] winner_overall_advantages = [] loser_overall_advantages = [] for vector in loser_versus_vectors: loser_versus_advantages.append(vector[min(auction_index, len(vector) - 1)]) for vector in winner_versus_vectors: winner_versus_advantages.append(vector[min(auction_index, len(vector) - 1)]) for vector in loser_overall_vectors: loser_overall_advantages.append(vector[min(auction_index, len(vector) - 1)]) for vector in winner_overall_vectors: winner_overall_advantages.append(vector[min(auction_index, len(vector) - 1)]) output_handle.write(",".join([str(x) for x in [auction_index, np.mean(loser_versus_advantages), np.mean(winner_versus_advantages), np.mean(loser_overall_advantages), np.mean(winner_overall_advantages)]]) + "\n") print("Done with versus graphs")