mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-27 17:25:16 +00:00
41 lines
1.2 KiB
Go
41 lines
1.2 KiB
Go
|
package riskcontrol
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||
|
indicatorv2 "github.com/c9s/bbgo/pkg/indicator/v2"
|
||
|
"github.com/c9s/bbgo/pkg/types"
|
||
|
)
|
||
|
|
||
|
type PriceRiskControl struct {
|
||
|
referencePrice *indicatorv2.EWMAStream
|
||
|
lossThreshold fixedpoint.Value
|
||
|
}
|
||
|
|
||
|
func NewPriceRiskControl(refPrice *indicatorv2.EWMAStream, threshold fixedpoint.Value) *PriceRiskControl {
|
||
|
return &PriceRiskControl{
|
||
|
referencePrice: refPrice,
|
||
|
lossThreshold: threshold,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (r *PriceRiskControl) IsSafe(side types.SideType, price fixedpoint.Value, quantity fixedpoint.Value) bool {
|
||
|
refPrice := fixedpoint.NewFromFloat(r.referencePrice.Last(0))
|
||
|
// calculate profit
|
||
|
var profit fixedpoint.Value
|
||
|
if side == types.SideTypeBuy {
|
||
|
profit = refPrice.Sub(price).Mul(quantity)
|
||
|
} else if side == types.SideTypeSell {
|
||
|
profit = price.Sub(refPrice).Mul(quantity)
|
||
|
}
|
||
|
return profit.Compare(r.lossThreshold) > 0
|
||
|
}
|
||
|
|
||
|
func (r *PriceRiskControl) IsSafeLimitOrder(o types.SubmitOrder) (bool, error) {
|
||
|
if !(o.Type == types.OrderTypeLimit || o.Type == types.OrderTypeLimitMaker) {
|
||
|
return false, fmt.Errorf("order type is not limit order")
|
||
|
}
|
||
|
return r.IsSafe(o.Side, o.Price, o.Quantity), nil
|
||
|
}
|