"""当前截面上预设顺序统计量截尾;检查不变成员与新同分换仓。""" import json def clip(scores, upper_count): values = sorted(scores.values()) cap = values[-upper_count - 1] return {s: min(v, cap) for s, v in scores.items()}, cap def top(scores, count): return sorted(scores, key=lambda s: (-scores[s], s))[:count] same = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 100} same_clipped, same_cap = clip(same, 1) assert same_cap == 4 assert set(top(same, 2)) == set(top(same_clipped, 2)) == {'D', 'E'} changed = {'X': 100, 'A': 4, 'B': 3, 'C': 2, 'D': 1} clipped, cap = clip(changed, 1) assert cap == 4 and top(changed, 1) == ['X'] and top(clipped, 1) == ['A'] def account(target): cash, orders = 200, [] if target != 'X': cash += 80 * 10 - 1 cash -= 80 * 10 + 1 orders = [['X', 'sell', 80, 10, 1], [target, 'buy', 80, 10, 1]] mark = {'X': 10.2, 'A': 10.1}[target] return {'cash': cash, 'orders': orders, 'fees': sum(order[4] for order in orders), 'equity': round(cash + 80 * mark, 6)} assert account('X')['equity'] == 1016 and account('A')['equity'] == 1006 assert account('X')['orders'] == [] assert account('A')['orders'] == [['X', 'sell', 80, 10, 1], ['A', 'buy', 80, 10, 1]] assert account('X')['cash'] == 200 and account('A')['cash'] == 198 assert sum(order[4] for order in account('X')['orders']) == 0 assert sum(order[4] for order in account('A')['orders']) == 2 assert account('X')['fees'] == 0 and account('A')['fees'] == 2 print(json.dumps({'unchanged_members': {'before': top(same, 2), 'after': top(same_clipped, 2), 'cap': same_cap}, 'changed_scores': clipped, 'cap': cap, 'raw_account': account('X'), 'clipped_account': account('A')}))