mirror of
https://github.com/c9s/bbgo.git
synced 2024-09-20 08:11:08 +00:00
add transfer history command for calculating baseline and show transfer records
This commit is contained in:
parent
2d246c3f71
commit
ea7b501c26
10
cmd/pnl.go
10
cmd/pnl.go
|
@ -20,10 +20,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
PnLCmd.Flags().String("exchange", "", "target exchange")
|
pnlCmd.Flags().String("exchange", "", "target exchange")
|
||||||
PnLCmd.Flags().String("symbol", "BTCUSDT", "trading symbol")
|
pnlCmd.Flags().String("symbol", "BTCUSDT", "trading symbol")
|
||||||
PnLCmd.Flags().String("since", "", "pnl since time")
|
pnlCmd.Flags().String("since", "", "pnl since time")
|
||||||
RootCmd.AddCommand(PnLCmd)
|
RootCmd.AddCommand(pnlCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func connectMysql() (*sqlx.DB, error) {
|
func connectMysql() (*sqlx.DB, error) {
|
||||||
|
@ -50,7 +50,7 @@ func newExchange(n types.ExchangeName) types.Exchange {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var PnLCmd = &cobra.Command{
|
var pnlCmd = &cobra.Command{
|
||||||
Use: "pnl",
|
Use: "pnl",
|
||||||
Short: "pnl calculator",
|
Short: "pnl calculator",
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
|
|
172
cmd/transfers.go
Normal file
172
cmd/transfers.go
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sort"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
transferHistoryCmd.Flags().String("exchange", "", "target exchange")
|
||||||
|
transferHistoryCmd.Flags().String("asset", "BTC", "trading symbol")
|
||||||
|
transferHistoryCmd.Flags().String("since", "", "since time")
|
||||||
|
RootCmd.AddCommand(transferHistoryCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type TimeRecord struct {
|
||||||
|
Record interface{}
|
||||||
|
Time time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type timeSlice []TimeRecord
|
||||||
|
|
||||||
|
func (p timeSlice) Len() int {
|
||||||
|
return len(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p timeSlice) Less(i, j int) bool {
|
||||||
|
return p[i].Time.Before(p[j].Time)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p timeSlice) Swap(i, j int) {
|
||||||
|
p[i], p[j] = p[j], p[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var transferHistoryCmd = &cobra.Command{
|
||||||
|
Use: "transfer-history",
|
||||||
|
Short: "show transfer history",
|
||||||
|
|
||||||
|
SilenceUsage: true,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
_ = ctx
|
||||||
|
|
||||||
|
exchangeNameStr, err := cmd.Flags().GetString("exchange")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
exchangeName, err := types.ValidExchangeName(exchangeNameStr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
asset, err := cmd.Flags().GetString("asset")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// default
|
||||||
|
var now = time.Now()
|
||||||
|
var since = now.AddDate(-1, 0, 0)
|
||||||
|
var until = now
|
||||||
|
|
||||||
|
sinceStr, err := cmd.Flags().GetString("since")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sinceStr) > 0 {
|
||||||
|
loc, err := time.LoadLocation("Asia/Taipei")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
since, err = time.ParseInLocation("2006-01-02", sinceStr, loc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
exchange := newExchange(exchangeName)
|
||||||
|
|
||||||
|
var records timeSlice
|
||||||
|
|
||||||
|
deposits, err := exchange.QueryDepositHistory(ctx, asset, since, until)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, d := range deposits {
|
||||||
|
records = append(records, TimeRecord{
|
||||||
|
Record: d,
|
||||||
|
Time: d.EffectiveTime(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
withdraws, err := exchange.QueryWithdrawHistory(ctx, asset, since, until)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, w := range withdraws {
|
||||||
|
records = append(records, TimeRecord{
|
||||||
|
Record: w,
|
||||||
|
Time: w.EffectiveTime(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(records)
|
||||||
|
|
||||||
|
for _, record := range records {
|
||||||
|
switch record := record.Record.(type) {
|
||||||
|
|
||||||
|
case types.Deposit:
|
||||||
|
log.Infof("%s: %s <== (deposit) %f [%s]", record.Time, record.Asset, record.Amount, record.Status)
|
||||||
|
|
||||||
|
case types.Withdraw:
|
||||||
|
log.Infof("%s: %s ==> (withdraw) %f [%s]", record.ApplyTime, record.Asset, record.Amount, record.Status)
|
||||||
|
|
||||||
|
default:
|
||||||
|
log.Infof("unknown record: %+v", record)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stats := calBaselineStats(asset, deposits, withdraws)
|
||||||
|
log.Infof("total %s deposit: %f (x %d)", asset, stats.TotalDeposit, stats.NumOfDeposit)
|
||||||
|
log.Infof("total %s withdraw: %f (x %d)", asset, stats.TotalWithdraw, stats.NumOfWithdraw)
|
||||||
|
log.Infof("baseline %s balance: %f", asset, stats.BaselineBalance)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
type BaselineStats struct {
|
||||||
|
Asset string
|
||||||
|
NumOfDeposit int
|
||||||
|
NumOfWithdraw int
|
||||||
|
TotalDeposit float64
|
||||||
|
TotalWithdraw float64
|
||||||
|
BaselineBalance float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func calBaselineStats(asset string, deposits []types.Deposit, withdraws []types.Withdraw) (stats BaselineStats) {
|
||||||
|
stats.Asset = asset
|
||||||
|
stats.NumOfDeposit = len(deposits)
|
||||||
|
stats.NumOfWithdraw = len(withdraws)
|
||||||
|
|
||||||
|
for _, deposit := range deposits {
|
||||||
|
if deposit.Status == types.DepositSuccess {
|
||||||
|
stats.TotalDeposit += deposit.Amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, withdraw := range withdraws {
|
||||||
|
if withdraw.Status == "completed" {
|
||||||
|
stats.TotalWithdraw += withdraw.Amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.BaselineBalance = stats.TotalDeposit - stats.TotalWithdraw
|
||||||
|
return stats
|
||||||
|
}
|
|
@ -33,6 +33,10 @@ func New(key, secret string) *Exchange {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Exchange) Name() types.ExchangeName {
|
||||||
|
return types.ExchangeBinance
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Exchange) QueryAveragePrice(ctx context.Context, symbol string) (float64, error) {
|
func (e *Exchange) QueryAveragePrice(ctx context.Context, symbol string) (float64, error) {
|
||||||
resp, err := e.Client.NewAveragePriceService().Symbol(symbol).Do(ctx)
|
resp, err := e.Client.NewAveragePriceService().Symbol(symbol).Do(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -46,22 +50,7 @@ func (e *Exchange) NewStream() types.Stream {
|
||||||
return NewStream(e.Client)
|
return NewStream(e.Client)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Withdraw struct {
|
func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since, until time.Time) (allWithdraws []types.Withdraw, err error) {
|
||||||
ID string `json:"id"`
|
|
||||||
Asset string `json:"asset"`
|
|
||||||
Amount float64 `json:"amount"`
|
|
||||||
Address string `json:"address"`
|
|
||||||
AddressTag string `json:"addressTag"`
|
|
||||||
Status string `json:"status"`
|
|
||||||
|
|
||||||
TransactionID string `json:"txId"`
|
|
||||||
TransactionFee float64 `json:"transactionFee"`
|
|
||||||
WithdrawOrderID string `json:"withdrawOrderId"`
|
|
||||||
ApplyTime time.Time `json:"applyTime"`
|
|
||||||
Network string `json:"network"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since, until time.Time) (allWithdraws []Withdraw, err error) {
|
|
||||||
|
|
||||||
startTime := since
|
startTime := since
|
||||||
txIDs := map[string]struct{}{}
|
txIDs := map[string]struct{}{}
|
||||||
|
@ -80,7 +69,7 @@ func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since
|
||||||
Do(ctx)
|
Do(ctx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return allWithdraws, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range withdraws {
|
for _, d := range withdraws {
|
||||||
|
@ -88,7 +77,6 @@ func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0(0:pending,6: credited but cannot withdraw, 1:success)
|
|
||||||
status := ""
|
status := ""
|
||||||
switch d.Status {
|
switch d.Status {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -111,7 +99,7 @@ func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since
|
||||||
}
|
}
|
||||||
|
|
||||||
txIDs[d.TxID] = struct{}{}
|
txIDs[d.TxID] = struct{}{}
|
||||||
allWithdraws = append(allWithdraws, Withdraw{
|
allWithdraws = append(allWithdraws, types.Withdraw{
|
||||||
ApplyTime: time.Unix(0, d.ApplyTime*int64(time.Millisecond)),
|
ApplyTime: time.Unix(0, d.ApplyTime*int64(time.Millisecond)),
|
||||||
Asset: d.Asset,
|
Asset: d.Asset,
|
||||||
Amount: d.Amount,
|
Amount: d.Amount,
|
||||||
|
|
|
@ -30,6 +30,10 @@ func New(key, secret string) *Exchange {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Exchange) Name() types.ExchangeName {
|
||||||
|
return types.ExchangeMax
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Exchange) NewStream() types.Stream {
|
func (e *Exchange) NewStream() types.Stream {
|
||||||
return NewStream(e.key, e.secret)
|
return NewStream(e.key, e.secret)
|
||||||
}
|
}
|
||||||
|
@ -83,26 +87,110 @@ func (e *Exchange) QueryAccount(ctx context.Context) (*types.Account, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exchange) QueryDepositHistory(ctx context.Context, asset string, since, until time.Time) (allDeposits []types.Deposit, err error) {
|
func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since, until time.Time) (allWithdraws []types.Withdraw, err error) {
|
||||||
deposits, err := e.client.AccountService.NewGetDepositHistoryRequest().
|
startTime := since
|
||||||
Currency(asset).
|
txIDs := map[string]struct{}{}
|
||||||
From(since.Unix()).
|
|
||||||
To(until.Unix()).Do(ctx)
|
|
||||||
|
|
||||||
if err != nil {
|
for startTime.Before(until) {
|
||||||
return nil, err
|
// startTime ~ endTime must be in 90 days
|
||||||
|
endTime := startTime.AddDate(0, 0, 60)
|
||||||
|
if endTime.After(until) {
|
||||||
|
endTime = until
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("querying withdraw %s: %s <=> %s", asset, startTime, endTime)
|
||||||
|
withdraws, err := e.client.AccountService.NewGetWithdrawalHistoryRequest().
|
||||||
|
Currency(toLocalCurrency(asset)).
|
||||||
|
From(startTime.Unix()).
|
||||||
|
To(endTime.Unix()).
|
||||||
|
Do(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return allWithdraws, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, d := range withdraws {
|
||||||
|
if _, ok := txIDs[d.TxID]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// we can convert this later
|
||||||
|
status := d.State
|
||||||
|
switch d.State {
|
||||||
|
|
||||||
|
case "confirmed":
|
||||||
|
status = "completed" // make it compatible with binance
|
||||||
|
|
||||||
|
case "submitting", "submitted", "accepted",
|
||||||
|
"rejected", "suspect", "approved", "delisted_processing",
|
||||||
|
"processing", "retryable", "sent", "canceled",
|
||||||
|
"failed", "pending",
|
||||||
|
"kgi_manually_processing", "kgi_manually_confirmed", "kgi_possible_failed",
|
||||||
|
"sygna_verifying":
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = d.State
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
txIDs[d.TxID] = struct{}{}
|
||||||
|
allWithdraws = append(allWithdraws, types.Withdraw{
|
||||||
|
ApplyTime: time.Unix(d.CreatedAt, 0),
|
||||||
|
Asset: toGlobalCurrency(d.Currency),
|
||||||
|
Amount: util.MustParseFloat(d.Amount),
|
||||||
|
Address: "",
|
||||||
|
AddressTag: "",
|
||||||
|
TransactionID: d.TxID,
|
||||||
|
TransactionFee: util.MustParseFloat(d.Fee),
|
||||||
|
// WithdrawOrderID: d.WithdrawOrderID,
|
||||||
|
// Network: d.Network,
|
||||||
|
Status: status,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
startTime = endTime
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range deposits {
|
return allWithdraws, nil
|
||||||
allDeposits = append(allDeposits, types.Deposit{
|
}
|
||||||
Time: time.Unix(d.CreatedAt, 0),
|
|
||||||
Amount: util.MustParseFloat(d.Amount),
|
func (e *Exchange) QueryDepositHistory(ctx context.Context, asset string, since, until time.Time) (allDeposits []types.Deposit, err error) {
|
||||||
Asset: d.Currency,
|
startTime := since
|
||||||
Address: "", // not supported
|
txIDs := map[string]struct{}{}
|
||||||
AddressTag: "", // not supported
|
for startTime.Before(until) {
|
||||||
TransactionID: d.TxID,
|
// startTime ~ endTime must be in 90 days
|
||||||
Status: convertDepositState(d.State),
|
endTime := startTime.AddDate(0, 0, 60)
|
||||||
})
|
if endTime.After(until) {
|
||||||
|
endTime = until
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("querying deposit history %s: %s <=> %s", asset, startTime, endTime)
|
||||||
|
deposits, err := e.client.AccountService.NewGetDepositHistoryRequest().
|
||||||
|
Currency(toLocalCurrency(asset)).
|
||||||
|
From(startTime.Unix()).
|
||||||
|
To(endTime.Unix()).Do(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, d := range deposits {
|
||||||
|
if _, ok := txIDs[d.TxID]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
allDeposits = append(allDeposits, types.Deposit{
|
||||||
|
Time: time.Unix(d.CreatedAt, 0),
|
||||||
|
Amount: util.MustParseFloat(d.Amount),
|
||||||
|
Asset: toGlobalCurrency(d.Currency),
|
||||||
|
Address: "", // not supported
|
||||||
|
AddressTag: "", // not supported
|
||||||
|
TransactionID: d.TxID,
|
||||||
|
Status: convertDepositState(d.State),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
startTime = endTime
|
||||||
}
|
}
|
||||||
|
|
||||||
return allDeposits, err
|
return allDeposits, err
|
||||||
|
@ -119,7 +207,7 @@ func convertDepositState(a string) types.DepositStatus {
|
||||||
case "rejected":
|
case "rejected":
|
||||||
return types.DepositRejected
|
return types.DepositRejected
|
||||||
|
|
||||||
case "cancelled":
|
case "canceled":
|
||||||
return types.DepositCancelled
|
return types.DepositCancelled
|
||||||
|
|
||||||
case "suspect", "refunded":
|
case "suspect", "refunded":
|
||||||
|
|
|
@ -118,7 +118,7 @@ type Deposit struct {
|
||||||
Fee string `json:"fee"`
|
Fee string `json:"fee"`
|
||||||
TxID string `json:"txid"`
|
TxID string `json:"txid"`
|
||||||
State string `json:"state"`
|
State string `json:"state"`
|
||||||
Confirmations int `json:"confirmations"`
|
Confirmations string `json:"confirmations"`
|
||||||
CreatedAt int64 `json:"created_at"`
|
CreatedAt int64 `json:"created_at"`
|
||||||
UpdatedAt int64 `json:"updated_at"`
|
UpdatedAt int64 `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ type GetDepositHistoryRequestParams struct {
|
||||||
Currency string `json:"currency"`
|
Currency string `json:"currency"`
|
||||||
From int64 `json:"from,omitempty"` // seconds
|
From int64 `json:"from,omitempty"` // seconds
|
||||||
To int64 `json:"to,omitempty"` // seconds
|
To int64 `json:"to,omitempty"` // seconds
|
||||||
State string `json:"state,omitempty"` // submitting, submitted, rejected, accepted, checking, refunded, cancelled, suspect
|
State string `json:"state,omitempty"` // submitting, submitted, rejected, accepted, checking, refunded, canceled, suspect
|
||||||
Limit int `json:"limit,omitempty"`
|
Limit int `json:"limit,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,3 +186,89 @@ func (s *AccountService) NewGetDepositHistoryRequest() *GetDepositHistoryRequest
|
||||||
client: s.client,
|
client: s.client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type Withdraw struct {
|
||||||
|
UUID string `json:"uuid"`
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
CurrencyVersion string `json:"currency_version"` // "eth"
|
||||||
|
Amount string `json:"amount"`
|
||||||
|
Fee string `json:"fee"`
|
||||||
|
TxID string `json:"txid"`
|
||||||
|
|
||||||
|
// State can be "submitting", "submitted",
|
||||||
|
// "rejected", "accepted", "suspect", "approved", "delisted_processing",
|
||||||
|
// "processing", "retryable", "sent", "canceled",
|
||||||
|
// "failed", "pending", "confirmed",
|
||||||
|
// "kgi_manually_processing", "kgi_manually_confirmed", "kgi_possible_failed",
|
||||||
|
// "sygna_verifying"
|
||||||
|
State string `json:"state"`
|
||||||
|
Confirmations int `json:"confirmations"`
|
||||||
|
CreatedAt int64 `json:"created_at"`
|
||||||
|
UpdatedAt int64 `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetWithdrawHistoryRequestParams struct {
|
||||||
|
*PrivateRequestParams
|
||||||
|
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
From int64 `json:"from,omitempty"` // seconds
|
||||||
|
To int64 `json:"to,omitempty"` // seconds
|
||||||
|
State string `json:"state,omitempty"` // submitting, submitted, rejected, accepted, checking, refunded, canceled, suspect
|
||||||
|
Limit int `json:"limit,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetWithdrawHistoryRequest struct {
|
||||||
|
client *RestClient
|
||||||
|
params GetWithdrawHistoryRequestParams
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GetWithdrawHistoryRequest) State(state string) *GetWithdrawHistoryRequest {
|
||||||
|
r.params.State = state
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GetWithdrawHistoryRequest) Currency(currency string) *GetWithdrawHistoryRequest {
|
||||||
|
r.params.Currency = currency
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GetWithdrawHistoryRequest) Limit(limit int) *GetWithdrawHistoryRequest {
|
||||||
|
r.params.Limit = limit
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GetWithdrawHistoryRequest) From(from int64) *GetWithdrawHistoryRequest {
|
||||||
|
r.params.From = from
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GetWithdrawHistoryRequest) To(to int64) *GetWithdrawHistoryRequest {
|
||||||
|
r.params.To = to
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GetWithdrawHistoryRequest) Do(ctx context.Context) (withdraws []Withdraw, err error) {
|
||||||
|
req, err := r.client.newAuthenticatedRequest("GET", "v2/withdrawals", &r.params)
|
||||||
|
if err != nil {
|
||||||
|
return withdraws, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := r.client.sendRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
return withdraws, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := response.DecodeJSON(&withdraws); err != nil {
|
||||||
|
return withdraws, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return withdraws, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *AccountService) NewGetWithdrawalHistoryRequest() *GetWithdrawHistoryRequest {
|
||||||
|
return &GetWithdrawHistoryRequest{
|
||||||
|
client: s.client,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,18 +13,22 @@ const (
|
||||||
|
|
||||||
DepositSuccess = DepositStatus("success")
|
DepositSuccess = DepositStatus("success")
|
||||||
|
|
||||||
DepositCancelled = DepositStatus("cancelled")
|
DepositCancelled = DepositStatus("canceled")
|
||||||
|
|
||||||
// created but can not withdraw
|
// created but can not withdraw
|
||||||
DepositCredited = DepositStatus("credited")
|
DepositCredited = DepositStatus("credited")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Deposit struct {
|
type Deposit struct {
|
||||||
Time time.Time `json:"time"`
|
Time time.Time `json:"time"`
|
||||||
Amount float64 `json:"amount"`
|
Amount float64 `json:"amount"`
|
||||||
Asset string `json:"asset"`
|
Asset string `json:"asset"`
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
AddressTag string `json:"addressTag"`
|
AddressTag string `json:"addressTag"`
|
||||||
TransactionID string `json:"txId"`
|
TransactionID string `json:"txId"`
|
||||||
Status DepositStatus `json:"status"`
|
Status DepositStatus `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Deposit) EffectiveTime() time.Time {
|
||||||
|
return d.Time
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ func ValidExchangeName(a string) (ExchangeName, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Exchange interface {
|
type Exchange interface {
|
||||||
|
Name() ExchangeName
|
||||||
|
|
||||||
PlatformFeeCurrency() string
|
PlatformFeeCurrency() string
|
||||||
|
|
||||||
NewStream() Stream
|
NewStream() Stream
|
||||||
|
@ -42,6 +44,10 @@ type Exchange interface {
|
||||||
|
|
||||||
QueryAveragePrice(ctx context.Context, symbol string) (float64, error)
|
QueryAveragePrice(ctx context.Context, symbol string) (float64, error)
|
||||||
|
|
||||||
|
QueryDepositHistory(ctx context.Context, asset string, since, until time.Time) (allDeposits []Deposit, err error)
|
||||||
|
|
||||||
|
QueryWithdrawHistory(ctx context.Context, asset string, since, until time.Time) (allWithdraws []Withdraw, err error)
|
||||||
|
|
||||||
SubmitOrder(ctx context.Context, order *SubmitOrder) error
|
SubmitOrder(ctx context.Context, order *SubmitOrder) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
pkg/types/withdraw.go
Normal file
22
pkg/types/withdraw.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Withdraw struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Asset string `json:"asset"`
|
||||||
|
Amount float64 `json:"amount"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
AddressTag string `json:"addressTag"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
|
||||||
|
TransactionID string `json:"txId"`
|
||||||
|
TransactionFee float64 `json:"transactionFee"`
|
||||||
|
WithdrawOrderID string `json:"withdrawOrderId"`
|
||||||
|
ApplyTime time.Time `json:"applyTime"`
|
||||||
|
Network string `json:"network"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w Withdraw) EffectiveTime() time.Time {
|
||||||
|
return w.ApplyTime
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user