rpcserver/exchanges: Add additional param checks plus other minor bugfixes/improvements (#652)

* deleting the unwanted file created during testing + adding more verbose errors for cli

* wip

* checking params throughout wip

* improving errors

* wip

* thrasher patch

* better err name

* whip

* testing and fixing errors WIP

* upgrades and better errors

* broken test

* wip

* adding some tests

* using tempDir

* mini improvement

* little changes

* better time check

* fixing error

* more glorious changes

* end of day wip

* shazzy changes

* checking error

* appveyor

* last changes:
This commit is contained in:
Adam
2021-03-30 13:40:01 +11:00
committed by GitHub
parent 2855e68bac
commit 08f1b5d5d3
13 changed files with 457 additions and 283 deletions

View File

@@ -29,6 +29,7 @@ import (
"github.com/thrasher-corp/gocryptotrader/database/models/sqlite3"
"github.com/thrasher-corp/gocryptotrader/database/repository/audit"
exchangeDB "github.com/thrasher-corp/gocryptotrader/database/repository/exchange"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
@@ -55,10 +56,12 @@ var (
errInvalidArguments = errors.New("invalid arguments received")
errExchangeNameUnset = errors.New("exchange name unset")
errCurrencyPairUnset = errors.New("currency pair unset")
errStartEndTimesUnset = errors.New("invalid start and end times")
errInvalidTimes = errors.New("invalid start and end times")
errAssetTypeDisabled = errors.New("asset type is disabled")
errAssetTypeUnset = errors.New("asset type unset")
errDispatchSystem = errors.New("dispatch system offline")
errCurrencyNotEnabled = errors.New("currency not enabled")
errCurrencyPairInvalid = errors.New("currency provided is not found in the available pairs list")
)
// RPCServer struct
@@ -335,6 +338,16 @@ func (s *RPCServer) GetTicker(_ context.Context, r *gctrpc.GetTickerRequest) (*g
return nil, err
}
e := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, e, a, currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
})
if err != nil {
return nil, err
}
t, err := s.GetSpecificTicker(currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
@@ -494,12 +507,14 @@ func (s *RPCServer) GetOrderbooks(_ context.Context, r *gctrpc.GetOrderbooksRequ
// GetAccountInfo returns an account balance for a specific exchange
func (s *RPCServer) GetAccountInfo(_ context.Context, r *gctrpc.GetAccountInfoRequest) (*gctrpc.GetAccountInfoResponse, error) {
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return nil, errExchangeNotLoaded
assetType, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
assetType, err := asset.New(r.AssetType)
exch := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, exch, assetType, currency.Pair{})
if err != nil {
return nil, err
}
@@ -514,12 +529,13 @@ func (s *RPCServer) GetAccountInfo(_ context.Context, r *gctrpc.GetAccountInfoRe
// UpdateAccountInfo forces an update of the account info
func (s *RPCServer) UpdateAccountInfo(ctx context.Context, r *gctrpc.GetAccountInfoRequest) (*gctrpc.GetAccountInfoResponse, error) {
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return nil, errExchangeNotLoaded
assetType, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
assetType, err := asset.New(r.AssetType)
exch := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, exch, assetType, currency.Pair{})
if err != nil {
return nil, err
}
@@ -552,16 +568,13 @@ func createAccountInfoRequest(h account.Holdings) (*gctrpc.GetAccountInfoRespons
// GetAccountInfoStream streams an account balance for a specific exchange
func (s *RPCServer) GetAccountInfoStream(r *gctrpc.GetAccountInfoRequest, stream gctrpc.GoCryptoTrader_GetAccountInfoStreamServer) error {
if r.Exchange == "" {
return errExchangeNameUnset
assetType, err := asset.New(r.AssetType)
if err != nil {
return err
}
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return errExchangeNotLoaded
}
assetType, err := asset.New(r.AssetType)
err = checkParams(r.Exchange, exch, assetType, currency.Pair{})
if err != nil {
return err
}
@@ -803,17 +816,25 @@ func (s *RPCServer) GetOrders(_ context.Context, r *gctrpc.GetOrdersRequest) (*g
if r == nil {
return nil, errInvalidArguments
}
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return nil, errExchangeNotLoaded
}
if r.Pair == nil {
return nil, errCurrencyPairUnset
}
a, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
if r.Pair == nil {
return nil, errCurrencyPairUnset
}
cp := currency.NewPairWithDelimiter(
r.Pair.Base,
r.Pair.Quote,
r.Pair.Delimiter)
exch := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, exch, a, cp)
if err != nil {
return nil, err
}
var start, end time.Time
if r.StartDate != "" {
start, err = time.Parse(common.SimpleTimeFormat, r.StartDate)
@@ -828,23 +849,7 @@ func (s *RPCServer) GetOrders(_ context.Context, r *gctrpc.GetOrdersRequest) (*g
}
}
if !start.IsZero() && !end.IsZero() && start.After(end) {
return nil, errStartEndTimesUnset
}
cp := currency.NewPairWithDelimiter(
r.Pair.Base,
r.Pair.Quote,
r.Pair.Delimiter)
var pairs currency.Pairs
pairs, err = exch.GetEnabledPairs(a)
if err != nil {
return nil, err
}
if !pairs.Contains(cp, false) {
return nil, fmt.Errorf("%s %w %v, please check your config",
exch.GetName(),
errCurrencyNotEnabled,
cp.String())
return nil, errInvalidTimes
}
request := &order.GetOrdersRequest{
@@ -917,10 +922,7 @@ func (s *RPCServer) GetOrder(_ context.Context, r *gctrpc.GetOrderRequest) (*gct
if r == nil {
return nil, errInvalidArguments
}
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return nil, errExchangeNotLoaded
}
if r.Pair == nil {
return nil, errCurrencyPairUnset
}
@@ -936,6 +938,12 @@ func (s *RPCServer) GetOrder(_ context.Context, r *gctrpc.GetOrderRequest) (*gct
return nil, err
}
exch := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, exch, a, pair)
if err != nil {
return nil, err
}
result, err := s.OrderManager.GetOrderInfo(r.Exchange, r.OrderId, pair, a)
if err != nil {
return nil, fmt.Errorf("error whilst trying to retrieve info for order %s: %w", r.OrderId, err)
@@ -986,12 +994,23 @@ func (s *RPCServer) GetOrder(_ context.Context, r *gctrpc.GetOrderRequest) (*gct
// SubmitOrder submits an order specified by exchange, currency pair and asset
// type
func (s *RPCServer) SubmitOrder(_ context.Context, r *gctrpc.SubmitOrderRequest) (*gctrpc.SubmitOrderResponse, error) {
p, err := currency.NewPairFromStrings(r.Pair.Base, r.Pair.Quote)
a, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
a, err := asset.New(r.AssetType)
if r.Pair == nil {
return nil, errCurrencyPairUnset
}
p := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
exch := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, exch, a, p)
if err != nil {
return nil, err
}
@@ -1032,12 +1051,18 @@ func (s *RPCServer) SubmitOrder(_ context.Context, r *gctrpc.SubmitOrderRequest)
// SimulateOrder simulates an order specified by exchange, currency pair and asset
// type
func (s *RPCServer) SimulateOrder(_ context.Context, r *gctrpc.SimulateOrderRequest) (*gctrpc.SimulateOrderResponse, error) {
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return nil, errExchangeNotLoaded
if r.Pair == nil {
return nil, errCurrencyPairUnset
}
p, err := currency.NewPairFromStrings(r.Pair.Base, r.Pair.Quote)
p := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
exch := s.GetExchangeByName(r.Exchange)
err := checkParams(r.Exchange, exch, asset.Spot, p)
if err != nil {
return nil, err
}
@@ -1073,12 +1098,18 @@ func (s *RPCServer) SimulateOrder(_ context.Context, r *gctrpc.SimulateOrderRequ
// WhaleBomb finds the amount required to reach a specific price target for a given exchange, pair
// and asset type
func (s *RPCServer) WhaleBomb(_ context.Context, r *gctrpc.WhaleBombRequest) (*gctrpc.SimulateOrderResponse, error) {
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return nil, errExchangeNotLoaded
if r.Pair == nil {
return nil, errCurrencyPairUnset
}
p, err := currency.NewPairFromStrings(r.Pair.Base, r.Pair.Quote)
p := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
exch := s.GetExchangeByName(r.Exchange)
err := checkParams(r.Exchange, exch, asset.Item(""), p)
if err != nil {
return nil, err
}
@@ -1114,17 +1145,23 @@ func (s *RPCServer) WhaleBomb(_ context.Context, r *gctrpc.WhaleBombRequest) (*g
// CancelOrder cancels an order specified by exchange, currency pair and asset
// type
func (s *RPCServer) CancelOrder(_ context.Context, r *gctrpc.CancelOrderRequest) (*gctrpc.GenericResponse, error) {
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return nil, errExchangeNotLoaded
if r.Pair == nil {
return nil, errCurrencyPairUnset
}
p, err := currency.NewPairFromStrings(r.Pair.Base, r.Pair.Quote)
p := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
a, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
a, err := asset.New(r.AssetType)
exch := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, exch, a, p)
if err != nil {
return nil, err
}
@@ -1146,17 +1183,19 @@ func (s *RPCServer) CancelOrder(_ context.Context, r *gctrpc.CancelOrderRequest)
// CancelBatchOrders cancels an orders specified by exchange, currency pair and asset type
func (s *RPCServer) CancelBatchOrders(_ context.Context, r *gctrpc.CancelBatchOrdersRequest) (*gctrpc.CancelBatchOrdersResponse, error) {
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return nil, errExchangeNotLoaded
pair := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
pair, err := currency.NewPairFromStrings(r.Pair.Base, r.Pair.Quote)
assetType, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
assetType, err := asset.New(r.AssetType)
exch := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, exch, assetType, pair)
if err != nil {
return nil, err
}
@@ -1228,6 +1267,12 @@ func (s *RPCServer) AddEvent(_ context.Context, r *gctrpc.AddEventRequest) (*gct
return nil, err
}
exch := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, exch, a, p)
if err != nil {
return nil, err
}
id, err := Add(r.Exchange, r.Item, evtCondition, p, a, r.Action)
if err != nil {
return nil, err
@@ -1535,22 +1580,15 @@ func (s *RPCServer) SetExchangePair(_ context.Context, r *gctrpc.SetExchangePair
return nil, err
}
if r.AssetType == "" {
return nil, errors.New("asset type must be specified")
}
a, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
if !exchCfg.CurrencyPairs.GetAssetTypes().Contains(a) {
return nil, fmt.Errorf("specified asset %s is not supported by exchange", a)
}
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return nil, errExchangeNotLoaded
err = checkParams(r.Exchange, exch, a, currency.Pair{})
if err != nil {
return nil, err
}
base := exch.GetBase()
@@ -1617,24 +1655,19 @@ func (s *RPCServer) SetExchangePair(_ context.Context, r *gctrpc.SetExchangePair
// GetOrderbookStream streams the requested updated orderbook
func (s *RPCServer) GetOrderbookStream(r *gctrpc.GetOrderbookStreamRequest, stream gctrpc.GoCryptoTrader_GetOrderbookStreamServer) error {
if r.Exchange == "" {
return errExchangeNameUnset
}
if r.Pair.String() == "" {
return errCurrencyPairUnset
}
if r.AssetType == "" {
return errAssetTypeUnset
}
p, err := currency.NewPairFromStrings(r.Pair.Base, r.Pair.Quote)
a, err := asset.New(r.AssetType)
if err != nil {
return err
}
a, err := asset.New(r.AssetType)
p := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
exch := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, exch, a, p)
if err != nil {
return err
}
@@ -1735,6 +1768,11 @@ func (s *RPCServer) GetTickerStream(r *gctrpc.GetTickerStreamRequest, stream gct
return errExchangeNameUnset
}
a, err := asset.New(r.AssetType)
if err != nil {
return err
}
if r.Pair.String() == "" {
return errCurrencyPairUnset
}
@@ -1748,11 +1786,6 @@ func (s *RPCServer) GetTickerStream(r *gctrpc.GetTickerStreamRequest, stream gct
return err
}
a, err := asset.New(r.AssetType)
if err != nil {
return err
}
pipe, err := ticker.SubscribeTicker(r.Exchange, p, a)
if err != nil {
return err
@@ -1874,17 +1907,6 @@ func (s *RPCServer) GetAuditEvent(_ context.Context, r *gctrpc.GetAuditEventRequ
// GetHistoricCandles returns historical candles for a given exchange
func (s *RPCServer) GetHistoricCandles(_ context.Context, r *gctrpc.GetHistoricCandlesRequest) (*gctrpc.GetHistoricCandlesResponse, error) {
if r.Exchange == "" {
return nil, errExchangeNameUnset
}
if r.Pair.String() == "" {
return nil, errCurrencyPairUnset
}
if r.Start == r.End {
return nil, errStartEndTimesUnset
}
var klineItem kline.Item
UTCStartTime, err := time.Parse(common.SimpleTimeFormat, r.Start)
if err != nil {
return nil, err
@@ -1894,6 +1916,31 @@ func (s *RPCServer) GetHistoricCandles(_ context.Context, r *gctrpc.GetHistoricC
if err != nil {
return nil, err
}
if UTCStartTime.After(UTCEndTime) || UTCStartTime.Equal(UTCEndTime) {
return nil, errInvalidTimes
}
if r.Pair == nil {
return nil, errCurrencyPairUnset
}
pair := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
a, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
exch := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, exch, a, pair)
if err != nil {
return nil, err
}
interval := kline.Interval(r.TimeInterval)
resp := gctrpc.GetHistoricCandlesResponse{
@@ -1903,16 +1950,7 @@ func (s *RPCServer) GetHistoricCandles(_ context.Context, r *gctrpc.GetHistoricC
End: r.End,
}
a, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
pair := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
var klineItem kline.Item
if r.UseDb {
klineItem, err = kline.LoadFromDatabase(r.Exchange,
pair,
@@ -1924,18 +1962,14 @@ func (s *RPCServer) GetHistoricCandles(_ context.Context, r *gctrpc.GetHistoricC
return nil, err
}
} else {
exchangeEngine := s.GetExchangeByName(r.Exchange)
if exchangeEngine == nil {
return nil, errors.New("Exchange " + r.Exchange + " not found")
}
if r.ExRequest {
klineItem, err = exchangeEngine.GetHistoricCandlesExtended(pair,
klineItem, err = exch.GetHistoricCandlesExtended(pair,
a,
UTCStartTime,
UTCEndTime,
interval)
} else {
klineItem, err = exchangeEngine.GetHistoricCandles(pair,
klineItem, err = exch.GetHistoricCandles(pair,
a,
UTCStartTime,
UTCEndTime,
@@ -2596,27 +2630,23 @@ func (s *RPCServer) GetSavedTrades(_ context.Context, r *gctrpc.GetSavedTradesRe
if r.End == "" || r.Start == "" || r.Exchange == "" || r.Pair == nil || r.AssetType == "" || r.Pair.String() == "" {
return nil, errInvalidArguments
}
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return nil, errExchangeNotLoaded
p := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
cp, err := currency.NewPairFromStrings(r.Pair.Base, r.Pair.Quote)
a, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
a := asset.Item(r.AssetType)
if !a.IsValid() {
return nil, errors.New("invalid asset")
}
var pairs currency.Pairs
pairs, err = exch.GetEnabledPairs(a)
exch := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, exch, a, p)
if err != nil {
return nil, err
}
if !pairs.Contains(cp, false) {
return nil, errors.New("currency not enabled")
}
var UTCStartTime, UTCEndTime time.Time
UTCStartTime, err = time.Parse(common.SimpleTimeFormat, r.Start)
@@ -2658,7 +2688,6 @@ func (s *RPCServer) ConvertTradesToCandles(_ context.Context, r *gctrpc.ConvertT
if r.End == "" || r.Start == "" || r.Exchange == "" || r.Pair == nil || r.AssetType == "" || r.Pair.String() == "" || r.TimeInterval == 0 {
return nil, errInvalidArguments
}
exch := s.GetExchangeByName(r.Exchange)
UTCStartTime, err := time.Parse(common.SimpleTimeFormat, r.Start)
if err != nil {
return nil, err
@@ -2668,26 +2697,22 @@ func (s *RPCServer) ConvertTradesToCandles(_ context.Context, r *gctrpc.ConvertT
if err != nil {
return nil, err
}
if exch == nil {
return nil, errExchangeNotLoaded
p := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
var cp currency.Pair
cp, err = currency.NewPairFromStrings(r.Pair.Base, r.Pair.Quote)
a, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
a := asset.Item(r.AssetType)
if !a.IsValid() {
return nil, errors.New("invalid asset")
}
var pairs currency.Pairs
pairs, err = exch.GetEnabledPairs(a)
exch := s.GetExchangeByName(r.Exchange)
err = checkParams(r.Exchange, exch, a, p)
if err != nil {
return nil, err
}
if !pairs.Contains(cp, false) {
return nil, errors.New("currency not enabled")
}
var trades []trade.Data
trades, err = trade.GetTradesInRange(r.Exchange, r.AssetType, r.Pair.Base, r.Pair.Quote, UTCStartTime, UTCEndTime)
@@ -2740,27 +2765,22 @@ func (s *RPCServer) FindMissingSavedCandleIntervals(_ context.Context, r *gctrpc
if r.End == "" || r.Start == "" || r.ExchangeName == "" || r.Pair == nil || r.AssetType == "" || r.Pair.String() == "" || r.Interval <= 0 {
return nil, errInvalidArguments
}
exch := s.GetExchangeByName(r.ExchangeName)
if exch == nil {
return nil, errExchangeNotLoaded
p := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
cp, err := currency.NewPairFromStrings(r.Pair.Base, r.Pair.Quote)
a, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
a := asset.Item(r.AssetType)
if !a.IsValid() {
return nil, errors.New("invalid asset")
}
var pairs currency.Pairs
pairs, err = exch.GetEnabledPairs(a)
exch := s.GetExchangeByName(r.ExchangeName)
err = checkParams(r.ExchangeName, exch, a, p)
if err != nil {
return nil, err
}
if !pairs.Contains(cp, false) {
return nil, errors.New("currency not enabled")
}
var UTCStartTime, UTCEndTime time.Time
UTCStartTime, err = time.Parse(common.SimpleTimeFormat, r.Start)
@@ -2773,12 +2793,8 @@ func (s *RPCServer) FindMissingSavedCandleIntervals(_ context.Context, r *gctrpc
}
klineItem, err := kline.LoadFromDatabase(
r.ExchangeName,
currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
},
asset.Item(strings.ToLower(r.AssetType)),
p,
a,
kline.Interval(r.Interval),
UTCStartTime,
UTCEndTime,
@@ -2834,11 +2850,22 @@ func (s *RPCServer) FindMissingSavedTradeIntervals(_ context.Context, r *gctrpc.
if r.End == "" || r.Start == "" || r.ExchangeName == "" || r.Pair == nil || r.AssetType == "" || r.Pair.String() == "" {
return nil, errInvalidArguments
}
exch := s.GetExchangeByName(r.ExchangeName)
if exch == nil {
return nil, errExchangeNotLoaded
p := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
a, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
exch := s.GetExchangeByName(r.ExchangeName)
err = checkParams(r.ExchangeName, exch, a, p)
if err != nil {
return nil, err
}
var err error
var UTCStartTime, UTCEndTime time.Time
UTCStartTime, err = time.Parse(common.SimpleTimeFormat, r.Start)
if err != nil {
@@ -2858,23 +2885,6 @@ func (s *RPCServer) FindMissingSavedTradeIntervals(_ context.Context, r *gctrpc.
intervalMap[iterationTime] = false
iterationTime = iterationTime.Add(time.Hour)
}
var cp currency.Pair
cp, err = currency.NewPairFromStrings(r.Pair.Base, r.Pair.Quote)
if err != nil {
return nil, err
}
a := asset.Item(r.AssetType)
if !a.IsValid() {
return nil, errors.New("invalid asset")
}
var pairs currency.Pairs
pairs, err = exch.GetEnabledPairs(a)
if err != nil {
return nil, err
}
if !pairs.Contains(cp, false) {
return nil, errors.New("currency not enabled")
}
var trades []trade.Data
trades, err = trade.GetTradesInRange(
@@ -2950,26 +2960,22 @@ func (s *RPCServer) GetHistoricTrades(r *gctrpc.GetSavedTradesRequest, stream gc
if r.Exchange == "" || r.Pair == nil || r.AssetType == "" || r.Pair.String() == "" {
return errInvalidArguments
}
cp := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
a, err := asset.New(r.AssetType)
if err != nil {
return err
}
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return errExchangeNotLoaded
}
cp, err := currency.NewPairFromStrings(r.Pair.Base, r.Pair.Quote)
err = checkParams(r.Exchange, exch, a, cp)
if err != nil {
return err
}
a := asset.Item(r.AssetType)
if !a.IsValid() {
return errors.New("invalid asset")
}
var pairs currency.Pairs
pairs, err = exch.GetEnabledPairs(a)
if err != nil {
return err
}
if !pairs.Contains(cp, false) {
return errors.New("currency not enabled")
}
var trades []trade.Data
var UTCStartTime, UTCEndTime time.Time
UTCStartTime, err = time.Parse(common.SimpleTimeFormat, r.Start)
@@ -2989,7 +2995,7 @@ func (s *RPCServer) GetHistoricTrades(r *gctrpc.GetSavedTradesRequest, stream gc
for iterateStartTime := UTCStartTime; iterateStartTime.Before(UTCEndTime); iterateStartTime = iterateStartTime.Add(time.Hour) {
iterateEndTime := iterateStartTime.Add(time.Hour)
trades, err = exch.GetHistoricTrades(cp, asset.Item(r.AssetType), iterateStartTime, iterateEndTime)
trades, err = exch.GetHistoricTrades(cp, a, iterateStartTime, iterateEndTime)
if err != nil {
return err
}
@@ -3027,26 +3033,22 @@ func (s *RPCServer) GetRecentTrades(_ context.Context, r *gctrpc.GetSavedTradesR
if r.Exchange == "" || r.Pair == nil || r.AssetType == "" || r.Pair.String() == "" {
return nil, errInvalidArguments
}
cp := currency.Pair{
Delimiter: r.Pair.Delimiter,
Base: currency.NewCode(r.Pair.Base),
Quote: currency.NewCode(r.Pair.Quote),
}
a, err := asset.New(r.AssetType)
if err != nil {
return nil, err
}
exch := s.GetExchangeByName(r.Exchange)
if exch == nil {
return nil, errExchangeNotLoaded
}
cp, err := currency.NewPairFromStrings(r.Pair.Base, r.Pair.Quote)
err = checkParams(r.Exchange, exch, a, cp)
if err != nil {
return nil, err
}
a := asset.Item(r.AssetType)
if !a.IsValid() {
return nil, errors.New("invalid asset")
}
var pairs currency.Pairs
pairs, err = exch.GetEnabledPairs(a)
if err != nil {
return nil, err
}
if !pairs.Contains(cp, false) {
return nil, errors.New("currency not enabled")
}
var trades []trade.Data
trades, err = exch.GetRecentTrades(cp, asset.Item(r.AssetType))
if err != nil {
@@ -3072,3 +3074,40 @@ func (s *RPCServer) GetRecentTrades(_ context.Context, r *gctrpc.GetSavedTradesR
return resp, nil
}
func checkParams(exchName string, e exchange.IBotExchange, a asset.Item, p currency.Pair) error {
if e == nil {
return fmt.Errorf("%s %w", exchName, errExchangeNotLoaded)
}
if !e.IsEnabled() {
return fmt.Errorf("%s %w", exchName, errExchangeDisabled)
}
if a.IsValid() {
b := e.GetBase()
if b == nil {
return fmt.Errorf("%s %w", exchName, errExchangeBaseNotFound)
}
err := b.CurrencyPairs.IsAssetEnabled(a)
if err != nil {
return fmt.Errorf("%v %w", a, errAssetTypeDisabled)
}
}
if p.IsEmpty() {
return nil
}
enabledPairs, err := e.GetEnabledPairs(a)
if err != nil {
return err
}
if enabledPairs.Contains(p, true) {
return nil
}
availablePairs, err := e.GetAvailablePairs(a)
if err != nil {
return err
}
if availablePairs.Contains(p, true) {
return fmt.Errorf("%v %w", p, errCurrencyNotEnabled)
}
return fmt.Errorf("%v %w", p, errCurrencyPairInvalid)
}