2022-06-28 17:58:15 +00:00
package bbgo
2022-06-26 08:13:58 +00:00
import (
"context"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
)
2022-06-28 17:58:15 +00:00
// RoiTakeProfit force takes the profit by the given ROI percentage.
2022-06-26 08:13:58 +00:00
type RoiTakeProfit struct {
2022-10-28 09:56:07 +00:00
Symbol string ` json:"symbol" `
Percentage fixedpoint . Value ` json:"percentage" `
CancelActiveOrders bool ` json:"cancelActiveOrders" `
2022-06-26 08:13:58 +00:00
2024-02-28 06:30:22 +00:00
// Interval is the time resolution to update the stop order
// KLine per Interval will be used for updating the stop order
Interval types . Interval ` json:"interval,omitempty" `
2022-06-28 17:58:15 +00:00
session * ExchangeSession
orderExecutor * GeneralOrderExecutor
2022-06-26 08:13:58 +00:00
}
2022-07-19 03:00:45 +00:00
func ( s * RoiTakeProfit ) Subscribe ( session * ExchangeSession ) {
2024-02-28 06:30:22 +00:00
// use kline to handle roi stop
2024-02-28 07:02:57 +00:00
if s . Interval == "" {
s . Interval = types . Interval1m
}
2024-02-28 06:30:22 +00:00
session . Subscribe ( types . KLineChannel , s . Symbol , types . SubscribeOptions { Interval : s . Interval } )
2022-07-19 03:00:45 +00:00
}
2022-06-28 17:58:15 +00:00
func ( s * RoiTakeProfit ) Bind ( session * ExchangeSession , orderExecutor * GeneralOrderExecutor ) {
2022-06-26 08:13:58 +00:00
s . session = session
s . orderExecutor = orderExecutor
position := orderExecutor . Position ( )
2024-02-28 06:30:22 +00:00
session . MarketDataStream . OnKLineClosed ( types . KLineWith ( s . Symbol , s . Interval , func ( kline types . KLine ) {
2022-06-26 08:13:58 +00:00
closePrice := kline . Close
2023-11-29 10:26:01 +00:00
if position . IsClosed ( ) || position . IsDust ( closePrice ) || position . IsClosing ( ) {
2022-06-26 08:13:58 +00:00
return
}
roi := position . ROI ( closePrice )
2022-08-10 15:45:21 +00:00
if roi . Compare ( s . Percentage ) >= 0 {
2022-06-26 08:13:58 +00:00
// stop loss
2022-06-28 17:58:15 +00:00
Notify ( "[RoiTakeProfit] %s take profit is triggered by ROI %s/%s, price: %f" , position . Symbol , roi . Percentage ( ) , s . Percentage . Percentage ( ) , kline . Close . Float64 ( ) )
2022-10-28 09:56:07 +00:00
if s . CancelActiveOrders {
_ = s . orderExecutor . GracefulCancel ( context . Background ( ) )
}
2022-06-27 10:17:57 +00:00
_ = orderExecutor . ClosePosition ( context . Background ( ) , fixedpoint . One , "roiTakeProfit" )
2022-06-26 08:13:58 +00:00
return
}
2022-08-10 15:45:21 +00:00
} ) )
2022-06-26 08:13:58 +00:00
}