"""虚构费率的独立往返现金对账,不代表现行市场或券商报价。""" import json from decimal import Decimal as D from decimal import InvalidOperation def fill(side, raw_price, quantity): if side not in ('buy', 'sell'): raise ValueError('side必须是buy或sell') if type(quantity) is not int or quantity <= 0: raise ValueError('quantity必须是正整数且不能是bool') try: reference = D(raw_price) except (InvalidOperation, TypeError, ValueError, OverflowError) as error: raise ValueError('price必须是有限正数') from error if not reference.is_finite() or reference <= 0: raise ValueError('price必须是有限正数') sign = D(1) if side == 'buy' else D(-1) price = reference * (D(1) + sign * D('.001')) notional = price * quantity commission = max(D(1), notional * D('.0003')) sell_charge = notional * D('.001') if side == 'sell' else D(0) delta = -notional - commission if side == 'buy' else notional - commission - sell_charge return {'side': side, 'price': price, 'quantity': quantity, 'notional': notional, 'commission': commission, 'sell_charge': sell_charge, 'cash_delta': delta} invalid_inputs = [('BUY', '10', 100), ('hold', '10', 100), ('buy', '10', 0), ('buy', '10', -1), ('buy', '10', 1.5), ('buy', '10', True), ('buy', '0', 100), ('buy', '-1', 100), ('buy', 'NaN', 100), ('buy', 'Infinity', 100), ('buy', 'not-a-price', 100)] unexpected = [] for args in invalid_inputs: try: fill(*args) except ValueError: pass except Exception as error: unexpected.append([repr(args), type(error).__name__]) else: unexpected.append([repr(args), 'accepted']) assert not unexpected, unexpected buy, sell = fill('buy', '10', 100), fill('sell', '10.5', 100) cash = D(2000) + buy['cash_delta'] + sell['cash_delta'] gross_raw = D(100) * (D('10.5') - D('10')) slippage = buy['notional'] - D(1000) + D(1050) - sell['notional'] net = cash - D(2000) assert buy['price'] == D('10.010') and sell['price'] == D('10.4895') assert buy['commission'] == sell['commission'] == D(1) assert buy['sell_charge'] == 0 and sell['sell_charge'] == D('1.04895') assert net == D('44.90105') and cash == D('2044.90105') assert gross_raw - slippage - D(2) - sell['sell_charge'] == net assert fill('buy', '10', 10000)['commission'] > 1 double_counted = net - slippage assert double_counted != net print(json.dumps({'buy': buy, 'sell': sell, 'raw_pnl': gross_raw, 'slippage': slippage, 'ending_cash': cash, 'net_pnl': net, 'double_counted_pnl': double_counted}, default=str))