Skip to content

Commit

Permalink
Merge pull request #1815 from c9s/c9s/d2t/ignore-dust-deposits
Browse files Browse the repository at this point in the history
IMPROVE: [deposit2transfer] ignore dust amount
  • Loading branch information
c9s authored Nov 14, 2024
2 parents 66396f9 + 51909ba commit ac0dfff
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 7 deletions.
18 changes: 17 additions & 1 deletion pkg/notifier/slacknotifier/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -521,11 +523,25 @@ 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)
}

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 changes: 22 additions & 0 deletions pkg/notifier/slacknotifier/slack_test.go
Original file line number Diff line number Diff line change
@@ -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))
})
}
26 changes: 26 additions & 0 deletions pkg/strategy/deposit2transfer/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions pkg/strategy/xmaker/signal_book.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
65 changes: 59 additions & 6 deletions pkg/types/deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down Expand Up @@ -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,
})
}
Expand Down Expand Up @@ -138,19 +153,57 @@ 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 {
Expand Down

0 comments on commit ac0dfff

Please sign in to comment.