[ { "name": "a 60/40 portfolio exactly on target", "args": [ [ { "id": "EQUITY", "value": { "minor": 600000, "currency": "GBP" }, "targetBasisPoints": 6000 }, { "id": "BONDS", "value": { "minor": 400000, "currency": "GBP" }, "targetBasisPoints": 4000 } ] ], "expect": { "total": { "minor": 1000000, "currency": "GBP" }, "holdings": [ { "id": "EQUITY", "value": { "minor": 600000, "currency": "GBP" }, "weightBasisPoints": 6000, "targetBasisPoints": 6000, "driftBasisPoints": 0, "targetValue": { "minor": 600000, "currency": "GBP" }, "driftValue": { "minor": 0, "currency": "GBP" } }, { "id": "BONDS", "value": { "minor": 400000, "currency": "GBP" }, "weightBasisPoints": 4000, "targetBasisPoints": 4000, "driftBasisPoints": 0, "targetValue": { "minor": 400000, "currency": "GBP" }, "driftValue": { "minor": 0, "currency": "GBP" } } ], "maxAbsDriftBasisPoints": 0 } }, { "name": "equities have run up to 70% against a 60% target", "args": [ [ { "id": "EQUITY", "value": { "minor": 700000, "currency": "GBP" }, "targetBasisPoints": 6000 }, { "id": "BONDS", "value": { "minor": 300000, "currency": "GBP" }, "targetBasisPoints": 4000 } ] ], "expect": { "total": { "minor": 1000000, "currency": "GBP" }, "holdings": [ { "id": "EQUITY", "value": { "minor": 700000, "currency": "GBP" }, "weightBasisPoints": 7000, "targetBasisPoints": 6000, "driftBasisPoints": 1000, "targetValue": { "minor": 600000, "currency": "GBP" }, "driftValue": { "minor": 100000, "currency": "GBP" } }, { "id": "BONDS", "value": { "minor": 300000, "currency": "GBP" }, "weightBasisPoints": 3000, "targetBasisPoints": 4000, "driftBasisPoints": -1000, "targetValue": { "minor": 400000, "currency": "GBP" }, "driftValue": { "minor": -100000, "currency": "GBP" } } ], "maxAbsDriftBasisPoints": 1000 } }, { "name": "three equal holdings are 3333 bp each and the weights do not sum to 10000", "args": [ [ { "id": "A", "value": { "minor": 100, "currency": "GBP" }, "targetBasisPoints": 3333 }, { "id": "B", "value": { "minor": 100, "currency": "GBP" }, "targetBasisPoints": 3333 }, { "id": "C", "value": { "minor": 100, "currency": "GBP" }, "targetBasisPoints": 3334 } ] ], "expect": { "total": { "minor": 300, "currency": "GBP" }, "holdings": [ { "id": "A", "value": { "minor": 100, "currency": "GBP" }, "weightBasisPoints": 3333, "targetBasisPoints": 3333, "driftBasisPoints": 0, "targetValue": { "minor": 100, "currency": "GBP" }, "driftValue": { "minor": 0, "currency": "GBP" } }, { "id": "B", "value": { "minor": 100, "currency": "GBP" }, "weightBasisPoints": 3333, "targetBasisPoints": 3333, "driftBasisPoints": 0, "targetValue": { "minor": 100, "currency": "GBP" }, "driftValue": { "minor": 0, "currency": "GBP" } }, { "id": "C", "value": { "minor": 100, "currency": "GBP" }, "weightBasisPoints": 3333, "targetBasisPoints": 3334, "driftBasisPoints": -1, "targetValue": { "minor": 100, "currency": "GBP" }, "driftValue": { "minor": 0, "currency": "GBP" } } ], "maxAbsDriftBasisPoints": 1 } }, { "name": "half a basis point rounds up for both holdings, so the weights sum to 10001", "args": [ [ { "id": "A", "value": { "minor": 1, "currency": "GBP" }, "targetBasisPoints": 0 }, { "id": "B", "value": { "minor": 19999, "currency": "GBP" }, "targetBasisPoints": 10000 } ] ], "expect": { "total": { "minor": 20000, "currency": "GBP" }, "holdings": [ { "id": "A", "value": { "minor": 1, "currency": "GBP" }, "weightBasisPoints": 1, "targetBasisPoints": 0, "driftBasisPoints": 1, "targetValue": { "minor": 0, "currency": "GBP" }, "driftValue": { "minor": 1, "currency": "GBP" } }, { "id": "B", "value": { "minor": 19999, "currency": "GBP" }, "weightBasisPoints": 10000, "targetBasisPoints": 10000, "driftBasisPoints": -1, "targetValue": { "minor": 20000, "currency": "GBP" }, "driftValue": { "minor": -1, "currency": "GBP" } } ], "maxAbsDriftBasisPoints": 1 } }, { "name": "drift comes from the exact values, not weight minus target: -0.5 bp is -1, not 1 - 1 = 0", "args": [ [ { "id": "A", "value": { "minor": 1, "currency": "GBP" }, "targetBasisPoints": 1 }, { "id": "B", "value": { "minor": 19999, "currency": "GBP" }, "targetBasisPoints": 9999 } ] ], "expect": { "total": { "minor": 20000, "currency": "GBP" }, "holdings": [ { "id": "A", "value": { "minor": 1, "currency": "GBP" }, "weightBasisPoints": 1, "targetBasisPoints": 1, "driftBasisPoints": -1, "targetValue": { "minor": 2, "currency": "GBP" }, "driftValue": { "minor": -1, "currency": "GBP" } }, { "id": "B", "value": { "minor": 19999, "currency": "GBP" }, "weightBasisPoints": 10000, "targetBasisPoints": 9999, "driftBasisPoints": 1, "targetValue": { "minor": 19998, "currency": "GBP" }, "driftValue": { "minor": 1, "currency": "GBP" } } ], "maxAbsDriftBasisPoints": 1 } }, { "name": "a new fund worth nothing yet is fully underweight", "args": [ [ { "id": "OLD", "value": { "minor": 500000, "currency": "GBP" }, "targetBasisPoints": 5000 }, { "id": "NEW", "value": { "minor": 0, "currency": "GBP" }, "targetBasisPoints": 5000 } ] ], "expect": { "total": { "minor": 500000, "currency": "GBP" }, "holdings": [ { "id": "OLD", "value": { "minor": 500000, "currency": "GBP" }, "weightBasisPoints": 10000, "targetBasisPoints": 5000, "driftBasisPoints": 5000, "targetValue": { "minor": 250000, "currency": "GBP" }, "driftValue": { "minor": 250000, "currency": "GBP" } }, { "id": "NEW", "value": { "minor": 0, "currency": "GBP" }, "weightBasisPoints": 0, "targetBasisPoints": 5000, "driftBasisPoints": -5000, "targetValue": { "minor": 250000, "currency": "GBP" }, "driftValue": { "minor": -250000, "currency": "GBP" } } ], "maxAbsDriftBasisPoints": 5000 } }, { "name": "a holding with a zero target is all drift", "args": [ [ { "id": "KEEP", "value": { "minor": 750000, "currency": "GBP" }, "targetBasisPoints": 10000 }, { "id": "SELL", "value": { "minor": 250000, "currency": "GBP" }, "targetBasisPoints": 0 } ] ], "expect": { "total": { "minor": 1000000, "currency": "GBP" }, "holdings": [ { "id": "KEEP", "value": { "minor": 750000, "currency": "GBP" }, "weightBasisPoints": 7500, "targetBasisPoints": 10000, "driftBasisPoints": -2500, "targetValue": { "minor": 1000000, "currency": "GBP" }, "driftValue": { "minor": -250000, "currency": "GBP" } }, { "id": "SELL", "value": { "minor": 250000, "currency": "GBP" }, "weightBasisPoints": 2500, "targetBasisPoints": 0, "driftBasisPoints": 2500, "targetValue": { "minor": 0, "currency": "GBP" }, "driftValue": { "minor": 250000, "currency": "GBP" } } ], "maxAbsDriftBasisPoints": 2500 } }, { "name": "values whose x10000 passes 2^53 stay exact", "args": [ [ { "id": "A", "value": { "minor": 900000000000000, "currency": "GBP" }, "targetBasisPoints": 5000 }, { "id": "B", "value": { "minor": 100000000000000, "currency": "GBP" }, "targetBasisPoints": 5000 } ] ], "expect": { "total": { "minor": 1000000000000000, "currency": "GBP" }, "holdings": [ { "id": "A", "value": { "minor": 900000000000000, "currency": "GBP" }, "weightBasisPoints": 9000, "targetBasisPoints": 5000, "driftBasisPoints": 4000, "targetValue": { "minor": 500000000000000, "currency": "GBP" }, "driftValue": { "minor": 400000000000000, "currency": "GBP" } }, { "id": "B", "value": { "minor": 100000000000000, "currency": "GBP" }, "weightBasisPoints": 1000, "targetBasisPoints": 5000, "driftBasisPoints": -4000, "targetValue": { "minor": 500000000000000, "currency": "GBP" }, "driftValue": { "minor": -400000000000000, "currency": "GBP" } } ], "maxAbsDriftBasisPoints": 4000 } }, { "name": "a single holding is the whole portfolio", "args": [ [ { "id": "ONLY", "value": { "minor": 12345, "currency": "GBP" }, "targetBasisPoints": 10000 } ] ], "expect": { "total": { "minor": 12345, "currency": "GBP" }, "holdings": [ { "id": "ONLY", "value": { "minor": 12345, "currency": "GBP" }, "weightBasisPoints": 10000, "targetBasisPoints": 10000, "driftBasisPoints": 0, "targetValue": { "minor": 12345, "currency": "GBP" }, "driftValue": { "minor": 0, "currency": "GBP" } } ], "maxAbsDriftBasisPoints": 0 } }, { "name": "a third of a basis point rounds down both ways", "args": [ [ { "id": "A", "value": { "minor": 33333, "currency": "GBP" }, "targetBasisPoints": 3000 }, { "id": "B", "value": { "minor": 66667, "currency": "GBP" }, "targetBasisPoints": 7000 } ] ], "expect": { "total": { "minor": 100000, "currency": "GBP" }, "holdings": [ { "id": "A", "value": { "minor": 33333, "currency": "GBP" }, "weightBasisPoints": 3333, "targetBasisPoints": 3000, "driftBasisPoints": 333, "targetValue": { "minor": 30000, "currency": "GBP" }, "driftValue": { "minor": 3333, "currency": "GBP" } }, { "id": "B", "value": { "minor": 66667, "currency": "GBP" }, "weightBasisPoints": 6667, "targetBasisPoints": 7000, "driftBasisPoints": -333, "targetValue": { "minor": 70000, "currency": "GBP" }, "driftValue": { "minor": -3333, "currency": "GBP" } } ], "maxAbsDriftBasisPoints": 333 } }, { "name": "an empty portfolio is an error", "args": [ [] ], "expectError": "holdings must not be empty" }, { "name": "the same id twice is an error", "args": [ [ { "id": "A", "value": { "minor": 1, "currency": "GBP" }, "targetBasisPoints": 5000 }, { "id": "A", "value": { "minor": 1, "currency": "GBP" }, "targetBasisPoints": 5000 } ] ], "expectError": "duplicate holding id \"A\"" }, { "name": "targets summing to 9999 are an error", "args": [ [ { "id": "A", "value": { "minor": 1, "currency": "GBP" }, "targetBasisPoints": 5000 }, { "id": "B", "value": { "minor": 1, "currency": "GBP" }, "targetBasisPoints": 4999 } ] ], "expectError": "targets must sum to 10000 basis points, received 9999" }, { "name": "mixed currencies are an error", "args": [ [ { "id": "A", "value": { "minor": 1, "currency": "GBP" }, "targetBasisPoints": 5000 }, { "id": "B", "value": { "minor": 1, "currency": "USD" }, "targetBasisPoints": 5000 } ] ], "expectError": "currency mismatch: GBP and USD" }, { "name": "a negative value is an error", "args": [ [ { "id": "A", "value": { "minor": -1, "currency": "GBP" }, "targetBasisPoints": 5000 }, { "id": "B", "value": { "minor": 10, "currency": "GBP" }, "targetBasisPoints": 5000 } ] ], "expectError": "holding values must be whole minor units, 0 or more" }, { "name": "a fractional minor unit is an error", "args": [ [ { "id": "A", "value": { "minor": 1.5, "currency": "GBP" }, "targetBasisPoints": 5000 }, { "id": "B", "value": { "minor": 10, "currency": "GBP" }, "targetBasisPoints": 5000 } ] ], "expectError": "holding values must be whole minor units, 0 or more" }, { "name": "a target above 10000 is an error even if the sum works out", "args": [ [ { "id": "A", "value": { "minor": 1, "currency": "GBP" }, "targetBasisPoints": 10001 }, { "id": "B", "value": { "minor": 1, "currency": "GBP" }, "targetBasisPoints": -1 } ] ], "expectError": "targetBasisPoints must be a whole number from 0 to 10000" }, { "name": "a fractional target is an error", "args": [ [ { "id": "A", "value": { "minor": 1, "currency": "GBP" }, "targetBasisPoints": 2500.5 }, { "id": "B", "value": { "minor": 1, "currency": "GBP" }, "targetBasisPoints": 7499.5 } ] ], "expectError": "targetBasisPoints must be a whole number from 0 to 10000" }, { "name": "a portfolio worth nothing is an error", "args": [ [ { "id": "A", "value": { "minor": 0, "currency": "GBP" }, "targetBasisPoints": 5000 }, { "id": "B", "value": { "minor": 0, "currency": "GBP" }, "targetBasisPoints": 5000 } ] ], "expectError": "the portfolio total must be greater than zero" } ]