Files
gocryptotrader/currency/manager.go
Ryan O'Hara-Reid a2381310da GCT: general updates across codebase (#699)
* orderbook: export orderbook nodes for external strategy inspection

* orderbook: Add in methods for locking and unlocking multiple books at the same time e.g. book1.LockWith(book2); defer book1.UnlockWith(book2)

* include waiting functionality for depth change alert

* backtester: add word.

* log: include logger changes to impl with downstream integration

* engine: reduce params for loading exchange

* assort: rm verbose in tests, change wording in ob, expose sync.waitgroup for ext. sync options

* ticker: reduce map look ups and contention when using RW mutex when there are over 80% writes adds find last function to get the latest rate

* engine/syncmanager: add in waitgroup for step over for external package calls

* cleaup

* engine: linter fix

* currency/fx: include all references to fiat currencies to default

* orderbook: Add in fields to Unsafe type for strategies to detect potential out of sync book operations

* syncmanager: changed config variable to display correct time

* ordermanager: Add time when none provided

* currency/manager: update getasset param to get enabled assets for minor optimizations

* ftx: use get all wallet balances for a better accounts breakdown

* orderbook: unlock in reverse order

* bithumb: fixes bug on market buy and sell orders

* bithumb: fix bug for nonce is also time window sensitive

* bithumb: get orders add required parameter

* bithumb: Add asset type to account struct

* currency: improve log output when checking currency and it fails

* bithumb: Add error return on incomplete pair

* ticker:unexport all service related methods

* ticker/currency: fixes

* orderbook: fix comment

* engine: revert variable name in LoadExchange method

* sync_manager: fix panic when enabling disabling manager

* engine: fix naming convention of exported function and comments

* engine: update comment

* orderbook: fix comment for unsafe type
2021-07-29 14:42:28 +10:00

211 lines
4.4 KiB
Go

package currency
import (
"errors"
"fmt"
"github.com/thrasher-corp/gocryptotrader/common/convert"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
)
// GetAssetTypes returns a list of stored asset types
func (p *PairsManager) GetAssetTypes(enabled bool) asset.Items {
p.m.RLock()
defer p.m.RUnlock()
var assetTypes asset.Items
for k, ps := range p.Pairs {
if enabled && (ps.AssetEnabled == nil || !*ps.AssetEnabled) {
continue
}
assetTypes = append(assetTypes, k)
}
return assetTypes
}
// Get gets the currency pair config based on the asset type
func (p *PairsManager) Get(a asset.Item) (*PairStore, error) {
p.m.RLock()
defer p.m.RUnlock()
c, ok := p.Pairs[a]
if !ok {
return nil,
fmt.Errorf("cannot get pair store, asset type %s not supported", a)
}
return c, nil
}
// Store stores a new currency pair config based on its asset type
func (p *PairsManager) Store(a asset.Item, ps PairStore) {
p.m.Lock()
if p.Pairs == nil {
p.Pairs = make(map[asset.Item]*PairStore)
}
p.Pairs[a] = &ps
p.m.Unlock()
}
// Delete deletes a map entry based on the supplied asset type
func (p *PairsManager) Delete(a asset.Item) {
p.m.Lock()
defer p.m.Unlock()
if p.Pairs == nil {
return
}
delete(p.Pairs, a)
}
// GetPairs gets a list of stored pairs based on the asset type and whether
// they're enabled or not
func (p *PairsManager) GetPairs(a asset.Item, enabled bool) (Pairs, error) {
p.m.RLock()
defer p.m.RUnlock()
if p.Pairs == nil {
return nil, nil
}
c, ok := p.Pairs[a]
if !ok {
return nil, nil
}
if enabled {
for i := range c.Enabled {
if !c.Available.Contains(c.Enabled[i], true) {
return c.Enabled,
fmt.Errorf("enabled pair %s of asset type %s not contained in available list",
c.Enabled[i],
a)
}
}
return c.Enabled, nil
}
return c.Available, nil
}
// StorePairs stores a list of pairs based on the asset type and whether
// they're enabled or not
func (p *PairsManager) StorePairs(a asset.Item, pairs Pairs, enabled bool) {
p.m.Lock()
defer p.m.Unlock()
if p.Pairs == nil {
p.Pairs = make(map[asset.Item]*PairStore)
}
c, ok := p.Pairs[a]
if !ok {
p.Pairs[a] = new(PairStore)
c = p.Pairs[a]
}
if enabled {
c.Enabled = pairs
} else {
c.Available = pairs
}
}
// DisablePair removes the pair from the enabled pairs list if found
func (p *PairsManager) DisablePair(a asset.Item, pair Pair) error {
p.m.Lock()
defer p.m.Unlock()
c, err := p.getPairStore(a)
if err != nil {
return err
}
if !c.Enabled.Contains(pair, true) {
return errors.New("specified pair is not enabled")
}
c.Enabled = c.Enabled.Remove(pair)
return nil
}
// EnablePair adds a pair to the list of enabled pairs if it exists in the list
// of available pairs and isn't already added
func (p *PairsManager) EnablePair(a asset.Item, pair Pair) error {
p.m.Lock()
defer p.m.Unlock()
c, err := p.getPairStore(a)
if err != nil {
return err
}
if !c.Available.Contains(pair, true) {
return fmt.Errorf("%s pair was not found in the list of available pairs",
pair)
}
if c.Enabled.Contains(pair, true) {
return fmt.Errorf("%s pair is already enabled", pair)
}
c.Enabled = c.Enabled.Add(pair)
return nil
}
// IsAssetEnabled checks to see if an asset is enabled
func (p *PairsManager) IsAssetEnabled(a asset.Item) error {
p.m.RLock()
defer p.m.RUnlock()
c, err := p.getPairStore(a)
if err != nil {
return err
}
if c.AssetEnabled == nil {
return errors.New("cannot ascertain if asset is enabled, variable is nil")
}
if !*c.AssetEnabled {
return fmt.Errorf("asset %s not enabled", a)
}
return nil
}
// SetAssetEnabled sets if an asset is enabled or disabled for first run
func (p *PairsManager) SetAssetEnabled(a asset.Item, enabled bool) error {
p.m.Lock()
defer p.m.Unlock()
c, err := p.getPairStore(a)
if err != nil {
return err
}
if c.AssetEnabled == nil {
c.AssetEnabled = convert.BoolPtr(enabled)
return nil
}
if !*c.AssetEnabled && !enabled {
return errors.New("asset already disabled")
} else if *c.AssetEnabled && enabled {
return errors.New("asset already enabled")
}
*c.AssetEnabled = enabled
return nil
}
func (p *PairsManager) getPairStore(a asset.Item) (*PairStore, error) {
if p.Pairs == nil {
return nil, errors.New("pair manager not initialised")
}
c, ok := p.Pairs[a]
if !ok {
return nil, errors.New("asset type not found")
}
if c == nil {
return nil, errors.New("currency store is nil")
}
return c, nil
}