Skip to content

Commit

Permalink
fix(paperwallet): add logic to release locked funds when we cancel or…
Browse files Browse the repository at this point in the history
…der (#339)
  • Loading branch information
ramilexe authored Jul 13, 2024
1 parent 0474603 commit cad0986
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
15 changes: 15 additions & 0 deletions exchange/paperwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,21 @@ func (p *PaperWallet) Cancel(order model.Order) error {
for i, o := range p.orders {
if o.ExchangeID == order.ExchangeID {
p.orders[i].Status = model.OrderStatusTypeCanceled

// unlock funds
assset, quote := SplitAssetQuote(o.Pair)
// we have open long position
if p.assets[assset].Lock > 0 && o.Side == model.SideTypeSell {
p.assets[assset].Free += o.Quantity
p.assets[assset].Lock -= o.Quantity
} else {
// we don't have open long position
if p.assets[assset].Lock == 0 {
amount := order.Price * order.Quantity
p.assets[quote].Free += amount
p.assets[quote].Lock -= amount
}
}
}
}
return nil
Expand Down
46 changes: 46 additions & 0 deletions exchange/paperwallet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,52 @@ func TestPaperWallet_OrderLimit(t *testing.T) {
require.Equal(t, 0.0, wallet.assets["USDT"].Lock)
require.Equal(t, 10.0, wallet.avgLongPrice["BTCUSDT"])
})

t.Run("cancel buy order before executing", func(t *testing.T) {
wallet := NewPaperWallet(context.Background(), "USDT", WithPaperAsset("USDT", 100))
order, err := wallet.CreateOrderLimit(model.SideTypeBuy, "BTCUSDT", 1, 100)
require.NoError(t, err)

// create order and lock values
require.Len(t, wallet.orders, 1)
require.Equal(t, 1.0, order.Quantity)
require.Equal(t, 100.0, order.Price)
require.Equal(t, 0.0, wallet.assets["USDT"].Free)
require.Equal(t, 100.0, wallet.assets["USDT"].Lock)

// cancel limit order and it should unlock funds
err = wallet.Cancel(order)
require.NoError(t, err)

require.Equal(t, model.OrderStatusTypeCanceled, wallet.orders[0].Status)
require.Equal(t, 100.0, wallet.assets["USDT"].Free)
require.Equal(t, 0.0, wallet.assets["USDT"].Lock)
require.Equal(t, 0.0, wallet.assets["BTC"].Free)
require.Equal(t, 0.0, wallet.assets["BTC"].Lock)
})

t.Run("cancel sell order before executing", func(t *testing.T) {
wallet := NewPaperWallet(context.Background(), "USDT", WithPaperAsset("USDT", 100))
order, err := wallet.CreateOrderLimit(model.SideTypeSell, "BTCUSDT", 1, 100)
require.NoError(t, err)

// create order and lock values
require.Len(t, wallet.orders, 1)
require.Equal(t, 1.0, order.Quantity)
require.Equal(t, 100.0, order.Price)
require.Equal(t, 0.0, wallet.assets["USDT"].Free)
require.Equal(t, 100.0, wallet.assets["USDT"].Lock)

// cancel limit order and it should unlock funds
err = wallet.Cancel(order)
require.NoError(t, err)

require.Equal(t, model.OrderStatusTypeCanceled, wallet.orders[0].Status)
require.Equal(t, 100.0, wallet.assets["USDT"].Free)
require.Equal(t, 0.0, wallet.assets["USDT"].Lock)
require.Equal(t, 0.0, wallet.assets["BTC"].Free)
require.Equal(t, 0.0, wallet.assets["BTC"].Lock)
})
}

func TestPaperWallet_OrderMarket(t *testing.T) {
Expand Down

0 comments on commit cad0986

Please sign in to comment.