"""固定等权合成秩与基础秩,实际边界替换和增量费用。""" import json from statistics import mean base = {'A': 4, 'B': 3, 'C': 2, 'D': 1} candidate = {'A': 3, 'B': 1, 'C': 4, 'D': 2} combined = {s: mean([base[s], candidate[s]]) for s in base} assert combined == {'A': 3.5, 'B': 2, 'C': 3, 'D': 1.5} top = lambda scores: sorted(scores, key=lambda s: (-scores[s], s))[:2] baseline, expanded = top(base), top(combined) assert baseline == ['A', 'B'] and expanded == ['A', 'C'] def account(target): holdings, cash, fees, orders = {'A', 'B'}, 200, 0, [] for side, symbols in [('sell', holdings - set(target)), ('buy', set(target) - holdings)]: for symbol in sorted(symbols): cash += 399 if side == 'sell' else -401 fees += 1 orders.append([symbol, side, 40, 10, 1]) marks = {'A': 10.2, 'B': 10.1, 'C': 10.5} return {'orders': orders, 'fees': fees, 'cash': cash, 'equity': cash + sum(40 * marks[s] for s in target)} assert account(baseline)['equity'] == 1012 assert account(expanded)['equity'] == 1026 assert account(baseline)['orders'] == [] and account(baseline)['cash'] == 200 assert account(baseline)['fees'] == 0 assert account(expanded)['orders'] == [['B', 'sell', 40, 10, 1], ['C', 'buy', 40, 10, 1]] assert account(expanded)['cash'] == 198 and account(expanded)['fees'] == 2 decision_increment = account(expanded)['equity'] - account(baseline)['equity'] assert decision_increment == 14 redundant = {s: mean([base[s], base[s]]) for s in base} assert top(redundant) == baseline and account(top(redundant))['fees'] == 0 print(json.dumps({'base': base, 'candidate': candidate, 'combined': combined, 'baseline': baseline, 'expanded': expanded, 'baseline_account': account(baseline), 'expanded_account': account(expanded), 'decision_increment': decision_increment, 'duplicate_factor_changes_members': False}))