third version
This commit is contained in:
+13
-3
@@ -29,6 +29,8 @@ type SizingConfig struct {
|
||||
type SizingInput struct {
|
||||
Portfolio domain.Portfolio
|
||||
SelectedInstruments int
|
||||
ExistingExposure decimal.Decimal
|
||||
ReservedCash decimal.Decimal
|
||||
LimitPrice decimal.Decimal
|
||||
Lot int64
|
||||
EntryIntervalVolume decimal.Decimal
|
||||
@@ -66,11 +68,19 @@ func (s Sizer) Size(input SizingInput) SizingResult {
|
||||
input.SelectedInstruments = 1
|
||||
}
|
||||
capLimit := input.Portfolio.Equity.Mul(s.cfg.MaxPositionPct)
|
||||
exposureLimit := input.Portfolio.Equity.Mul(s.cfg.MaxTotalExposurePct).
|
||||
Div(decimal.NewFromInt(int64(input.SelectedInstruments)))
|
||||
totalExposureLimit := input.Portfolio.Equity.Mul(s.cfg.MaxTotalExposurePct)
|
||||
remainingExposure := totalExposureLimit.Sub(input.ExistingExposure)
|
||||
if remainingExposure.IsNegative() {
|
||||
remainingExposure = decimal.Zero
|
||||
}
|
||||
exposureLimit := remainingExposure.Div(decimal.NewFromInt(int64(input.SelectedInstruments)))
|
||||
liquidityLimit := money.Min(input.EntryIntervalVolume, input.ExitIntervalVolume).
|
||||
Mul(s.cfg.MaxParticipationRate)
|
||||
cashLimit := input.Portfolio.Cash.Mul(s.cfg.CashUsageBuffer)
|
||||
availableCash := input.Portfolio.Cash.Sub(input.ReservedCash)
|
||||
if availableCash.IsNegative() {
|
||||
availableCash = decimal.Zero
|
||||
}
|
||||
cashLimit := availableCash.Mul(s.cfg.CashUsageBuffer)
|
||||
riskLimit := capLimit
|
||||
if input.Q05OvernightAbs.IsPositive() {
|
||||
riskBudget := input.Portfolio.Equity.Mul(s.cfg.RiskBudgetPerInstrumentPct)
|
||||
|
||||
@@ -170,3 +170,28 @@ func TestSizerAppliesSizeReductionFactor(t *testing.T) {
|
||||
t.Fatalf("unexpected reduced sizing: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSizerSubtractsExistingExposureAndReservedCash(t *testing.T) {
|
||||
sizer := NewSizer(SizingConfig{
|
||||
MaxPositionPct: rd("1"),
|
||||
MaxTotalExposurePct: rd("0.50"),
|
||||
MaxParticipationRate: rd("1"),
|
||||
CashUsageBuffer: rd("1"),
|
||||
RiskBudgetPerInstrumentPct: rd("1"),
|
||||
MinOrderNotionalRUB: rd("1"),
|
||||
})
|
||||
got := sizer.Size(SizingInput{
|
||||
Portfolio: domain.Portfolio{Equity: rd("100000"), Cash: rd("50000")},
|
||||
SelectedInstruments: 2,
|
||||
ExistingExposure: rd("30000"),
|
||||
ReservedCash: rd("10000"),
|
||||
LimitPrice: rd("100"),
|
||||
Lot: 1,
|
||||
EntryIntervalVolume: rd("1000000"),
|
||||
ExitIntervalVolume: rd("1000000"),
|
||||
Q05OvernightAbs: rd("1"),
|
||||
})
|
||||
if got.Lots != 100 || !got.TargetNotional.Equal(rd("10000")) {
|
||||
t.Fatalf("unexpected sizing with reserved exposure: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user