diff --git a/pkg/risk/leverage.go b/pkg/risk/leverage.go new file mode 100644 index 000000000..451f20dbb --- /dev/null +++ b/pkg/risk/leverage.go @@ -0,0 +1,50 @@ +package risk + +import ( + "github.com/c9s/bbgo/pkg/fixedpoint" + "github.com/c9s/bbgo/pkg/types" +) + +// How to Calculate Cost Required to Open a Position in Perpetual Futures Contracts +// +// See +// +// For Long Position: +// = Number of Contract * Absolute Value {min[0, direction of order x (mark price - order price)]} +// +// For short position: +// = Number of Contract * Absolute Value {min[0, direction of order x (mark price - order price)]} +func CalculateOpenLoss(numContract, markPrice, orderPrice fixedpoint.Value, side types.SideType) fixedpoint.Value { + var d = fixedpoint.One + if side == types.SideTypeSell { + d = fixedpoint.NegOne + } + + var openLoss = numContract.Mul(fixedpoint.Min(fixedpoint.Zero, d.Mul(markPrice.Sub(orderPrice))).Abs()) + return openLoss +} + +func CalculateMarginCost(price, quantity, leverage fixedpoint.Value) fixedpoint.Value { + var notionalValue = price.Mul(quantity) + var cost = notionalValue.Div(leverage) + return cost +} + +func CalculatePositionCost(markPrice, orderPrice, quantity, leverage fixedpoint.Value, side types.SideType) fixedpoint.Value { + var marginCost = CalculateMarginCost(orderPrice, quantity, leverage) + var openLoss = CalculateOpenLoss(quantity, markPrice, orderPrice, side) + return marginCost.Add(openLoss) +} + +// CalculateMaxPosition calculates the maximum notional value of the position and return the max quantity you can use. +func CalculateMaxPosition(price, availableMargin, leverage fixedpoint.Value) fixedpoint.Value { + var maxNotionalValue = availableMargin.Mul(leverage) + var maxQuantity = maxNotionalValue.Div(price) + return maxQuantity +} + +// CalculateLeverage calculates the leverage of the given position (price and quantity) +func CalculateLeverage(price, quantity, availableMargin fixedpoint.Value) fixedpoint.Value { + var notional = price.Mul(quantity) + return notional.Div(availableMargin) +}