2023-06-29 07:06:03 +00:00
|
|
|
package riskcontrol
|
|
|
|
|
|
|
|
import (
|
2023-07-03 09:09:13 +00:00
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
|
2023-06-29 07:06:03 +00:00
|
|
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
2023-07-10 08:54:22 +00:00
|
|
|
"github.com/c9s/bbgo/pkg/indicator/v2"
|
2023-06-29 07:06:03 +00:00
|
|
|
"github.com/c9s/bbgo/pkg/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
type CircuitBreakRiskControl struct {
|
|
|
|
// Since price could be fluctuated large,
|
|
|
|
// use an EWMA to smooth it in running time
|
2023-07-10 08:54:22 +00:00
|
|
|
price *indicatorv2.EWMAStream
|
2023-07-03 09:09:13 +00:00
|
|
|
position *types.Position
|
|
|
|
profitStats *types.ProfitStats
|
|
|
|
lossThreshold fixedpoint.Value
|
2023-06-29 07:06:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewCircuitBreakRiskControl(
|
|
|
|
position *types.Position,
|
2023-07-10 08:54:22 +00:00
|
|
|
price *indicatorv2.EWMAStream,
|
2023-07-03 09:09:13 +00:00
|
|
|
lossThreshold fixedpoint.Value,
|
2023-06-29 07:06:03 +00:00
|
|
|
profitStats *types.ProfitStats) *CircuitBreakRiskControl {
|
|
|
|
|
|
|
|
return &CircuitBreakRiskControl{
|
2023-07-03 09:09:13 +00:00
|
|
|
price: price,
|
|
|
|
position: position,
|
|
|
|
profitStats: profitStats,
|
|
|
|
lossThreshold: lossThreshold,
|
2023-06-29 07:06:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsHalted returns whether we reached the circuit break condition set for this day?
|
|
|
|
func (c *CircuitBreakRiskControl) IsHalted() bool {
|
|
|
|
var unrealized = c.position.UnrealizedProfit(fixedpoint.NewFromFloat(c.price.Last(0)))
|
2023-07-03 09:09:13 +00:00
|
|
|
log.Infof("[CircuitBreakRiskControl] realized PnL = %f, unrealized PnL = %f\n",
|
|
|
|
c.profitStats.TodayPnL.Float64(),
|
|
|
|
unrealized.Float64())
|
|
|
|
return unrealized.Add(c.profitStats.TodayPnL).Compare(c.lossThreshold) <= 0
|
2023-06-29 07:06:03 +00:00
|
|
|
}
|