def print_largest_absolute_savings_samples(per_pair_savings):
    for pair, trade_size, agg, pct_savings_list in data_import.pct_savings_gen(
            per_pair_savings):
        mean_savings = compute_mean(pct_savings_list)
        if abs(mean_savings) > 50:
            print(
                f"{pair} ${trade_size} vs {agg} mean_savings={mean_savings}%")
def print_avg_savings_per_pair_by_agg(per_pair_savings,
                                      only_trade_size=None,
                                      print_threshold=0,
                                      samples=False,
                                      min_stablecoins=0):
    for_trade_size = f"for Trade Size = {only_trade_size}" if only_trade_size else ''

    pair_agg_savings = defaultdict(lambda: defaultdict(list))

    for pair, trade_size, agg, pct_savings in data_import.pct_savings_gen(
            per_pair_savings):
        if only_trade_size and trade_size != only_trade_size: continue
        if min_stablecoins == 1 and not has_stablecoin(pair): continue
        if min_stablecoins == 2 and not both_stablecoins(pair): continue

        pair_agg_savings[pair][agg] += pct_savings

    print(
        f"\n\nAverage Savings {for_trade_size} (min_stablecoins={min_stablecoins})"
    )

    print(f"\nToken\tMean Pct. Savings")
    for pair, agg_savings in sorted(pair_agg_savings.items()):
        print(f"{pair[1]}\t{compute_mean(sum(agg_savings.values(), [])):.2f}")

        for agg, savings in agg_savings.items():
            better_pct, worse_pct, same_pct = better_worse_same_pcts(savings)
            avg_savings = compute_mean(savings)
            if abs(avg_savings) > print_threshold:
                print(
                    f"    {agg:<8}\t{better_pct:>3}/{worse_pct:>3}/{same_pct:>3}\t{avg_savings:.2f}"
                )
                if samples: print(f"    {agg}:\t{savings}")
def print_savings_summary_by_pair_csv(per_pair_savings,
                                      only_trade_size,
                                      agg_names,
                                      only_token=None,
                                      min_stablecoins=0,
                                      label="Average Savings by ETH pair"):
    print(f"\n{label} trade size = {only_trade_size}")

    pair_agg_savings = defaultdict(lambda: defaultdict(list))
    print(f"\nPair,{','.join(agg_names)}")

    for pair, trade_size, agg, pct_savings_list in data_import.pct_savings_gen(
            per_pair_savings):
        if trade_size != only_trade_size: continue
        # if only_token and only_token not in pair: continue
        # if only_token and pair[0] != only_token: continue
        if only_token and pair[1] != only_token: continue
        if min_stablecoins == 1 and not has_stablecoin(pair): continue
        if min_stablecoins == 2 and not both_stablecoins(pair): continue

        pair_agg_savings[pair][agg] += pct_savings_list

    for pair in sorted(pair_agg_savings):
        row = f"{pair[0]}/{pair[1]}"
        agg_savings = pair_agg_savings[pair]
        for agg in agg_names:
            if agg in agg_savings:
                row += f",{compute_mean(agg_savings[agg]) :.2f}"
            else:
                row += f","
        print(row)
Esempio n. 4
0
def aggregated_savings(per_token_savings):
    """Aggregates savings over all tokens for each trade_size"""
    per_trade_size_savings = defaultdict(lambda: defaultdict(list))

    for token, trade_size, agg, totle_split_pct_savings_list in data_import.pct_savings_gen(
            per_token_savings):
        per_trade_size_savings[trade_size][agg] += totle_split_pct_savings_list

    return per_trade_size_savings
def do_neg_savings(per_token_savings, trade_sizes):
    neg_savings, pos_savings = defaultdict(
        lambda: defaultdict(int)), defaultdict(lambda: defaultdict(int))
    neg_savings_without_fee = defaultdict(lambda: defaultdict(int))
    for token, trade_size, agg, pct_savings in data_import.pct_savings_gen(
            per_token_savings):
        for pct in pct_savings:
            if pct > 0.0:
                pos_savings[agg][trade_size] += 1
            else:
                neg_savings[agg][trade_size] += 1
                if pct < -0.25:
                    neg_savings_without_fee[agg][trade_size] += 1

    neg_samples, pos_samples, neg_without_fee_samples = 0, 0, 0
    aggs = sorted(list(set(neg_savings.keys()) | set(pos_savings.keys())))
    for agg in aggs:
        neg_samples_agg = sum(neg_savings[agg].values())
        neg_samples += neg_samples_agg
        neg_without_fee_samples_agg = sum(
            neg_savings_without_fee[agg].values())
        neg_without_fee_samples += neg_without_fee_samples_agg
        pos_samples_agg = sum(pos_savings[agg].values())
        pos_samples += pos_samples_agg

        total_samples_agg = neg_samples_agg + pos_samples_agg
        neg_pct_agg = 100.0 * neg_samples_agg / total_samples_agg
        neg_pct_without_fee_agg = 100.0 * neg_without_fee_samples_agg / total_samples_agg
        print(
            f"\nOut of {total_samples_agg} comparisons, Totle's price (without fees) was worse than {agg}'s {neg_without_fee_samples_agg} times, resulting in worse price {neg_pct_without_fee_agg:.1f}% of the time."
        )
        # print(f"Out of {total_samples_agg} comparisons, Totle's fees exceeded the price savings {neg_samples_agg} times, resulting in negative price savings {neg_pct_agg:.1f}% of the time.")

    total_samples = neg_samples + pos_samples
    neg_pct = 100.0 * neg_samples / total_samples
    neg_pct_without_fee = 100.0 * neg_without_fee_samples / total_samples

    print(
        f"\n\nOut of {total_samples} comparisons, Totle's price (without fees) was worse than competitor's {neg_without_fee_samples} times, resulting in worse price {neg_pct_without_fee:.1f}% of the time."
    )
    print(
        f"Out of {total_samples} comparisons, Totle's fees exceeded the price savings {neg_samples} times, resulting in negative price savings {neg_pct:.1f}% of the time."
    )

    print_neg_savings_csv(pos_savings,
                          neg_savings,
                          aggs,
                          trade_sizes,
                          label="Negative Price Savings Pct. vs Competitors")
    print_neg_savings_csv(pos_savings,
                          neg_savings_without_fee,
                          aggs,
                          trade_sizes,
                          label="Worse price (without fees) vs Competitors")
def print_stablecoin_pcts(pair_savings):
    """counts what percent of  savings were due to stablecoin/stablecoin pairs"""
    ss_count, all_count = 0, 0
    for pair, trade_size, agg, pct_savings_list in data_import.pct_savings_gen(
            pair_savings):
        all_count += len(pct_savings_list)
        if has_stablecoin(pair):
            ss_count += len(pct_savings_list)

    # print(f"\n{ss_count}/{all_count} ({100*ss_count/all_count}%) outliers were stablecoin/stablecoin pairs")
    print(
        f"\n{ss_count}/{all_count} ({100*ss_count/all_count}%) involved a stablecoin"
    )
def print_avg_savings_per_pair_by_trade_size(per_pair_savings,
                                             only_trade_sizes):
    pairs_trade_size_savings = defaultdict(lambda: defaultdict(list))
    for pair, trade_size, agg, pct_savings in data_import.pct_savings_gen(
            per_pair_savings):
        pairs_trade_size_savings[pair][trade_size] += pct_savings

    trade_size_strs = map(lambda ts: f"{ts:8.1f}", only_trade_sizes)
    print(f"Pair            {''.join(trade_size_strs)}")
    for pair, trade_size_savings in pairs_trade_size_savings.items():
        row = f"{str(pair):<16}"
        for ts in only_trade_sizes:
            row += f"{compute_mean(trade_size_savings[ts]):8.2f}" if ts in trade_size_savings else "      "
        print(row)
def print_stablecoin_pairs(pair_savings, only_trade_sizes):
    pairs_trade_size_savings = defaultdict(lambda: defaultdict(list))
    for pair, trade_size, agg, pct_savings_list in data_import.pct_savings_gen(
            pair_savings):
        if both_stablecoins(pair):
            pairs_trade_size_savings[pair][trade_size] += pct_savings_list
            mean_savings = compute_mean(pct_savings_list)
            # print(f"{pair} ${trade_size} vs {agg} mean_savings={mean_savings}%")

    trade_size_strs = map(lambda ts: f"{ts:8.1f}", only_trade_sizes)
    print(f"\nPair            {''.join(trade_size_strs)}")
    for pair, trade_size_savings in sorted(pairs_trade_size_savings.items()):
        row = f"{str(pair):<16}"
        for ts in only_trade_sizes:
            row += f"{compute_mean(trade_size_savings[ts]):8.2f}" if ts in trade_size_savings else "      "
        print(row)
def print_top_ten_pairs_savings(per_pair_savings, only_trade_size=None):
    for_trade_size = f"for Trade Size = {only_trade_size}" if only_trade_size else ''

    pair_savings = defaultdict(list)
    for pair, trade_size, exchange, pct_savings in data_import.pct_savings_gen(
            per_pair_savings):
        if only_trade_size and trade_size != only_trade_size: continue
        pair_savings[pair] += pct_savings

    avg_savings_pairs = {}
    for pair, savings_list in pair_savings.items():
        avg_savings_pairs[compute_mean(savings_list)] = pair
    sorted_avg_savings_pairs = sorted(avg_savings_pairs.items())

    print(f"\nTop 10 Negative Price Savings {for_trade_size}")
    for pct_savings, pair in sorted_avg_savings_pairs[0:10]:
        print(f"{pair[0]}/{pair[1]}\t{pct_savings:.2f}%")
    print(f"\nTop 10 Positive Price Savings {for_trade_size}")
    for pct_savings, pair in reversed(sorted_avg_savings_pairs[-10:-1]):
        print(f"{pair[0]}/{pair[1]}\t{pct_savings:.2f}%")
def print_avg_savings_by_pair(per_pair_savings,
                              only_trade_size=None,
                              only_aggs=None,
                              show_only_to=False):
    token_savings = defaultdict(lambda: defaultdict(list))
    for pair, trade_size, agg, pct_savings in data_import.pct_savings_gen(
            per_pair_savings):
        if only_trade_size and trade_size != only_trade_size: continue
        token_savings[pair][agg] += pct_savings

    print(f"\nAverage Savings by Pair for Trade Size={only_trade_size}")
    print(f"\nPair,{','.join(only_aggs)}")

    for pair, savings in sorted(token_savings.items()):
        row = f"{pair[1]}" if show_only_to else f"{pair[1]}>{pair[0]}"
        for agg in only_aggs:
            if agg in savings:
                row += f",{compute_mean(savings[agg]) :.2f}"
            else:
                row += f","
        print(row)
def do_better_worse_same_by_trade_size(per_pair_savings, label):
    print(f"\n{label}")
    better_price, worse_price, same_price, total_samples = defaultdict(
        int), defaultdict(int), defaultdict(int), defaultdict(int)
    trade_sizes = set()
    total_samples

    for pair, trade_size, agg, pct_savings in data_import.pct_savings_gen(
            per_pair_savings):
        trade_sizes.add(trade_size)
        better_count, worse_count, same_count = better_worse_same_counts(
            pct_savings)
        better_price[trade_size] += better_count
        worse_price[trade_size] += worse_count
        same_price[trade_size] += same_count
        total_samples[trade_size] += better_count + worse_count + same_count

    better_pct, worse_pct, same_pct = {}, {}, {}
    for trade_size in trade_sizes:
        better_pct[trade_size] = 100.0 * better_price[
            trade_size] / total_samples[trade_size]
        worse_pct[trade_size] = 100.0 * worse_price[
            trade_size] / total_samples[trade_size]
        same_pct[trade_size] = 100.0 * same_price[trade_size] / total_samples[
            trade_size]

    header = 'Totle price was         better           worse           same'
    print(f"\n{header}")
    for trade_size in sorted(trade_sizes):
        print(
            f"{trade_size:<14} {better_pct[trade_size]:14.2f}% {worse_pct[trade_size]:14.2f}% {same_pct[trade_size]:14.2f}%"
        )

    # do CSV
    *a, b, c, d = header.split()
    print(','.join([' '.join(a), b, c, d]))
    for trade_size in sorted(trade_sizes):
        print(
            f"{trade_size},{better_pct[trade_size]:.2f}%,{worse_pct[trade_size]:.2f}%,{same_pct[trade_size]:.2f}%"
        )
def do_better_worse_same_price(per_pair_savings, label, agg_breakdown=False):
    print(f"\n{label}")
    better_price, worse_price, same_price = defaultdict(
        lambda: defaultdict(int)), defaultdict(
            lambda: defaultdict(int)), defaultdict(lambda: defaultdict(int))

    for token, trade_size, agg, pct_savings in data_import.pct_savings_gen(
            per_pair_savings):
        better_count, worse_count, same_count = better_worse_same_counts(
            pct_savings)
        better_price[agg][trade_size] += better_count
        worse_price[agg][trade_size] += worse_count
        same_price[agg][trade_size] += same_count

    better_price_samples, worse_price_samples, same_price_samples = 0, 0, 0
    better_pct, worse_pct, same_pct = {}, {}, {}
    aggs = sorted(
        list(
            set(better_price.keys()) | set(worse_price.keys())
            | set(worse_price.keys())))
    for agg in aggs:
        better_price_samples_agg = sum(better_price[agg].values())
        better_price_samples += better_price_samples_agg
        worse_price_samples_agg = sum(worse_price[agg].values())
        worse_price_samples += worse_price_samples_agg
        same_price_samples_agg = sum(same_price[agg].values())
        same_price_samples += same_price_samples_agg

        total_samples_agg = better_price_samples_agg + worse_price_samples_agg + same_price_samples_agg

        better_pct[agg] = 100.0 * better_price_samples_agg / total_samples_agg
        worse_pct[agg] = 100.0 * worse_price_samples_agg / total_samples_agg
        same_pct[agg] = 100.0 * same_price_samples_agg / total_samples_agg

    if agg_breakdown:
        header = 'Totle price was         better           worse           same'
        print(f"\n{header}")
        for agg in aggs:
            print(
                f"{agg:<14} {better_pct[agg]:14.2f}% {worse_pct[agg]:14.2f}% {same_pct[agg]:14.2f}%"
            )

        # do csv
        *a, b, c, d = header.split()
        print(','.join([' '.join(a), b, c, d]))
        for agg in aggs:
            print(
                f"{agg},{better_pct[agg]:.2f}%,{worse_pct[agg]:.2f}%,{same_pct[agg]:.2f}%"
            )

    total_samples = better_price_samples + worse_price_samples + same_price_samples
    better_pct = 100.0 * better_price_samples / total_samples
    worse_pct = 100.0 * worse_price_samples / total_samples
    same_pct = 100.0 * same_price_samples / total_samples

    print("\n")
    print(
        f"Out of {total_samples} comparisons, Totle's price was better than competitor's {better_pct:.1f}% of the time, worse {worse_pct:.1f}% of the time, and the same {same_pct:.1f}% of the time."
    )

    # print_neg_savings_csv(pos_savings, neg_savings, aggs, trade_sizes, label="Negative Price Savings Pct. vs Competitors")
    return total_samples