engine/exchanges: Add exchange currency state subsystem (#774)

* state: Add management system (init)

* linter: fix

* engine: gofmt

* gct: after merge fixup

* documentation: add

* rpc: implement services for testing

* gctcli: gofmt state_management.go

* documentation: reinstate lost information

* state: Add pair check to determine trading operation

* exchanges: add interface for specific state scoped subsystem functionality

* engine/order_man: reduce code footprint using new method

* RPC: implement pair trading request and change exported name to something specific to state

* engine: add tests

* engine: Add to withdraw manager

* documentation: reinstate soxipy in contrib. list

* engine: const fake name

* Glorious: NITERINOS

* merge: fix issues

* engine: csm incorporate service name into log output

* engine: fix linter issues

* gct: fix tests

* currencystate: remove management type

* rpc: fix tests

* backtester: fix tests

* Update engine/currency_state_manager.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update engine/currency_state_manager.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update exchanges/currencystate/currency_state.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update exchanges/alert/alert.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update exchanges/alert/alert.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* glorious: nits

* config: integrate with config and remove flag delay adjustment

* gctcli: fix issues after name changes

* engine: gofmt manager file

* Update engine/rpcserver.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* engine: Add enable/disable manager functions, add default popoulation for potential assets

* linter: fix

* engine/test: bump subsystem count

* Update engine/currency_state_manager.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* Update exchanges/bithumb/bithumb.go

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>

* glorious: nits addressed

* alert: fix commenting for its generalized purpose

* glorious: nits

* engine: use standard string in log output

* bitfinex: apply patch, thanks @thrasher-

* bitfinex: fix spelling

* engine/currencystate: Add logs/fix logs

Co-authored-by: Scott <gloriousCode@users.noreply.github.com>
This commit is contained in:
Ryan O'Hara-Reid
2021-09-27 13:33:49 +10:00
committed by GitHub
parent 1d7c656665
commit 5dfbbf84de
48 changed files with 4685 additions and 1110 deletions

View File

@@ -273,6 +273,11 @@ func main() {
URL: "https://github.com/blombard",
Contributions: 1,
},
{
Login: "soxipy",
URL: "https://github.com/soxipy",
Contributions: 2,
},
}...)
if verbose {

View File

@@ -0,0 +1,14 @@
{{define "engine currency_state_manager" -}}
{{template "header" .}}
## Current Features for {{.CapitalName}}
+ The state manager keeps currency states up to date, which include:
* Withdrawal - Determines if the currency is allowed to be withdrawn from the exchange.
* Deposit - Determines if the currency is allowed to be deposited to an exchange.
* Trading - Determines if the currency is allowed to be traded on the exchange.
+ This allows for an internal state check to compliment internal and external
strategies.
{{template "contributions"}}
{{template "donations" .}}
{{end}}

View File

@@ -11,6 +11,11 @@ implementation
+ A guide on implementing API support for a new exchange can be found [here](../docs/ADD_NEW_EXCHANGE.md)
## websocket notes
+ If contributing websocket improvements, please make sure order reports
follow [these rules](../docs/WS_ORDER_EVENTS.md).
### Please click GoDocs chevron above to view current GoDoc information for this package
{{template "contributions"}}
{{template "donations" .}}

View File

@@ -0,0 +1,300 @@
package main
import (
"github.com/thrasher-corp/gocryptotrader/gctrpc"
"github.com/urfave/cli/v2"
)
var currencyStateManagementCommand = &cli.Command{
Name: "currencystate",
Usage: "execute exchange currency state management command",
ArgsUsage: "<command> <args>",
Subcommands: []*cli.Command{
{
Name: "getall",
Usage: "fetch all currency states associated with an exchange",
ArgsUsage: "<exchange>",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "exchange",
Usage: "the exchange to act on",
},
},
Action: stateGetAll,
},
{
Name: "withdraw",
Usage: "returns if the currency can be withdrawn from the exchange",
ArgsUsage: "<exchange> <code> <asset>",
Flags: stateFlags,
Action: stateGetWithdrawal,
},
{
Name: "deposit",
Usage: "returns if the currency can be deposited onto an exchange",
ArgsUsage: "<exchange> <code> <asset>",
Flags: stateFlags,
Action: stateGetDeposit,
},
{
Name: "trade",
Usage: "returns if the currency can be traded on the exchange",
ArgsUsage: "<exchange> <code> <asset>",
Flags: stateFlags,
Action: stateGetTrading,
},
{
Name: "tradepair",
Usage: "returns if the currency pair can be traded on the exchange",
ArgsUsage: "<exchange> <pair> <asset>",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "exchange",
Usage: "the exchange to act on",
},
&cli.StringFlag{
Name: "pair",
Usage: "the currency pair e.g. btc-usd",
},
&cli.StringFlag{
Name: "asset",
Usage: "the asset type",
},
},
Action: stateGetPairTrading,
},
},
}
var stateFlags = []cli.Flag{
&cli.StringFlag{
Name: "exchange",
Usage: "the exchange to act on",
},
&cli.StringFlag{
Name: "code",
Usage: "the currency code",
},
&cli.StringFlag{
Name: "asset",
Usage: "the asset type",
},
}
func stateGetAll(c *cli.Context) error {
if c.NArg() == 0 && c.NumFlags() == 0 {
return cli.ShowSubcommandHelp(c)
}
var exchange string
if c.IsSet("exchange") {
exchange = c.String("exchange")
} else {
exchange = c.Args().First()
}
conn, cancel, err := setupClient(c)
if err != nil {
return err
}
defer closeConn(conn, cancel)
client := gctrpc.NewGoCryptoTraderClient(conn)
result, err := client.CurrencyStateGetAll(c.Context,
&gctrpc.CurrencyStateGetAllRequest{Exchange: exchange},
)
if err != nil {
return err
}
jsonOutput(result)
return nil
}
func stateGetDeposit(c *cli.Context) error {
if c.NArg() == 0 && c.NumFlags() == 0 {
return cli.ShowSubcommandHelp(c)
}
var exchange string
if c.IsSet("exchange") {
exchange = c.String("exchange")
} else {
exchange = c.Args().First()
}
var code string
if c.IsSet("code") {
code = c.String("code")
} else {
code = c.Args().Get(1)
}
var a string
if c.IsSet("asset") {
a = c.String("asset")
} else {
a = c.Args().Get(2)
}
conn, cancel, err := setupClient(c)
if err != nil {
return err
}
defer closeConn(conn, cancel)
client := gctrpc.NewGoCryptoTraderClient(conn)
result, err := client.CurrencyStateDeposit(c.Context,
&gctrpc.CurrencyStateDepositRequest{
Exchange: exchange,
Code: code,
Asset: a},
)
if err != nil {
return err
}
jsonOutput(result)
return nil
}
func stateGetWithdrawal(c *cli.Context) error {
if c.NArg() == 0 && c.NumFlags() == 0 {
return cli.ShowSubcommandHelp(c)
}
var exchange string
if c.IsSet("exchange") {
exchange = c.String("exchange")
} else {
exchange = c.Args().First()
}
var code string
if c.IsSet("code") {
code = c.String("code")
} else {
code = c.Args().Get(1)
}
var a string
if c.IsSet("asset") {
a = c.String("asset")
} else {
a = c.Args().Get(2)
}
conn, cancel, err := setupClient(c)
if err != nil {
return err
}
defer closeConn(conn, cancel)
client := gctrpc.NewGoCryptoTraderClient(conn)
result, err := client.CurrencyStateWithdraw(c.Context,
&gctrpc.CurrencyStateWithdrawRequest{
Exchange: exchange,
Code: code,
Asset: a},
)
if err != nil {
return err
}
jsonOutput(result)
return nil
}
func stateGetTrading(c *cli.Context) error {
if c.NArg() == 0 && c.NumFlags() == 0 {
return cli.ShowSubcommandHelp(c)
}
var exchange string
if c.IsSet("exchange") {
exchange = c.String("exchange")
} else {
exchange = c.Args().First()
}
var code string
if c.IsSet("code") {
code = c.String("code")
} else {
code = c.Args().Get(1)
}
var a string
if c.IsSet("asset") {
a = c.String("asset")
} else {
a = c.Args().Get(2)
}
conn, cancel, err := setupClient(c)
if err != nil {
return err
}
defer closeConn(conn, cancel)
client := gctrpc.NewGoCryptoTraderClient(conn)
result, err := client.CurrencyStateTrading(c.Context,
&gctrpc.CurrencyStateTradingRequest{
Exchange: exchange,
Code: code,
Asset: a},
)
if err != nil {
return err
}
jsonOutput(result)
return nil
}
func stateGetPairTrading(c *cli.Context) error {
if c.NArg() == 0 && c.NumFlags() == 0 {
return cli.ShowSubcommandHelp(c)
}
var exchange string
if c.IsSet("exchange") {
exchange = c.String("exchange")
} else {
exchange = c.Args().First()
}
var pair string
if c.IsSet("pair") {
pair = c.String("pair")
} else {
pair = c.Args().Get(1)
}
var a string
if c.IsSet("asset") {
a = c.String("asset")
} else {
a = c.Args().Get(2)
}
conn, cancel, err := setupClient(c)
if err != nil {
return err
}
defer closeConn(conn, cancel)
client := gctrpc.NewGoCryptoTraderClient(conn)
result, err := client.CurrencyStateTradingPair(c.Context,
&gctrpc.CurrencyStateTradingPairRequest{
Exchange: exchange,
Pair: pair,
Asset: a},
)
if err != nil {
return err
}
jsonOutput(result)
return nil
}

View File

@@ -161,6 +161,7 @@ func main() {
websocketManagerCommand,
tradeCommand,
dataHistoryCommands,
currencyStateManagementCommand,
}
ctx, cancel := context.WithCancel(context.Background())