Exchanges: Add in exchange defined tolerance settings (#647)

* Exchanges: Add in exchange defined tolerance settings to conform to min max amounts/price/notional etc (Initial)

* Add to tests fix linter

* Binance: Implement CMF and usdtMarginFutures fetching of currency information, addr nits

* binance: Add in test for tolerance set up

* exchanges: add in more tolerance settings and add tests

* nits: addr

* fix linter issue

* RPCServer: Use ordermanager instead of going direct to exchange

* Nits: Addr

* nits: glorious addr phase one

* nits: glorious nits phase 2

* exchange: move tolerance -> limits in order package add wrapper function, split binance functions to asset files

* nits: Addr thrasher + also include locking of limits struct when we update via syncer later on

* nits: mdc addr

* nits: glorious nits

* limits: unexport mutex

* limit: revert maths optim. and fix spelling

* limit: Add decimal package

* limit: don't check price on market order

* Orders: Add order execution checks on fake orders so as to always conform to tight specifications even in simulation

* binance: handle case where spot is not enabled but margin is

* backtester: add in amount conforming to back tested events to simulate realistic orders

* rm ln

* order limit: return amount when limit is nil and conformToAmount is requested

* nits: glorious nits + friends

* backtester/orders: fix tests

* nits: glorious nits

* nits: glorious nits

* RMLINE

* nits: more glorious nits!

* nits: pooosh

* binance: fix margin logic

* nits: Add warning, settings log and report item for exchange order execution limits

* backtester: add specific warnings in report output

* backtest: Adjust warnings
This commit is contained in:
Ryan O'Hara-Reid
2021-03-25 15:47:15 +11:00
committed by GitHub
parent 3c72a199f2
commit 881bab2d5a
40 changed files with 1193 additions and 105 deletions

View File

@@ -1,6 +1,7 @@
package main
import (
"errors"
"log"
"math/rand"
"sync"
@@ -83,133 +84,137 @@ func testWrappers(e exchange.IBotExchange) []string {
var funcs []string
_, err := e.FetchTicker(p, assetType)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "FetchTicker")
}
_, err = e.UpdateTicker(p, assetType)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "UpdateTicker")
}
_, err = e.FetchOrderbook(p, assetType)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "FetchOrderbook")
}
_, err = e.UpdateOrderbook(p, assetType)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "UpdateOrderbook")
}
_, err = e.FetchTradablePairs(asset.Spot)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "FetchTradablePairs")
}
err = e.UpdateTradablePairs(false)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "UpdateTradablePairs")
}
_, err = e.FetchAccountInfo(assetType)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "GetAccountInfo")
}
_, err = e.GetRecentTrades(p, assetType)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "GetRecentTrades")
}
_, err = e.GetHistoricTrades(p, assetType, time.Time{}, time.Time{})
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "GetHistoricTrades")
}
_, err = e.GetFundingHistory()
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "GetFundingHistory")
}
_, err = e.SubmitOrder(nil)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "SubmitOrder")
}
_, err = e.ModifyOrder(nil)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "ModifyOrder")
}
err = e.CancelOrder(nil)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "CancelOrder")
}
_, err = e.CancelBatchOrders(nil)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "CancelBatchOrders")
}
_, err = e.CancelAllOrders(nil)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "CancelAllOrders")
}
_, err = e.GetOrderInfo("1", p, assetType)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "GetOrderInfo")
}
_, err = e.GetOrderHistory(nil)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "GetOrderHistory")
}
_, err = e.GetActiveOrders(nil)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "GetActiveOrders")
}
_, err = e.GetDepositAddress(currency.BTC, "")
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "GetDepositAddress")
}
_, err = e.WithdrawCryptocurrencyFunds(nil)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "WithdrawCryptocurrencyFunds")
}
_, err = e.WithdrawFiatFunds(nil)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "WithdrawFiatFunds")
}
_, err = e.WithdrawFiatFundsToInternationalBank(nil)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "WithdrawFiatFundsToInternationalBank")
}
_, err = e.GetHistoricCandles(currency.Pair{}, asset.Spot, time.Unix(0, 0), time.Unix(0, 0), kline.OneDay)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "GetHistoricCandles")
}
_, err = e.GetHistoricCandlesExtended(currency.Pair{}, asset.Spot, time.Unix(0, 0), time.Unix(0, 0), kline.OneDay)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "GetHistoricCandlesExtended")
}
_, err = e.UpdateAccountInfo(assetType)
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "UpdateAccountInfo")
}
_, err = e.GetFeeByType(&exchange.FeeBuilder{})
if err == common.ErrNotYetImplemented {
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "GetFeeByType")
}
err = e.UpdateOrderExecutionLimits(asset.DownsideProfitContract)
if errors.Is(err, common.ErrNotYetImplemented) {
funcs = append(funcs, "UpdateOrderExecutionLimits")
}
return funcs
}

View File

@@ -420,14 +420,14 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
})
var getHistoricTradesResponse []trade.Data
getHistoricTradesResponse, err = e.GetHistoricTrades(p, assetTypes[i], time.Now().Add(-time.Hour*24), time.Now())
getHistoricTradesResponse, err = e.GetHistoricTrades(p, assetTypes[i], time.Now().Add(-time.Hour), time.Now())
msg = ""
if err != nil {
msg = err.Error()
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{p, assetTypes[i], time.Now().Add(-time.Hour * 24), time.Now()}),
SentParams: jsonifyInterface([]interface{}{p, assetTypes[i], time.Now().Add(-time.Hour), time.Now()}),
Function: "GetHistoricTrades",
Error: msg,
Response: jsonifyInterface([]interface{}{getHistoricTradesResponse}),
@@ -448,7 +448,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
})
var getHistoricCandlesResponse kline.Item
startTime, endTime := time.Now().AddDate(0, -1, 0), time.Now()
startTime, endTime := time.Now().AddDate(0, 0, -1), time.Now()
getHistoricCandlesResponse, err = e.GetHistoricCandles(p, assetTypes[i], startTime, endTime, kline.OneDay)
msg = ""
if err != nil {
@@ -475,6 +475,20 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config)
Response: getHisotirCandlesExtendedResponse,
SentParams: jsonifyInterface([]interface{}{p, assetTypes[i], startTime, endTime, kline.OneDay}),
})
err = e.UpdateOrderExecutionLimits(assetTypes[i])
msg = ""
if err != nil {
msg = err.Error()
responseContainer.ErrorCount++
}
responseContainer.EndpointResponses = append(responseContainer.EndpointResponses, EndpointResponse{
SentParams: jsonifyInterface([]interface{}{assetTypes[i]}),
Function: "UpdateOrderExecutionLimits",
Error: msg,
Response: jsonifyInterface([]interface{}{""}),
})
}
var fetchAccountInfoResponse account.Holdings

View File

@@ -4,7 +4,8 @@
"orderType": "LIMIT",
"amount": 1333333337,
"price": 1333333337,
"orderID": ""
"orderID": "",
"assetType": ""
},
"withdrawWalletAddress": "",
"bankAccount": {