mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-15 03:23:52 +00:00
Merge pull request #1815 from c9s/c9s/d2t/ignore-dust-deposits
IMPROVE: [deposit2transfer] ignore dust amount
This commit is contained in:
commit
ac0dfff59d
|
@ -29,6 +29,8 @@ var groupIdRegExp = regexp.MustCompile(`^<!subteam\^(.+?)>$`)
|
|||
|
||||
var emailRegExp = regexp.MustCompile("`^(?P<name>[a-zA-Z0-9.!#$%&'*+/=?^_ \\x60{|}~-]+)@(?P<domain>[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$`gm")
|
||||
|
||||
var typeNamePrefixRE = regexp.MustCompile(`^\*?([a-zA-Z0-9_]+\.)?`)
|
||||
|
||||
type notifyTask struct {
|
||||
channel string
|
||||
|
||||
|
@ -521,7 +523,7 @@ func diffsToComment(obj any, diffs []dynamic.Diff) (text string) {
|
|||
return text
|
||||
}
|
||||
|
||||
text += fmt.Sprintf("%T updated\n", obj)
|
||||
text += fmt.Sprintf("_%s_ updated\n", objectName(obj))
|
||||
|
||||
for _, diff := range diffs {
|
||||
text += fmt.Sprintf("- %s: `%s` transited to `%s`\n", diff.Field, diff.Before, diff.After)
|
||||
|
@ -529,3 +531,17 @@ func diffsToComment(obj any, diffs []dynamic.Diff) (text string) {
|
|||
|
||||
return text
|
||||
}
|
||||
|
||||
func objectName(obj any) string {
|
||||
type labelInf interface {
|
||||
Label() string
|
||||
}
|
||||
|
||||
if ll, ok := obj.(labelInf); ok {
|
||||
return ll.Label()
|
||||
}
|
||||
|
||||
typeName := fmt.Sprintf("%T", obj)
|
||||
typeName = typeNamePrefixRE.ReplaceAllString(typeName, "")
|
||||
return typeName
|
||||
}
|
||||
|
|
22
pkg/notifier/slacknotifier/slack_test.go
Normal file
22
pkg/notifier/slacknotifier/slack_test.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
package slacknotifier
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
func Test_objectName(t *testing.T) {
|
||||
t.Run("deposit", func(t *testing.T) {
|
||||
var deposit = &types.Deposit{}
|
||||
assert.Equal(t, "Deposit", objectName(deposit))
|
||||
})
|
||||
|
||||
t.Run("local type", func(t *testing.T) {
|
||||
type A struct{}
|
||||
var obj = &A{}
|
||||
assert.Equal(t, "A", objectName(obj))
|
||||
})
|
||||
}
|
|
@ -55,6 +55,9 @@ type Strategy struct {
|
|||
Interval types.Duration `json:"interval"`
|
||||
TransferDelay types.Duration `json:"transferDelay"`
|
||||
|
||||
IgnoreDust bool `json:"ignoreDust"`
|
||||
DustAmounts map[string]fixedpoint.Value `json:"dustAmounts"`
|
||||
|
||||
SlackAlert *SlackAlert `json:"slackAlert"`
|
||||
|
||||
marginTransferService marginTransferService
|
||||
|
@ -85,6 +88,15 @@ func (s *Strategy) Defaults() error {
|
|||
s.TransferDelay = types.Duration(3 * time.Second)
|
||||
}
|
||||
|
||||
if s.DustAmounts == nil {
|
||||
s.DustAmounts = map[string]fixedpoint.Value{
|
||||
"USDC": fixedpoint.NewFromFloat(1.0),
|
||||
"USDT": fixedpoint.NewFromFloat(1.0),
|
||||
"BTC": fixedpoint.NewFromFloat(0.00001),
|
||||
"ETH": fixedpoint.NewFromFloat(0.00001),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -129,6 +141,16 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Strategy) isDust(asset string, amount fixedpoint.Value) bool {
|
||||
if s.IgnoreDust {
|
||||
if dustAmount, ok := s.DustAmounts[asset]; ok {
|
||||
return amount.Compare(dustAmount) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Strategy) tickWatcher(ctx context.Context, interval time.Duration) {
|
||||
ticker := time.NewTicker(interval)
|
||||
defer ticker.Stop()
|
||||
|
@ -284,6 +306,10 @@ func (s *Strategy) scanDepositHistory(ctx context.Context, asset string, duratio
|
|||
continue
|
||||
}
|
||||
|
||||
if s.isDust(asset, deposit.Amount) {
|
||||
continue
|
||||
}
|
||||
|
||||
// if the deposit record is already in the watch list, update it
|
||||
if _, ok := s.watchingDeposits[deposit.TransactionID]; ok {
|
||||
s.addWatchingDeposit(deposit)
|
||||
|
|
|
@ -28,6 +28,7 @@ type StreamBookSetter interface {
|
|||
type OrderBookBestPriceVolumeSignal struct {
|
||||
RatioThreshold fixedpoint.Value `json:"ratioThreshold"`
|
||||
MinVolume fixedpoint.Value `json:"minVolume"`
|
||||
MinQuoteVolume fixedpoint.Value `json:"minQuoteVolume"`
|
||||
|
||||
symbol string
|
||||
book *types.StreamOrderBook
|
||||
|
|
|
@ -28,6 +28,21 @@ const (
|
|||
DepositCredited = DepositStatus("credited")
|
||||
)
|
||||
|
||||
func (s DepositStatus) SlackEmoji() string {
|
||||
switch s {
|
||||
case DepositPending:
|
||||
return ":hourglass_not_done:"
|
||||
case DepositCredited:
|
||||
return ":dollar_banknote:"
|
||||
case DepositSuccess:
|
||||
return ":check_mark_button:"
|
||||
case DepositCancelled:
|
||||
return ":stop_button:"
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
type Deposit struct {
|
||||
GID int64 `json:"gid" db:"gid"`
|
||||
Exchange ExchangeName `json:"exchange" db:"exchange"`
|
||||
|
@ -106,7 +121,7 @@ func (d *Deposit) SlackAttachment() slack.Attachment {
|
|||
if len(d.Status) > 0 {
|
||||
fields = append(fields, slack.AttachmentField{
|
||||
Title: "Status",
|
||||
Value: string(d.Status),
|
||||
Value: string(d.Status) + " " + d.Status.SlackEmoji(),
|
||||
Short: false,
|
||||
})
|
||||
}
|
||||
|
@ -138,21 +153,59 @@ func (d *Deposit) SlackAttachment() slack.Attachment {
|
|||
})
|
||||
|
||||
return slack.Attachment{
|
||||
Color: depositStatusSlackColor(d.Status),
|
||||
Title: fmt.Sprintf("Deposit %s %s To %s (%s)", d.Amount.String(), d.Asset, d.Address, d.Exchange),
|
||||
// TitleLink: "",
|
||||
Pretext: "",
|
||||
Text: "",
|
||||
Color: depositStatusSlackColor(d.Status),
|
||||
Fallback: "",
|
||||
ID: 0,
|
||||
Title: fmt.Sprintf("Deposit %s %s To %s (%s)", d.Amount.String(), d.Asset, d.Address, d.Exchange),
|
||||
TitleLink: getExplorerURL(d.Network, d.TransactionID),
|
||||
Pretext: "",
|
||||
Text: "",
|
||||
ImageURL: "",
|
||||
ThumbURL: "",
|
||||
ServiceName: "",
|
||||
ServiceIcon: "",
|
||||
FromURL: "",
|
||||
OriginalURL: "",
|
||||
// ServiceName: "",
|
||||
// ServiceIcon: "",
|
||||
// FromURL: "",
|
||||
// OriginalURL: "",
|
||||
Fields: fields,
|
||||
Actions: nil,
|
||||
MarkdownIn: nil,
|
||||
Blocks: slack.Blocks{},
|
||||
Footer: fmt.Sprintf("Apply Time: %s", d.Time.Time().Format(time.RFC3339)),
|
||||
FooterIcon: ExchangeFooterIcon(d.Exchange),
|
||||
Ts: "",
|
||||
}
|
||||
}
|
||||
|
||||
func getExplorerURL(network string, txID string) string {
|
||||
switch strings.ToUpper(network) {
|
||||
case "BTC":
|
||||
return getBitcoinNetworkExplorerURL(txID)
|
||||
case "BSC":
|
||||
return getBscNetworkExplorerURL(txID)
|
||||
case "ETH":
|
||||
return getEthNetworkExplorerURL(txID)
|
||||
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func getEthNetworkExplorerURL(txID string) string {
|
||||
return "https://etherscan.io/tx/" + txID
|
||||
}
|
||||
|
||||
func getBitcoinNetworkExplorerURL(txID string) string {
|
||||
return "https://www.blockchain.com/explorer/transactions/btc/" + txID
|
||||
}
|
||||
|
||||
func getBscNetworkExplorerURL(txID string) string {
|
||||
return "https://bscscan.com/tx/" + txID
|
||||
}
|
||||
|
||||
func depositStatusSlackColor(status DepositStatus) string {
|
||||
switch status {
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user