Save this Python 3 code as pareto.py and run python3 pareto.py. It has no external dependencies. The zero-cost IDs are A, B, C and B-copy; at 10 bps they are B, C and B-copy. Comparisons use full floating-point values; rounding happens only in the printed table. The all-pairs calculation takes quadratic time in the candidate count.
Independent educational calculation. This is not a TradingView CSV parser or a built-in Backtest Deep Report feature.python
from math import isfinite
# Hypothetical account units; each interval includes all executed sides.
candidates = {
"A": ([10, -6, 10], [1000, 1000, 1000]),
"B": ([6, -4, 10], [200, 200, 200]),
"C": ([4, -2, 5], [100, 100, 100]),
"D": ([5, -5, 9], [300, 300, 300]),
"B-copy": ([6, -4, 10], [200, 200, 200]),
}
def metrics(pnl, traded, cost, initial=100):
if not pnl or len(pnl) != len(traded):
raise ValueError("Need matching nonempty interval arrays")
if not all(isfinite(x) for x in [initial, cost, *pnl, *traded]):
raise ValueError("Inputs must be finite")
if initial <= 0 or cost < 0 or any(x < 0 for x in traded):
raise ValueError("Invalid capital, cost or traded amount")
equity = peak = initial
drawdown = 0.0
for gross, notional in zip(pnl, traded):
equity += gross - cost * notional
if equity <= 0:
raise ValueError("Insolvent path: excluded by this example")
peak = max(peak, equity)
drawdown = max(drawdown, (peak - equity) / peak)
return ((equity - initial) / initial, drawdown, sum(traded) / initial)
def dominates(a, b):
# Maximize return, minimize drawdown and turnover.
no_worse = a[0] >= b[0] and a[1] <= b[1] and a[2] <= b[2]
better = a[0] > b[0] or a[1] < b[1] or a[2] < b[2]
return no_worse and better
def frontier(points):
if any(len(p) != 3 or not all(isfinite(x) for x in p)
or p[1] < 0 or p[2] < 0 for p in points.values()):
raise ValueError("Need finite return, nonnegative risk and turnover")
return [name for name, p in points.items()
if not any(dominates(q, p) for q in points.values())]
for cost in (0, 0.001):
points = {name: metrics(*inputs, cost) for name, inputs in candidates.items()}
print(f"Cost {cost * 10000:.0f} bps: {frontier(points)}")
for name, (ret, dd, turnover) in points.items():
print(f" {name}: return={ret:.4%}, drawdown={dd:.4%}, turnover={turnover:g}x")
assert frontier({}) == []
assert frontier({"x": (0, 0, 0)}) == ["x"]
assert not dominates((0.12, 0.04, 6), (0.12, 0.04, 6))
assert dominates((0.12, 0.03, 6), (0.12, 0.04, 6))
assert dominates((-0.01, 0.03, 6), (-0.02, 0.04, 7))