mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-20 23:16:49 +00:00
Engine improvements
Add back events tests Fill out SMTP comms handler Add getcommunicationrelayers gRPC command
This commit is contained in:
@@ -183,6 +183,32 @@ func getRPCEndpoints(_ *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var getCommunicationRelayersCommand = cli.Command{
|
||||
Name: "getcommsrelayers",
|
||||
Usage: "gets GoCryptoTrader communication relayers",
|
||||
Action: getCommunicationRelayers,
|
||||
}
|
||||
|
||||
func getCommunicationRelayers(_ *cli.Context) error {
|
||||
conn, err := setupClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
client := gctrpc.NewGoCryptoTraderClient(conn)
|
||||
result, err := client.GetCommunicationRelayers(context.Background(),
|
||||
&gctrpc.GetCommunicationRelayersRequest{},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
jsonOutput(result)
|
||||
return nil
|
||||
}
|
||||
|
||||
var getExchangesCommand = cli.Command{
|
||||
Name: "getexchanges",
|
||||
Usage: "gets a list of enabled or available exchanges",
|
||||
|
||||
@@ -89,6 +89,7 @@ func main() {
|
||||
enableSubsystemCommand,
|
||||
disableSubsystemCommand,
|
||||
getRPCEndpointsCommand,
|
||||
getCommunicationRelayersCommand,
|
||||
getExchangesCommand,
|
||||
enableExchangeCommand,
|
||||
disableExchangeCommand,
|
||||
|
||||
@@ -24,6 +24,12 @@ type Event struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
// CommsStatus stores the status of a comms relayer
|
||||
type CommsStatus struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Connected bool `json:"connected"`
|
||||
}
|
||||
|
||||
// IsEnabled returns if the comms package has been enabled in the configuration
|
||||
func (b *Base) IsEnabled() bool {
|
||||
return b.Enabled
|
||||
|
||||
@@ -30,7 +30,9 @@ func (c IComm) Setup() {
|
||||
err := c[i].Connect()
|
||||
if err != nil {
|
||||
log.Errorf("Communications: %s failed to connect. Err: %s", c[i].GetName(), err)
|
||||
continue
|
||||
}
|
||||
log.Debugf("Communications: %v is enabled and online.", c[i].GetName())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +50,18 @@ func (c IComm) PushEvent(event Event) {
|
||||
}
|
||||
}
|
||||
|
||||
// GetStatus returns the status of the comms relayers
|
||||
func (c IComm) GetStatus() map[string]CommsStatus {
|
||||
result := make(map[string]CommsStatus)
|
||||
for x := range c {
|
||||
result[c[x].GetName()] = CommsStatus{
|
||||
Enabled: c[x].IsEnabled(),
|
||||
Connected: c[x].IsConnected(),
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// GetEnabledCommunicationMediums prints out enabled and connected communication
|
||||
// packages
|
||||
// (#debug output only)
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"net/smtp"
|
||||
"strings"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/communications/base"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -23,6 +23,7 @@ type SMTPservice struct {
|
||||
Port string
|
||||
AccountName string
|
||||
AccountPassword string
|
||||
From string
|
||||
RecipientList string
|
||||
}
|
||||
|
||||
@@ -36,7 +37,9 @@ func (s *SMTPservice) Setup(cfg *config.CommunicationsConfig) {
|
||||
s.Port = cfg.SMTPConfig.Port
|
||||
s.AccountName = cfg.SMTPConfig.AccountName
|
||||
s.AccountPassword = cfg.SMTPConfig.AccountPassword
|
||||
s.From = cfg.SMTPConfig.From
|
||||
s.RecipientList = cfg.SMTPConfig.RecipientList
|
||||
log.Debugf("SMTP: Setup - From: %v. To: %s. Server: %s.", s.From, s.RecipientList, s.Host)
|
||||
}
|
||||
|
||||
// IsConnected returns whether or not the connection is connected
|
||||
@@ -51,36 +54,34 @@ func (s *SMTPservice) Connect() error {
|
||||
}
|
||||
|
||||
// PushEvent sends an event to supplied recipient list via SMTP
|
||||
func (s *SMTPservice) PushEvent(base.Event) error {
|
||||
return common.ErrNotYetImplemented
|
||||
func (s *SMTPservice) PushEvent(e base.Event) error {
|
||||
return s.Send(e.Type, e.Message)
|
||||
}
|
||||
|
||||
// Send sends an email template to the recipient list via your SMTP host when
|
||||
// an internal event is triggered by GoCryptoTrader
|
||||
func (s *SMTPservice) Send(subject, alert string) error {
|
||||
if subject == "" || alert == "" {
|
||||
func (s *SMTPservice) Send(subject, msg string) error {
|
||||
if subject == "" || msg == "" {
|
||||
return errors.New("STMPservice Send() please add subject and alert")
|
||||
}
|
||||
|
||||
list := strings.Split(s.RecipientList, ",")
|
||||
log.Debugf("SMTP: Sending email to %v. Subject: %s Message: %s [From: %s]", s.RecipientList,
|
||||
subject, msg, s.From)
|
||||
messageToSend := fmt.Sprintf(
|
||||
msgSMTP,
|
||||
s.RecipientList,
|
||||
subject,
|
||||
mime,
|
||||
msg)
|
||||
|
||||
for i := range list {
|
||||
messageToSend := fmt.Sprintf(
|
||||
msgSMTP,
|
||||
list[i],
|
||||
subject,
|
||||
mime,
|
||||
alert)
|
||||
|
||||
err := smtp.SendMail(
|
||||
s.Host+":"+s.Port,
|
||||
smtp.PlainAuth("", s.AccountName, s.AccountPassword, s.Host),
|
||||
s.AccountName,
|
||||
[]string{list[i]},
|
||||
[]byte(messageToSend))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err := smtp.SendMail(
|
||||
s.Host+":"+s.Port,
|
||||
smtp.PlainAuth("", s.AccountName, s.AccountPassword, s.Host),
|
||||
s.From,
|
||||
strings.Split(s.RecipientList, ","),
|
||||
[]byte(messageToSend))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -251,6 +251,7 @@ type SMTPConfig struct {
|
||||
Port string `json:"port"`
|
||||
AccountName string `json:"accountName"`
|
||||
AccountPassword string `json:"accountPassword"`
|
||||
From string `json:"from"`
|
||||
RecipientList string `json:"recipientList"`
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,13 @@ func (c *commsManager) Start() (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *commsManager) GetStatus() (map[string]base.CommsStatus, error) {
|
||||
if !c.Started() {
|
||||
return nil, errors.New("communications manager not started")
|
||||
}
|
||||
return c.comms.GetStatus(), nil
|
||||
}
|
||||
|
||||
func (c *commsManager) Stop() error {
|
||||
if atomic.LoadInt32(&c.started) == 0 {
|
||||
return errors.New("communications manager not started")
|
||||
|
||||
@@ -143,14 +143,12 @@ func (e *Event) ExecuteAction() bool {
|
||||
// String turns the structure event into a string
|
||||
func (e *Event) String() string {
|
||||
return fmt.Sprintf(
|
||||
"If the %s%s [%s] %s on %s meets the following %v then %s.", e.Pair.Base.String(),
|
||||
e.Pair.Quote.String(), e.Asset, e.Item, e.Exchange, e.Condition, e.Action,
|
||||
"If the %s [%s] %s on %s meets the following %v then %s.", e.Pair.String(),
|
||||
strings.ToUpper(e.Asset.String()), e.Item, e.Exchange, e.Condition, e.Action,
|
||||
)
|
||||
}
|
||||
|
||||
func (e *Event) processTicker() bool {
|
||||
targetPrice := e.Condition.Price
|
||||
|
||||
t, err := ticker.GetTicker(e.Exchange, e.Pair, e.Asset)
|
||||
if err != nil {
|
||||
if Bot.Settings.Verbose {
|
||||
@@ -159,16 +157,13 @@ func (e *Event) processTicker() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
lastPrice := t.Last
|
||||
|
||||
if lastPrice == 0 {
|
||||
if t.Last == 0 {
|
||||
if Bot.Settings.Verbose {
|
||||
log.Debugln("Events: ticker last price is 0")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return e.processCondition(lastPrice, targetPrice)
|
||||
return e.processCondition(t.Last, e.Condition.Price)
|
||||
}
|
||||
|
||||
func (e *Event) processCondition(actual, threshold float64) bool {
|
||||
@@ -259,14 +254,14 @@ func IsValidEvent(exchange, item string, condition EventConditionParams, action
|
||||
}
|
||||
|
||||
if item == ItemPrice {
|
||||
if condition.Price == 0 {
|
||||
if condition.Price <= 0 {
|
||||
return errInvalidCondition
|
||||
}
|
||||
}
|
||||
|
||||
if item == ItemOrderbook {
|
||||
if condition.OrderbookAmount == 0 {
|
||||
return errInvalidAction
|
||||
if condition.OrderbookAmount <= 0 {
|
||||
return errInvalidCondition
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,10 +271,6 @@ func IsValidEvent(exchange, item string, condition EventConditionParams, action
|
||||
if a[0] != ActionSMSNotify {
|
||||
return errInvalidAction
|
||||
}
|
||||
|
||||
if a[1] != "ALL" {
|
||||
Bot.CommsManager.PushEvent(base.Event{Type: a[1]})
|
||||
}
|
||||
} else if action != ActionConsolePrint && action != ActionTest {
|
||||
return errInvalidAction
|
||||
}
|
||||
@@ -302,10 +293,12 @@ func EventManger() {
|
||||
}
|
||||
success := event.CheckEventCondition()
|
||||
if success {
|
||||
log.Debugf(
|
||||
"Events: ID: %d triggered on %s successfully.\n", event.ID,
|
||||
event.Exchange,
|
||||
msg := fmt.Sprintf(
|
||||
"Events: ID: %d triggered on %s successfully [%v]\n", event.ID,
|
||||
event.Exchange, event.String(),
|
||||
)
|
||||
log.Info(msg)
|
||||
Bot.CommsManager.PushEvent(base.Event{Type: "event", Message: msg})
|
||||
event.Executed = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,369 +1,358 @@
|
||||
package engine
|
||||
|
||||
//
|
||||
// import (
|
||||
// "testing"
|
||||
//
|
||||
// "github.com/thrasher-/gocryptotrader/config"
|
||||
// "github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
// "github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
// "github.com/thrasher-/gocryptotrader/smsglobal"
|
||||
// )
|
||||
//
|
||||
// var (
|
||||
// loaded = false
|
||||
// )
|
||||
//
|
||||
// func testSetup(t *testing.T) {
|
||||
// if !loaded {
|
||||
// cfg := config.GetConfig()
|
||||
// err := cfg.LoadConfig("")
|
||||
// if err != nil {
|
||||
// t.Fatalf("Test failed. Failed to load config %s", err)
|
||||
// }
|
||||
// smsglobal.New(cfg.SMS.Username, cfg.SMS.Password, cfg.Name, cfg.SMS.Contacts)
|
||||
// loaded = true
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func TestAddEvent(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// pair := currency.NewPairFromStrings("BTC", "USD")
|
||||
// eventID, err := AddEvent("ANX", "price", ">,==", pair, assets.AssetTypeSpot, actionTest)
|
||||
// if err != nil && eventID != 0 {
|
||||
// t.Errorf("Test Failed. AddEvent: Error, %s", err)
|
||||
// }
|
||||
// eventID, err = AddEvent("ANXX", "price", ">,==", pair, assets.AssetTypeSpot, actionTest)
|
||||
// if err == nil && eventID == 0 {
|
||||
// t.Error("Test Failed. AddEvent: Error, error not captured in Exchange")
|
||||
// }
|
||||
// eventID, err = AddEvent("ANX", "prices", ">,==", pair, assets.AssetTypeSpot, actionTest)
|
||||
// if err == nil && eventID == 0 {
|
||||
// t.Error("Test Failed. AddEvent: Error, error not captured in Item")
|
||||
// }
|
||||
// eventID, err = AddEvent("ANX", "price", "3===D", pair, assets.AssetTypeSpot, actionTest)
|
||||
// if err == nil && eventID == 0 {
|
||||
// t.Error("Test Failed. AddEvent: Error, error not captured in Condition")
|
||||
// }
|
||||
// eventID, err = AddEvent("ANX", "price", ">,==", pair, assets.AssetTypeSpot, "console_prints")
|
||||
// if err == nil && eventID == 0 {
|
||||
// t.Error("Test Failed. AddEvent: Error, error not captured in Action")
|
||||
// }
|
||||
//
|
||||
// if !RemoveEvent(eventID) {
|
||||
// t.Error("Test Failed. RemoveEvent: Error, error removing event")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func TestRemoveEvent(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// pair := currency.NewPairFromStrings("BTC", "USD")
|
||||
// eventID, err := AddEvent("ANX", "price", ">,==", pair, assets.AssetTypeSpot, actionTest)
|
||||
// if err != nil && eventID != 0 {
|
||||
// t.Errorf("Test Failed. RemoveEvent: Error, %s", err)
|
||||
// }
|
||||
// if !RemoveEvent(eventID) {
|
||||
// t.Error("Test Failed. RemoveEvent: Error, error removing event")
|
||||
// }
|
||||
// if RemoveEvent(1234) {
|
||||
// t.Error("Test Failed. RemoveEvent: Error, error removing event")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func TestGetEventCounter(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// pair := currency.NewPairFromStrings("BTC", "USD")
|
||||
// one, err := AddEvent("ANX", "price", ">,==", pair, assets.AssetTypeSpot, actionTest)
|
||||
// if err != nil {
|
||||
// t.Errorf("Test Failed. GetEventCounter: Error, %s", err)
|
||||
// }
|
||||
// two, err := AddEvent("ANX", "price", ">,==", pair, assets.AssetTypeSpot, actionTest)
|
||||
// if err != nil {
|
||||
// t.Errorf("Test Failed. GetEventCounter: Error, %s", err)
|
||||
// }
|
||||
// three, err := AddEvent("ANX", "price", ">,==", pair, assets.AssetTypeSpot, actionTest)
|
||||
// if err != nil {
|
||||
// t.Errorf("Test Failed. GetEventCounter: Error, %s", err)
|
||||
// }
|
||||
//
|
||||
// Events[three-1].Executed = true
|
||||
//
|
||||
// total, _ := GetEventCounter()
|
||||
// if total <= 0 {
|
||||
// t.Errorf("Test Failed. GetEventCounter: Total = %d", total)
|
||||
// }
|
||||
// if !RemoveEvent(one) {
|
||||
// t.Error("Test Failed. GetEventCounter: Error, error removing event")
|
||||
// }
|
||||
// if !RemoveEvent(two) {
|
||||
// t.Error("Test Failed. GetEventCounter: Error, error removing event")
|
||||
// }
|
||||
// if !RemoveEvent(three) {
|
||||
// t.Error("Test Failed. GetEventCounter: Error, error removing event")
|
||||
// }
|
||||
//
|
||||
// total2, _ := GetEventCounter()
|
||||
// if total2 != 0 {
|
||||
// t.Errorf("Test Failed. GetEventCounter: Total = %d", total2)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func TestExecuteAction(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// pair := currency.NewPairFromStrings("BTC", "USD")
|
||||
// one, err := AddEvent("ANX", "price", ">,==", pair, assets.AssetTypeSpot, actionTest)
|
||||
// if err != nil {
|
||||
// t.Fatalf("Test Failed. ExecuteAction: Error, %s", err)
|
||||
// }
|
||||
// isExecuted := Events[one].ExecuteAction()
|
||||
// if !isExecuted {
|
||||
// t.Error("Test Failed. ExecuteAction: Error, error removing event")
|
||||
// }
|
||||
// if !RemoveEvent(one) {
|
||||
// t.Error("Test Failed. ExecuteAction: Error, error removing event")
|
||||
// }
|
||||
//
|
||||
// action := actionSMSNotify + "," + "ALL"
|
||||
// one, err = AddEvent("ANX", "price", ">,==", pair, assets.AssetTypeSpot, action)
|
||||
// if err != nil {
|
||||
// t.Fatalf("Test Failed. ExecuteAction: Error, %s", err)
|
||||
// }
|
||||
//
|
||||
// isExecuted = Events[one].ExecuteAction()
|
||||
// if !isExecuted {
|
||||
// t.Error("Test Failed. ExecuteAction: Error, error removing event")
|
||||
// }
|
||||
// if !RemoveEvent(one) {
|
||||
// t.Error("Test Failed. ExecuteAction: Error, error removing event")
|
||||
// }
|
||||
//
|
||||
// action = actionSMSNotify + "," + "StyleGherkin"
|
||||
// one, err = AddEvent("ANX", "price", ">,==", pair, assets.AssetTypeSpot, action)
|
||||
// if err != nil {
|
||||
// t.Fatalf("Test Failed. ExecuteAction: Error, %s", err)
|
||||
// }
|
||||
//
|
||||
// isExecuted = Events[one].ExecuteAction()
|
||||
// if !isExecuted {
|
||||
// t.Error("Test Failed. ExecuteAction: Error, error removing event")
|
||||
// }
|
||||
// if !RemoveEvent(one) {
|
||||
// t.Error("Test Failed. ExecuteAction: Error, error removing event")
|
||||
// }
|
||||
// // More tests when ExecuteAction is expanded
|
||||
// }
|
||||
//
|
||||
// func TestEventToString(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// pair := currency.NewPairFromStrings("BTC", "USD")
|
||||
// one, err := AddEvent("ANX", "price", ">,==", pair, assets.AssetTypeSpot, actionTest)
|
||||
// if err != nil {
|
||||
// t.Errorf("Test Failed. EventToString: Error, %s", err)
|
||||
// }
|
||||
//
|
||||
// eventString := Events[one].String()
|
||||
// if eventString != "If the BTCUSD [SPOT] price on ANX is > == then ACTION_TEST." {
|
||||
// t.Error("Test Failed. EventToString: Error, incorrect return string")
|
||||
// }
|
||||
//
|
||||
// if !RemoveEvent(one) {
|
||||
// t.Error("Test Failed. EventToString: Error, error removing event")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func TestCheckCondition(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// // Test invalid currency pair
|
||||
// newPair := currency.NewPairFromStrings("A", "B")
|
||||
// one, err := AddEvent("ANX", "price", ">=,10", newPair, assets.AssetTypeSpot, actionTest)
|
||||
// if err != nil {
|
||||
// t.Errorf("Test Failed. CheckCondition: Error, %s", err)
|
||||
// }
|
||||
// conditionBool := Events[one].CheckCondition()
|
||||
// if conditionBool {
|
||||
// t.Error("Test Failed. CheckCondition: Error, wrong conditional.")
|
||||
// }
|
||||
//
|
||||
// // Test last price == 0
|
||||
// var tickerNew ticker.Price
|
||||
// tickerNew.Last = 0
|
||||
// newPair = currency.NewPairFromStrings("BTC", "USD")
|
||||
// ticker.ProcessTicker("ANX", newPair, tickerNew, exchange.AssetTypeSpot)
|
||||
// Events[one].Pair = newPair
|
||||
// conditionBool = Events[one].CheckCondition()
|
||||
// if conditionBool {
|
||||
// t.Error("Test Failed. CheckCondition: Error, wrong conditional.")
|
||||
// }
|
||||
//
|
||||
// // Test last pricce > 0 and conditional logic
|
||||
// tickerNew.Last = 11
|
||||
// ticker.ProcessTicker("ANX", newPair, tickerNew, exchange.AssetTypeSpot)
|
||||
// Events[one].Condition = ">,10"
|
||||
// conditionBool = Events[one].CheckCondition()
|
||||
// if !conditionBool {
|
||||
// t.Error("Test Failed. CheckCondition: Error, wrong conditional.")
|
||||
// }
|
||||
//
|
||||
// // Test last price >= 10
|
||||
// Events[one].Condition = ">=,10"
|
||||
// conditionBool = Events[one].CheckCondition()
|
||||
// if !conditionBool {
|
||||
// t.Error("Test Failed. CheckCondition: Error, wrong conditional.")
|
||||
// }
|
||||
//
|
||||
// // Test last price <= 10
|
||||
// Events[one].Condition = "<,100"
|
||||
// conditionBool = Events[one].CheckCondition()
|
||||
// if !conditionBool {
|
||||
// t.Error("Test Failed. CheckCondition: Error, wrong conditional.")
|
||||
// }
|
||||
//
|
||||
// // Test last price <= 10
|
||||
// Events[one].Condition = "<=,100"
|
||||
// conditionBool = Events[one].CheckCondition()
|
||||
// if !conditionBool {
|
||||
// t.Error("Test Failed. CheckCondition: Error, wrong conditional.")
|
||||
// }
|
||||
//
|
||||
// Events[one].Condition = "==,11"
|
||||
// conditionBool = Events[one].CheckCondition()
|
||||
// if !conditionBool {
|
||||
// t.Error("Test Failed. CheckCondition: Error, wrong conditional.")
|
||||
// }
|
||||
//
|
||||
// Events[one].Condition = "^,11"
|
||||
// conditionBool = Events[one].CheckCondition()
|
||||
// if conditionBool {
|
||||
// t.Error("Test Failed. CheckCondition: Error, wrong conditional.")
|
||||
// }
|
||||
//
|
||||
// if !RemoveEvent(one) {
|
||||
// t.Error("Test Failed. CheckCondition: Error, error removing event")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func TestIsValidEvent(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// err := IsValidEvent("ANX", "price", ">,==", actionTest)
|
||||
// if err != nil {
|
||||
// t.Errorf("Test Failed. IsValidEvent: %s", err)
|
||||
// }
|
||||
// err = IsValidEvent("ANX", "price", ">,", actionTest)
|
||||
// if err == nil {
|
||||
// t.Errorf("Test Failed. IsValidEvent: %s", err)
|
||||
// }
|
||||
// err = IsValidEvent("ANX", "Testy", ">,==", actionTest)
|
||||
// if err == nil {
|
||||
// t.Errorf("Test Failed. IsValidEvent: %s", err)
|
||||
// }
|
||||
// err = IsValidEvent("Testys", "price", ">,==", actionTest)
|
||||
// if err == nil {
|
||||
// t.Errorf("Test Failed. IsValidEvent: %s", err)
|
||||
// }
|
||||
//
|
||||
// action := "blah,blah"
|
||||
// err = IsValidEvent("ANX", "price", ">=,10", action)
|
||||
// if err == nil {
|
||||
// t.Errorf("Test Failed. IsValidEvent: %s", err)
|
||||
// }
|
||||
//
|
||||
// action = "SMS,blah"
|
||||
// err = IsValidEvent("ANX", "price", ">=,10", action)
|
||||
// if err == nil {
|
||||
// t.Errorf("Test Failed. IsValidEvent: %s", err)
|
||||
// }
|
||||
//
|
||||
// //Function tests need to appended to this function when more actions are
|
||||
// //implemented
|
||||
// }
|
||||
//
|
||||
// func TestCheckEvents(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// pair := currency.NewPairFromStrings("BTC", "USD")
|
||||
// _, err := AddEvent("ANX", "price", ">=,10", pair, assets.AssetTypeSpot, actionTest)
|
||||
// if err != nil {
|
||||
// t.Fatal("Test failed. TestChcheckEvents add event")
|
||||
// }
|
||||
//
|
||||
// go CheckEvents()
|
||||
// }
|
||||
//
|
||||
// func TestIsValidExchange(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// boolean := IsValidExchange("ANX")
|
||||
// if !boolean {
|
||||
// t.Error("Test Failed. IsValidExchange: Error, incorrect Exchange")
|
||||
// }
|
||||
// boolean = IsValidExchange("OBTUSE")
|
||||
// if boolean {
|
||||
// t.Error("Test Failed. IsValidExchange: Error, incorrect return")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func TestIsValidCondition(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// boolean := IsValidCondition(">")
|
||||
// if !boolean {
|
||||
// t.Error("Test Failed. IsValidCondition: Error, incorrect Condition")
|
||||
// }
|
||||
// boolean = IsValidCondition(">=")
|
||||
// if !boolean {
|
||||
// t.Error("Test Failed. IsValidCondition: Error, incorrect Condition")
|
||||
// }
|
||||
// boolean = IsValidCondition("<")
|
||||
// if !boolean {
|
||||
// t.Error("Test Failed. IsValidCondition: Error, incorrect Condition")
|
||||
// }
|
||||
// boolean = IsValidCondition("<=")
|
||||
// if !boolean {
|
||||
// t.Error("Test Failed. IsValidCondition: Error, incorrect Condition")
|
||||
// }
|
||||
// boolean = IsValidCondition("==")
|
||||
// if !boolean {
|
||||
// t.Error("Test Failed. IsValidCondition: Error, incorrect Condition")
|
||||
// }
|
||||
// boolean = IsValidCondition("**********")
|
||||
// if boolean {
|
||||
// t.Error("Test Failed. IsValidCondition: Error, incorrect return")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func TestIsValidAction(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// boolean := IsValidAction("sms")
|
||||
// if !boolean {
|
||||
// t.Error("Test Failed. IsValidAction: Error, incorrect Action")
|
||||
// }
|
||||
// boolean = IsValidAction(actionTest)
|
||||
// if !boolean {
|
||||
// t.Error("Test Failed. IsValidAction: Error, incorrect Action")
|
||||
// }
|
||||
// boolean = IsValidAction("randomstring")
|
||||
// if boolean {
|
||||
// t.Error("Test Failed. IsValidAction: Error, incorrect return")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func TestIsValidItem(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// boolean := IsValidItem("price")
|
||||
// if !boolean {
|
||||
// t.Error("Test Failed. IsValidItem: Error, incorrect Item")
|
||||
// }
|
||||
// boolean = IsValidItem("obtuse")
|
||||
// if boolean {
|
||||
// t.Error("Test Failed. IsValidItem: Error, incorrect return")
|
||||
// }
|
||||
// }
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/assets"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
)
|
||||
|
||||
const (
|
||||
testExchange = "Bitstamp"
|
||||
)
|
||||
|
||||
var (
|
||||
configLoaded = false
|
||||
)
|
||||
|
||||
func addValidEvent() (int64, error) {
|
||||
return Add(testExchange,
|
||||
ItemPrice,
|
||||
EventConditionParams{Condition: ConditionGreaterThan, Price: 1},
|
||||
currency.NewPair(currency.BTC, currency.USD),
|
||||
assets.AssetTypeSpot,
|
||||
"SMS,test")
|
||||
}
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
if !configLoaded {
|
||||
loadConfig(t)
|
||||
}
|
||||
|
||||
_, err := Add("", "", EventConditionParams{}, currency.Pair{}, "", "")
|
||||
if err == nil {
|
||||
t.Error("should err on invalid params")
|
||||
}
|
||||
|
||||
_, err = addValidEvent()
|
||||
if err != nil {
|
||||
t.Error("unexpected result", err)
|
||||
}
|
||||
|
||||
_, err = addValidEvent()
|
||||
if err != nil {
|
||||
t.Error("unexpected result", err)
|
||||
}
|
||||
|
||||
if len(Events) != 2 {
|
||||
t.Error("2 events should be stored")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemove(t *testing.T) {
|
||||
if !configLoaded {
|
||||
loadConfig(t)
|
||||
}
|
||||
|
||||
id, err := addValidEvent()
|
||||
if err != nil {
|
||||
t.Error("unexpected result", err)
|
||||
}
|
||||
|
||||
if s := Remove(id); !s {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
|
||||
if s := Remove(id); s {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetEventCounter(t *testing.T) {
|
||||
if !configLoaded {
|
||||
loadConfig(t)
|
||||
}
|
||||
|
||||
_, err := addValidEvent()
|
||||
if err != nil {
|
||||
t.Error("unexpected result", err)
|
||||
}
|
||||
|
||||
n, e := GetEventCounter()
|
||||
if n == 0 || e > 0 {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
|
||||
Events[0].Executed = true
|
||||
n, e = GetEventCounter()
|
||||
if n == 0 || e == 0 {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecuteAction(t *testing.T) {
|
||||
t.Parallel()
|
||||
if Bot == nil {
|
||||
Bot = new(Engine)
|
||||
}
|
||||
|
||||
var e Event
|
||||
if r := e.ExecuteAction(); !r {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
|
||||
e.Action = "SMS,test"
|
||||
if r := e.ExecuteAction(); !r {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
|
||||
e.Action = "SMS,ALL"
|
||||
if r := e.ExecuteAction(); !r {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
t.Parallel()
|
||||
e := Event{
|
||||
Exchange: testExchange,
|
||||
Item: ItemPrice,
|
||||
Condition: EventConditionParams{
|
||||
Condition: ConditionGreaterThan,
|
||||
Price: 1,
|
||||
},
|
||||
Pair: currency.NewPair(currency.BTC, currency.USD),
|
||||
Asset: assets.AssetTypeSpot,
|
||||
Action: "SMS,ALL",
|
||||
}
|
||||
|
||||
if r := e.String(); r != "If the BTCUSD [SPOT] PRICE on Bitstamp meets the following {> 1 false false 0} then SMS,ALL." {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessTicker(t *testing.T) {
|
||||
if Bot == nil {
|
||||
Bot = new(Engine)
|
||||
}
|
||||
Bot.Settings.Verbose = true
|
||||
|
||||
e := Event{
|
||||
Exchange: testExchange,
|
||||
Pair: currency.NewPair(currency.BTC, currency.USD),
|
||||
Asset: assets.AssetTypeSpot,
|
||||
Condition: EventConditionParams{
|
||||
Condition: ConditionGreaterThan,
|
||||
Price: 1,
|
||||
},
|
||||
}
|
||||
|
||||
// this will throw an err with an unpopulated ticker
|
||||
ticker.Tickers = nil
|
||||
if r := e.processTicker(); r {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
|
||||
// now populate it with a 0 entry
|
||||
tick := ticker.Price{
|
||||
Pair: currency.NewPair(currency.BTC, currency.USD),
|
||||
Last: 0,
|
||||
}
|
||||
if err := ticker.ProcessTicker(e.Exchange, &tick, e.Asset); err != nil {
|
||||
t.Fatal("unexpected result:", err)
|
||||
}
|
||||
if r := e.processTicker(); r {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
|
||||
// now populate it with a number > 0
|
||||
tick.Last = 1337
|
||||
if err := ticker.ProcessTicker(e.Exchange, &tick, e.Asset); err != nil {
|
||||
t.Fatal("unexpected result:", err)
|
||||
}
|
||||
if r := e.processTicker(); !r {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessCondition(t *testing.T) {
|
||||
t.Parallel()
|
||||
var e Event
|
||||
tester := []struct {
|
||||
Condition string
|
||||
Actual float64
|
||||
Threshold float64
|
||||
ExpectedResult bool
|
||||
}{
|
||||
{ConditionGreaterThan, 1, 2, false},
|
||||
{ConditionGreaterThan, 2, 1, true},
|
||||
{ConditionGreaterThanOrEqual, 1, 2, false},
|
||||
{ConditionGreaterThanOrEqual, 2, 1, true},
|
||||
{ConditionIsEqual, 1, 1, true},
|
||||
{ConditionIsEqual, 1, 2, false},
|
||||
{ConditionLessThan, 1, 2, true},
|
||||
{ConditionLessThan, 2, 1, false},
|
||||
{ConditionLessThanOrEqual, 1, 2, true},
|
||||
{ConditionLessThanOrEqual, 2, 1, false},
|
||||
}
|
||||
for x := range tester {
|
||||
e.Condition.Condition = tester[x].Condition
|
||||
if r := e.processCondition(tester[x].Actual, tester[x].Threshold); r != tester[x].ExpectedResult {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessOrderbook(t *testing.T) {
|
||||
if Bot == nil {
|
||||
Bot = new(Engine)
|
||||
}
|
||||
Bot.Settings.Verbose = true
|
||||
|
||||
e := Event{
|
||||
Exchange: testExchange,
|
||||
Pair: currency.NewPair(currency.BTC, currency.USD),
|
||||
Asset: assets.AssetTypeSpot,
|
||||
Condition: EventConditionParams{
|
||||
Condition: ConditionGreaterThan,
|
||||
CheckBidsAndAsks: true,
|
||||
OrderbookAmount: 100,
|
||||
},
|
||||
}
|
||||
|
||||
// this will throw an err with an unpopulated orderbook
|
||||
orderbook.Orderbooks = nil
|
||||
if r := e.processOrderbook(); r {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
|
||||
// now populate it with a 0 entry
|
||||
o := orderbook.Base{
|
||||
Pair: currency.NewPair(currency.BTC, currency.USD),
|
||||
Bids: []orderbook.Item{{Amount: 24, Price: 23}},
|
||||
Asks: []orderbook.Item{{Amount: 24, Price: 23}},
|
||||
ExchangeName: e.Exchange,
|
||||
AssetType: e.Asset,
|
||||
}
|
||||
if err := o.Process(); err != nil {
|
||||
t.Fatal("unexpected result:", err)
|
||||
}
|
||||
|
||||
if r := e.processOrderbook(); !r {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckEventCondition(t *testing.T) {
|
||||
t.Parallel()
|
||||
if Bot == nil {
|
||||
Bot = new(Engine)
|
||||
}
|
||||
Bot.Settings.Verbose = true
|
||||
|
||||
e := Event{
|
||||
Item: ItemPrice,
|
||||
}
|
||||
if r := e.CheckEventCondition(); r {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
|
||||
e.Item = ItemOrderbook
|
||||
if r := e.CheckEventCondition(); r {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidEvent(t *testing.T) {
|
||||
if !configLoaded {
|
||||
loadConfig(t)
|
||||
}
|
||||
|
||||
// invalid exchange name
|
||||
if err := IsValidEvent("meow", "", EventConditionParams{}, ""); err != errExchangeDisabled {
|
||||
t.Error("unexpected result:", err)
|
||||
}
|
||||
|
||||
// invalid item
|
||||
if err := IsValidEvent(testExchange, "", EventConditionParams{}, ""); err != errInvalidItem {
|
||||
t.Error("unexpected result:", err)
|
||||
}
|
||||
|
||||
// invalid condition
|
||||
if err := IsValidEvent(testExchange, ItemPrice, EventConditionParams{}, ""); err != errInvalidCondition {
|
||||
t.Error("unexpected result:", err)
|
||||
}
|
||||
|
||||
// valid condition but empty price which will still throw an errInvalidCondition
|
||||
c := EventConditionParams{
|
||||
Condition: ConditionGreaterThan,
|
||||
}
|
||||
if err := IsValidEvent(testExchange, ItemPrice, c, ""); err != errInvalidCondition {
|
||||
t.Error("unexpected result:", err)
|
||||
}
|
||||
|
||||
// valid condition but empty orderbook amount will still still throw an errInvalidCondition
|
||||
if err := IsValidEvent(testExchange, ItemOrderbook, c, ""); err != errInvalidCondition {
|
||||
t.Error("unexpected result:", err)
|
||||
}
|
||||
|
||||
// test action splitting, but invalid
|
||||
c.OrderbookAmount = 1337
|
||||
if err := IsValidEvent(testExchange, ItemOrderbook, c, "a,meow"); err != errInvalidAction {
|
||||
t.Error("unexpected result:", err)
|
||||
}
|
||||
|
||||
// check for invalid action without splitting
|
||||
if err := IsValidEvent(testExchange, ItemOrderbook, c, "hi"); err != errInvalidAction {
|
||||
t.Error("unexpected result:", err)
|
||||
}
|
||||
|
||||
// valid event
|
||||
if err := IsValidEvent(testExchange, ItemOrderbook, c, "SMS,test"); err != nil {
|
||||
t.Error("unexpected result:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidExchange(t *testing.T) {
|
||||
t.Parallel()
|
||||
if s := IsValidExchange("invalidexchangerino"); s {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
|
||||
loadConfig(t)
|
||||
if s := IsValidExchange(testExchange); !s {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidCondition(t *testing.T) {
|
||||
t.Parallel()
|
||||
if s := IsValidCondition("invalidconditionerino"); s {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
if s := IsValidCondition(ConditionGreaterThan); !s {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidAction(t *testing.T) {
|
||||
t.Parallel()
|
||||
if s := IsValidAction("invalidactionerino"); s {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
if s := IsValidAction(ActionSMSNotify); !s {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidItem(t *testing.T) {
|
||||
t.Parallel()
|
||||
if s := IsValidItem("invaliditemerino"); s {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
if s := IsValidItem(ItemPrice); !s {
|
||||
t.Error("unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +195,24 @@ func (s *RPCServer) GetRPCEndpoints(ctx context.Context, r *gctrpc.GetRPCEndpoin
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// GetCommunicationRelayers returns the status of the engines communication relayers
|
||||
func (s *RPCServer) GetCommunicationRelayers(ctx context.Context, r *gctrpc.GetCommunicationRelayersRequest) (*gctrpc.GetCommunicationRelayersResponse, error) {
|
||||
relayers, err := Bot.CommsManager.GetStatus()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp gctrpc.GetCommunicationRelayersResponse
|
||||
resp.CommunicationRelayers = make(map[string]*gctrpc.CommunicationRelayer)
|
||||
for k, v := range relayers {
|
||||
resp.CommunicationRelayers[k] = &gctrpc.CommunicationRelayer{
|
||||
Enabled: v.Enabled,
|
||||
Connected: v.Connected,
|
||||
}
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// GetExchanges returns a list of exchanges
|
||||
// Param is whether or not you wish to list enabled exchanges
|
||||
func (s *RPCServer) GetExchanges(ctx context.Context, r *gctrpc.GetExchangesRequest) (*gctrpc.GetExchangesResponse, error) {
|
||||
|
||||
755
gctrpc/rpc.pb.go
755
gctrpc/rpc.pb.go
File diff suppressed because it is too large
Load Diff
@@ -89,6 +89,15 @@ func request_GoCryptoTrader_GetRPCEndpoints_0(ctx context.Context, marshaler run
|
||||
|
||||
}
|
||||
|
||||
func request_GoCryptoTrader_GetCommunicationRelayers_0(ctx context.Context, marshaler runtime.Marshaler, client GoCryptoTraderClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetCommunicationRelayersRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.GetCommunicationRelayers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_GoCryptoTrader_GetExchanges_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
@@ -665,6 +674,26 @@ func RegisterGoCryptoTraderHandlerClient(ctx context.Context, mux *runtime.Serve
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_GoCryptoTrader_GetCommunicationRelayers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_GoCryptoTrader_GetCommunicationRelayers_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_GoCryptoTrader_GetCommunicationRelayers_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_GoCryptoTrader_GetExchanges_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
@@ -1279,6 +1308,8 @@ var (
|
||||
|
||||
pattern_GoCryptoTrader_GetRPCEndpoints_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "getrpcendpoints"}, ""))
|
||||
|
||||
pattern_GoCryptoTrader_GetCommunicationRelayers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "getcommunicationrelayers"}, ""))
|
||||
|
||||
pattern_GoCryptoTrader_GetExchanges_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "getexchanges"}, ""))
|
||||
|
||||
pattern_GoCryptoTrader_DisableExchange_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "disableexchange"}, ""))
|
||||
@@ -1351,6 +1382,8 @@ var (
|
||||
|
||||
forward_GoCryptoTrader_GetRPCEndpoints_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_GoCryptoTrader_GetCommunicationRelayers_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_GoCryptoTrader_GetExchanges_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_GoCryptoTrader_DisableExchange_0 = runtime.ForwardResponseMessage
|
||||
|
||||
@@ -16,9 +16,16 @@ message GetInfoResponse {
|
||||
map<string, RPCEndpoint> rpc_endpoints = 7;
|
||||
}
|
||||
|
||||
// TO-DO comms APIs
|
||||
message GetCommunicationRelayersRequest {}
|
||||
message GetCommunicationRelayersResponse {}
|
||||
|
||||
message CommunicationRelayer {
|
||||
bool enabled = 1;
|
||||
bool connected = 2;
|
||||
}
|
||||
|
||||
message GetCommunicationRelayersResponse {
|
||||
map<string, CommunicationRelayer> communication_relayers = 1;
|
||||
}
|
||||
|
||||
message GenericSubsystemRequest {
|
||||
string subsystem = 1;
|
||||
@@ -456,6 +463,12 @@ service GoCryptoTrader {
|
||||
};
|
||||
}
|
||||
|
||||
rpc GetCommunicationRelayers (GetCommunicationRelayersRequest) returns (GetCommunicationRelayersResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/v1/getcommunicationrelayers"
|
||||
};
|
||||
}
|
||||
|
||||
rpc GetExchanges (GetExchangesRequest) returns (GetExchangesResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/v1/getexchanges"
|
||||
|
||||
@@ -243,6 +243,22 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/getcommunicationrelayers": {
|
||||
"get": {
|
||||
"operationId": "GetCommunicationRelayers",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/gctrpcGetCommunicationRelayersResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"GoCryptoTrader"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/getconfig": {
|
||||
"get": {
|
||||
"operationId": "GetConfig",
|
||||
@@ -960,6 +976,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"gctrpcCommunicationRelayer": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"format": "boolean"
|
||||
},
|
||||
"connected": {
|
||||
"type": "boolean",
|
||||
"format": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gctrpcConditionParams": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -1075,6 +1104,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"gctrpcGetCommunicationRelayersResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"communication_relayers": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/gctrpcCommunicationRelayer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"gctrpcGetConfigResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
Reference in New Issue
Block a user