mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
Formatting, linter and test for portfolio
This commit is contained in:
committed by
Adrian Gallagher
parent
3e4fb1660d
commit
f11f83fe50
@@ -80,7 +80,7 @@ type Config struct {
|
||||
Name string
|
||||
EncryptConfig int
|
||||
Cryptocurrencies string
|
||||
Portfolio portfolio.PortfolioBase `json:"PortfolioAddresses"`
|
||||
Portfolio portfolio.Base `json:"PortfolioAddresses"`
|
||||
SMS SMSGlobalConfig `json:"SMSGlobal"`
|
||||
Webserver WebserverConfig `json:"Webserver"`
|
||||
Exchanges []ExchangeConfig `json:"Exchanges"`
|
||||
|
||||
@@ -5,19 +5,19 @@ import (
|
||||
)
|
||||
|
||||
func TestAddEvent(t *testing.T) {
|
||||
eventID, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", ACTION_TEST)
|
||||
eventID, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", actionTest)
|
||||
if err != nil && eventID != 0 {
|
||||
t.Errorf("Test Failed. AddEvent: Error, %s", err)
|
||||
}
|
||||
eventID, err = AddEvent("ANXX", "price", ">,==", "BTC", "LTC", ACTION_TEST)
|
||||
eventID, err = AddEvent("ANXX", "price", ">,==", "BTC", "LTC", actionTest)
|
||||
if err == nil && eventID == 0 {
|
||||
t.Error("Test Failed. AddEvent: Error, error not captured in Exchange")
|
||||
}
|
||||
eventID, err = AddEvent("ANX", "prices", ">,==", "BTC", "LTC", ACTION_TEST)
|
||||
eventID, err = AddEvent("ANX", "prices", ">,==", "BTC", "LTC", actionTest)
|
||||
if err == nil && eventID == 0 {
|
||||
t.Error("Test Failed. AddEvent: Error, error not captured in Item")
|
||||
}
|
||||
eventID, err = AddEvent("ANX", "price", "3===D", "BTC", "LTC", ACTION_TEST)
|
||||
eventID, err = AddEvent("ANX", "price", "3===D", "BTC", "LTC", actionTest)
|
||||
if err == nil && eventID == 0 {
|
||||
t.Error("Test Failed. AddEvent: Error, error not captured in Condition")
|
||||
}
|
||||
@@ -25,7 +25,7 @@ func TestAddEvent(t *testing.T) {
|
||||
if err == nil && eventID == 0 {
|
||||
t.Error("Test Failed. AddEvent: Error, error not captured in Action")
|
||||
}
|
||||
eventID, err = AddEvent("ANX", "price", ">,==", "BATMAN", "ROBIN", ACTION_TEST)
|
||||
eventID, err = AddEvent("ANX", "price", ">,==", "BATMAN", "ROBIN", actionTest)
|
||||
if err == nil && eventID == 0 {
|
||||
t.Error("Test Failed. AddEvent: Error, error not captured in Action")
|
||||
}
|
||||
@@ -35,34 +35,38 @@ func TestAddEvent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRemoveEvent(t *testing.T) {
|
||||
eventID, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", ACTION_TEST)
|
||||
eventID, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", 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) {
|
||||
one, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", ACTION_TEST)
|
||||
one, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", actionTest)
|
||||
if err != nil {
|
||||
t.Errorf("Test Failed. GetEventCounter: Error, %s", err)
|
||||
}
|
||||
two, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", ACTION_TEST)
|
||||
two, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", actionTest)
|
||||
if err != nil {
|
||||
t.Errorf("Test Failed. GetEventCounter: Error, %s", err)
|
||||
}
|
||||
three, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", ACTION_TEST)
|
||||
three, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", 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")
|
||||
}
|
||||
@@ -80,7 +84,7 @@ func TestGetEventCounter(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExecuteAction(t *testing.T) {
|
||||
one, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", ACTION_TEST)
|
||||
one, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", actionTest)
|
||||
if err != nil {
|
||||
t.Errorf("Test Failed. ExecuteAction: Error, %s", err)
|
||||
}
|
||||
@@ -88,14 +92,15 @@ func TestExecuteAction(t *testing.T) {
|
||||
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) {
|
||||
one, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", ACTION_TEST)
|
||||
one, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", actionTest)
|
||||
if err != nil {
|
||||
t.Errorf("Test Failed. EventToString: Error, %s", err)
|
||||
}
|
||||
@@ -108,11 +113,10 @@ func TestEventToString(t *testing.T) {
|
||||
if !RemoveEvent(one) {
|
||||
t.Error("Test Failed. EventToString: Error, error removing event")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestCheckCondition(t *testing.T) { //error handling needs to be implemented
|
||||
one, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", ACTION_TEST)
|
||||
one, err := AddEvent("ANX", "price", ">,==", "BTC", "LTC", actionTest)
|
||||
if err != nil {
|
||||
t.Errorf("Test Failed. EventToString: Error, %s", err)
|
||||
}
|
||||
@@ -125,26 +129,58 @@ func TestCheckCondition(t *testing.T) { //error handling needs to be implemented
|
||||
if !RemoveEvent(one) {
|
||||
t.Error("Test Failed. EventToString: Error, error removing event")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestIsValidEvent(t *testing.T) {
|
||||
err := IsValidEvent("ANX", "price", ">,==", ACTION_TEST)
|
||||
err := IsValidEvent("ANX", "price", ">,==", actionTest)
|
||||
if err != nil {
|
||||
t.Errorf("Test Failed. IsValidExchange: Error %s", err)
|
||||
}
|
||||
err = IsValidEvent("ANX", "price", ">,", actionTest)
|
||||
if err == nil {
|
||||
t.Errorf("Test Failed. IsValidExchange: Error")
|
||||
}
|
||||
err = IsValidEvent("ANX", "Testy", ">,==", actionTest)
|
||||
if err == nil {
|
||||
t.Errorf("Test Failed. IsValidExchange: Error")
|
||||
}
|
||||
err = IsValidEvent("Testys", "price", ">,==", actionTest)
|
||||
if err == nil {
|
||||
t.Errorf("Test Failed. IsValidExchange: Error")
|
||||
}
|
||||
|
||||
//Function tests need to appended to this function when more actions are
|
||||
//implemented
|
||||
}
|
||||
|
||||
func TestCheckEvents(t *testing.T) { //Add error handling
|
||||
//CheckEvents() //check once error handling is implemented
|
||||
}
|
||||
|
||||
func TestIsValidCurrency(t *testing.T) {
|
||||
if !IsValidCurrency("BTC") {
|
||||
t.Error("Test Failed - Event_test.go TestIsValidCurrency Error")
|
||||
}
|
||||
if !IsValidCurrency("USD") {
|
||||
t.Error("Test Failed - Event_test.go TestIsValidCurrency Error")
|
||||
}
|
||||
if IsValidCurrency("testy") {
|
||||
t.Error("Test Failed - Event_test.go TestIsValidCurrency Error")
|
||||
}
|
||||
if !IsValidCurrency("USD", "BTC", "USD") {
|
||||
t.Error("Test Failed - Event_test.go TestIsValidCurrency Error")
|
||||
}
|
||||
if IsValidCurrency("USD", "USD", "Wigwham") {
|
||||
t.Error("Test Failed - Event_test.go TestIsValidCurrency Error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidExchange(t *testing.T) {
|
||||
boolean := IsValidExchange("ANX", CONFIG_PATH_TEST)
|
||||
boolean := IsValidExchange("ANX", configPathTest)
|
||||
if !boolean {
|
||||
t.Error("Test Failed. IsValidExchange: Error, incorrect Exchange")
|
||||
}
|
||||
boolean = IsValidExchange("OBTUSE", CONFIG_PATH_TEST)
|
||||
boolean = IsValidExchange("OBTUSE", configPathTest)
|
||||
if boolean {
|
||||
t.Error("Test Failed. IsValidExchange: Error, incorrect return")
|
||||
}
|
||||
@@ -182,7 +218,7 @@ func TestIsValidAction(t *testing.T) {
|
||||
if !boolean {
|
||||
t.Error("Test Failed. IsValidAction: Error, incorrect Action")
|
||||
}
|
||||
boolean = IsValidAction(ACTION_TEST)
|
||||
boolean = IsValidAction(actionTest)
|
||||
if !boolean {
|
||||
t.Error("Test Failed. IsValidAction: Error, incorrect Action")
|
||||
}
|
||||
|
||||
126
events/events.go
126
events/events.go
@@ -15,26 +15,27 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
ITEM_PRICE = "PRICE"
|
||||
GREATER_THAN = ">"
|
||||
GREATER_THAN_OR_EQUAL = ">="
|
||||
LESS_THAN = "<"
|
||||
LESS_THAN_OR_EQUAL = "<="
|
||||
IS_EQUAL = "=="
|
||||
ACTION_SMS_NOTIFY = "SMS"
|
||||
ACTION_CONSOLE_PRINT = "CONSOLE_PRINT"
|
||||
ACTION_TEST = "ACTION_TEST"
|
||||
CONFIG_PATH_TEST = config.ConfigTestFile
|
||||
itemPrice = "PRICE"
|
||||
greaterThan = ">"
|
||||
greaterThanOrEqual = ">="
|
||||
lessThan = "<"
|
||||
lessThanOrEqual = "<="
|
||||
isEqual = "=="
|
||||
actionSMSNotify = "SMS"
|
||||
actionConsolePrint = "CONSOLE_PRINT"
|
||||
actionTest = "ACTION_TEST"
|
||||
configPathTest = config.ConfigTestFile
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidItem = errors.New("Invalid item.")
|
||||
ErrInvalidCondition = errors.New("Invalid conditional option.")
|
||||
ErrInvalidAction = errors.New("Invalid action.")
|
||||
ErrExchangeDisabled = errors.New("Desired exchange is disabled.")
|
||||
ErrCurrencyInvalid = errors.New("Invalid currency.")
|
||||
errInvalidItem = errors.New("invalid item")
|
||||
errInvalidCondition = errors.New("invalid conditional option")
|
||||
errInvalidAction = errors.New("invalid action")
|
||||
errExchangeDisabled = errors.New("desired exchange is disabled")
|
||||
errCurrencyInvalid = errors.New("invalid currency")
|
||||
)
|
||||
|
||||
// Event struct holds the event variables
|
||||
type Event struct {
|
||||
ID int
|
||||
Exchange string
|
||||
@@ -46,8 +47,12 @@ type Event struct {
|
||||
Executed bool
|
||||
}
|
||||
|
||||
// Events variable is a pointer array to the event structures that will be
|
||||
// appended
|
||||
var Events []*Event
|
||||
|
||||
// AddEvent adds an event to the Events chain and returns an index/eventID
|
||||
// and an error
|
||||
func AddEvent(Exchange, Item, Condition, FirstCurrency, SecondCurrency, Action string) (int, error) {
|
||||
err := IsValidEvent(Exchange, Item, Condition, Action)
|
||||
if err != nil {
|
||||
@@ -55,7 +60,7 @@ func AddEvent(Exchange, Item, Condition, FirstCurrency, SecondCurrency, Action s
|
||||
}
|
||||
|
||||
if !IsValidCurrency(FirstCurrency, SecondCurrency) {
|
||||
return 0, ErrCurrencyInvalid
|
||||
return 0, errCurrencyInvalid
|
||||
}
|
||||
|
||||
Event := &Event{}
|
||||
@@ -77,6 +82,7 @@ func AddEvent(Exchange, Item, Condition, FirstCurrency, SecondCurrency, Action s
|
||||
return Event.ID, nil
|
||||
}
|
||||
|
||||
// RemoveEvent deletes and event by its ID
|
||||
func RemoveEvent(EventID int) bool {
|
||||
for i, x := range Events {
|
||||
if x.ID == EventID {
|
||||
@@ -87,6 +93,8 @@ func RemoveEvent(EventID int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetEventCounter displays the emount of total events on the chain and the
|
||||
// events that have been executed.
|
||||
func GetEventCounter() (int, int) {
|
||||
total := len(Events)
|
||||
executed := 0
|
||||
@@ -99,15 +107,18 @@ func GetEventCounter() (int, int) {
|
||||
return total, executed
|
||||
}
|
||||
|
||||
// ExecuteAction will execute the action pending on the chain
|
||||
func (e *Event) ExecuteAction() bool {
|
||||
if common.StringContains(e.Action, ",") {
|
||||
action := common.SplitStrings(e.Action, ",")
|
||||
if action[0] == ACTION_SMS_NOTIFY {
|
||||
if action[0] == actionSMSNotify {
|
||||
message := fmt.Sprintf("Event triggered: %s", e.EventToString())
|
||||
if action[1] == "ALL" {
|
||||
smsglobal.SMSSendToAll(message, config.Cfg)
|
||||
} else {
|
||||
smsglobal.SMSNotify(smsglobal.SMSGetNumberByName(action[1], config.Cfg.SMS), message, config.Cfg)
|
||||
smsglobal.SMSNotify(smsglobal.SMSGetNumberByName(action[1],
|
||||
config.Cfg.SMS), message, config.Cfg,
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -116,13 +127,18 @@ func (e *Event) ExecuteAction() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// EventToString turns the structure event into a string
|
||||
func (e *Event) EventToString() string {
|
||||
condition := common.SplitStrings(e.Condition, ",")
|
||||
return fmt.Sprintf("If the %s%s %s on %s is %s then %s.", e.FirstCurrency, e.SecondCurrency, e.Item, e.Exchange, condition[0]+" "+condition[1], e.Action)
|
||||
return fmt.Sprintf(
|
||||
"If the %s%s %s on %s is %s then %s.", e.FirstCurrency, e.SecondCurrency,
|
||||
e.Item, e.Exchange, condition[0]+" "+condition[1], e.Action,
|
||||
)
|
||||
}
|
||||
|
||||
func (e *Event) CheckCondition() bool { //Add error handling
|
||||
lastPrice := 0.00
|
||||
// CheckCondition will check the event structure to see if there is a condition
|
||||
// met
|
||||
func (e *Event) CheckCondition() bool {
|
||||
condition := common.SplitStrings(e.Condition, ",")
|
||||
targetPrice, _ := strconv.ParseFloat(condition[1], 64)
|
||||
|
||||
@@ -131,38 +147,38 @@ func (e *Event) CheckCondition() bool { //Add error handling
|
||||
return false
|
||||
}
|
||||
|
||||
lastPrice = ticker.Price[pair.CurrencyItem(e.FirstCurrency)][pair.CurrencyItem(e.SecondCurrency)].Last
|
||||
lastPrice := ticker.Price[pair.CurrencyItem(e.FirstCurrency)][pair.CurrencyItem(e.SecondCurrency)].Last
|
||||
|
||||
if lastPrice == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
switch condition[0] {
|
||||
case GREATER_THAN:
|
||||
case greaterThan:
|
||||
{
|
||||
if lastPrice > targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
}
|
||||
case GREATER_THAN_OR_EQUAL:
|
||||
case greaterThanOrEqual:
|
||||
{
|
||||
if lastPrice >= targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
}
|
||||
case LESS_THAN:
|
||||
case lessThan:
|
||||
{
|
||||
if lastPrice < targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
}
|
||||
case LESS_THAN_OR_EQUAL:
|
||||
case lessThanOrEqual:
|
||||
{
|
||||
if lastPrice <= targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
}
|
||||
case IS_EQUAL:
|
||||
case isEqual:
|
||||
{
|
||||
if lastPrice == targetPrice {
|
||||
return e.ExecuteAction()
|
||||
@@ -172,52 +188,56 @@ func (e *Event) CheckCondition() bool { //Add error handling
|
||||
return false
|
||||
}
|
||||
|
||||
// IsValidEvent checks the actions to be taken and returns an error if incorrect
|
||||
func IsValidEvent(Exchange, Item, Condition, Action string) error {
|
||||
Exchange = common.StringToUpper(Exchange)
|
||||
Item = common.StringToUpper(Item)
|
||||
Action = common.StringToUpper(Action)
|
||||
|
||||
configPath := ""
|
||||
if Action == ACTION_TEST {
|
||||
configPath = CONFIG_PATH_TEST
|
||||
if Action == actionTest {
|
||||
configPath = configPathTest
|
||||
}
|
||||
|
||||
if !IsValidExchange(Exchange, configPath) {
|
||||
return ErrExchangeDisabled
|
||||
return errExchangeDisabled
|
||||
}
|
||||
|
||||
if !IsValidItem(Item) {
|
||||
return ErrInvalidItem
|
||||
return errInvalidItem
|
||||
}
|
||||
|
||||
if !common.StringContains(Condition, ",") {
|
||||
return ErrInvalidCondition
|
||||
return errInvalidCondition
|
||||
}
|
||||
|
||||
condition := common.SplitStrings(Condition, ",")
|
||||
|
||||
if !IsValidCondition(condition[0]) || len(condition[1]) == 0 {
|
||||
return ErrInvalidCondition
|
||||
return errInvalidCondition
|
||||
}
|
||||
|
||||
if common.StringContains(Action, ",") {
|
||||
action := common.SplitStrings(Action, ",")
|
||||
|
||||
if action[0] != ACTION_SMS_NOTIFY {
|
||||
return ErrInvalidAction
|
||||
if action[0] != actionSMSNotify {
|
||||
return errInvalidAction
|
||||
}
|
||||
|
||||
if action[1] != "ALL" && smsglobal.SMSGetNumberByName(action[1], config.Cfg.SMS) == smsglobal.ErrSMSContactNotFound {
|
||||
return ErrInvalidAction
|
||||
if action[1] != "ALL" && smsglobal.SMSGetNumberByName(
|
||||
action[1], config.Cfg.SMS) == smsglobal.ErrSMSContactNotFound {
|
||||
return errInvalidAction
|
||||
}
|
||||
} else {
|
||||
if Action != ACTION_CONSOLE_PRINT && Action != ACTION_TEST {
|
||||
return ErrInvalidAction
|
||||
if Action != actionConsolePrint && Action != actionTest {
|
||||
return errInvalidAction
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckEvents is the overarching routine that will iterate through the Events
|
||||
// chain
|
||||
func CheckEvents() {
|
||||
for {
|
||||
total, executed := GetEventCounter()
|
||||
@@ -226,7 +246,10 @@ func CheckEvents() {
|
||||
if !event.Executed {
|
||||
success := event.CheckCondition()
|
||||
if success {
|
||||
log.Printf("Event %d triggered on %s successfully.\n", event.ID, event.Exchange)
|
||||
log.Printf(
|
||||
"Event %d triggered on %s successfully.\n", event.ID,
|
||||
event.Exchange,
|
||||
)
|
||||
event.Executed = true
|
||||
}
|
||||
}
|
||||
@@ -235,19 +258,21 @@ func CheckEvents() {
|
||||
}
|
||||
}
|
||||
|
||||
// IsValidCurrency takes in CRYPTO or FIAT currency strings and returns if valid
|
||||
func IsValidCurrency(currencies ...string) bool {
|
||||
for _, whatIsIt := range currencies {
|
||||
for index, whatIsIt := range currencies {
|
||||
whatIsIt = common.StringToUpper(whatIsIt)
|
||||
if currency.IsDefaultCryptocurrency(whatIsIt) {
|
||||
return true
|
||||
}
|
||||
if currency.IsDefaultCurrency(whatIsIt) {
|
||||
return true
|
||||
if currency.IsDefaultCryptocurrency(whatIsIt) || currency.IsDefaultCurrency(whatIsIt) {
|
||||
if len(currencies)-1 == index {
|
||||
return true
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsValidExchange validates the exchange
|
||||
func IsValidExchange(Exchange, configPath string) bool {
|
||||
Exchange = common.StringToUpper(Exchange)
|
||||
|
||||
@@ -264,27 +289,30 @@ func IsValidExchange(Exchange, configPath string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsValidCondition validates passed in condition
|
||||
func IsValidCondition(Condition string) bool {
|
||||
switch Condition {
|
||||
case GREATER_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, IS_EQUAL:
|
||||
case greaterThan, greaterThanOrEqual, lessThan, lessThanOrEqual, isEqual:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsValidAction validates passed in action
|
||||
func IsValidAction(Action string) bool {
|
||||
Action = common.StringToUpper(Action)
|
||||
switch Action {
|
||||
case ACTION_SMS_NOTIFY, ACTION_CONSOLE_PRINT, ACTION_TEST:
|
||||
case actionSMSNotify, actionConsolePrint, actionTest:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsValidItem validates passed in Item
|
||||
func IsValidItem(Item string) bool {
|
||||
Item = common.StringToUpper(Item)
|
||||
switch Item {
|
||||
case ITEM_PRICE:
|
||||
case itemPrice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
4
main.go
4
main.go
@@ -58,7 +58,7 @@ type ExchangeMain struct {
|
||||
|
||||
type Bot struct {
|
||||
config *config.Config
|
||||
portfolio *portfolio.PortfolioBase
|
||||
portfolio *portfolio.Base
|
||||
exchange ExchangeMain
|
||||
exchanges []exchange.IBotExchange
|
||||
tickers []ticker.Ticker
|
||||
@@ -242,7 +242,7 @@ func SeedExchangeAccountInfo(data []exchange.ExchangeAccountInfo) {
|
||||
}
|
||||
|
||||
if !port.ExchangeAddressExists(exchangeName, currencyName) {
|
||||
port.Addresses = append(port.Addresses, portfolio.PortfolioAddress{Address: exchangeName, CoinType: currencyName, Balance: total, Decscription: portfolio.PORTFOLIO_ADDRESS_EXCHANGE})
|
||||
port.Addresses = append(port.Addresses, portfolio.Address{Address: exchangeName, CoinType: currencyName, Balance: total, Decscription: portfolio.PortfolioAddressExchange})
|
||||
} else {
|
||||
port.UpdateExchangeAddressBalance(exchangeName, currencyName, total)
|
||||
}
|
||||
|
||||
@@ -10,35 +10,43 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
BLOCKR_API_URL = "blockr.io/api"
|
||||
BLOCKR_API_VERSION = "1"
|
||||
BLOCKR_ADDRESS_BALANCE = "address/balance"
|
||||
blockrAPIURL = "blockr.io/api"
|
||||
blockrAPIVersion = "1"
|
||||
blockrAddressBalance = "address/balance"
|
||||
|
||||
ETHERCHAIN_API_URL = "https://etherchain.org/api"
|
||||
ETHERCHAIN_ACCOUNT_MULTIPLE = "account/multiple"
|
||||
PORTFOLIO_ADDRESS_EXCHANGE = "Exchange"
|
||||
PORTFOLIO_ADDRESS_PERSONAL = "Personal"
|
||||
etherchainAPIURL = "https://etherchain.org/api"
|
||||
etherchainAccountMultiple = "account/multiple"
|
||||
// PortfolioAddressExchange holds the current portfolio address
|
||||
PortfolioAddressExchange = "Exchange"
|
||||
portfolioAddressPersonal = "Personal"
|
||||
)
|
||||
|
||||
var Portfolio PortfolioBase
|
||||
// Portfolio is variable store holding an array of portfolioAddress
|
||||
var Portfolio Base
|
||||
|
||||
type PortfolioAddress struct {
|
||||
// Base holds the portfolio base addresses
|
||||
type Base struct {
|
||||
Addresses []Address
|
||||
}
|
||||
|
||||
// Address sub type holding address information for portfolio
|
||||
type Address struct {
|
||||
Address string
|
||||
CoinType string
|
||||
Balance float64
|
||||
Decscription string
|
||||
}
|
||||
|
||||
type PortfolioBase struct {
|
||||
Addresses []PortfolioAddress
|
||||
}
|
||||
|
||||
// BlockrAddress holds JSON incoming and outgoing data for BLOCKR with address
|
||||
// information
|
||||
type BlockrAddress struct {
|
||||
Address string `json:"address"`
|
||||
Balance float64 `json:"balance"`
|
||||
BalanceMultisig float64 `json:"balance_multisig"`
|
||||
}
|
||||
|
||||
// BlockrAddressBalanceSingle holds JSON incoming and outgoing data for BLOCKR
|
||||
// with address balance information
|
||||
type BlockrAddressBalanceSingle struct {
|
||||
Status string `json:"status"`
|
||||
Data BlockrAddress `json:"data"`
|
||||
@@ -46,6 +54,8 @@ type BlockrAddressBalanceSingle struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// BlockrAddressBalanceMulti holds JSON incoming and outgoing data for BLOCKR
|
||||
// with address balance information for multiple wallets
|
||||
type BlockrAddressBalanceMulti struct {
|
||||
Status string `json:"status"`
|
||||
Data []BlockrAddress `json:"data"`
|
||||
@@ -53,6 +63,8 @@ type BlockrAddressBalanceMulti struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// EtherchainBalanceResponse holds JSON incoming and outgoing data for
|
||||
// Etherchain
|
||||
type EtherchainBalanceResponse struct {
|
||||
Status int `json:"status"`
|
||||
Data []struct {
|
||||
@@ -66,7 +78,8 @@ type EtherchainBalanceResponse struct {
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
// ExchangeAccountInfo : Generic type to hold each exchange's holdings in all enabled currencies
|
||||
// ExchangeAccountInfo : Generic type to hold each exchange's holdings in all
|
||||
// enabled currencies
|
||||
type ExchangeAccountInfo struct {
|
||||
ExchangeName string
|
||||
Currencies []ExchangeAccountCurrencyInfo
|
||||
@@ -79,6 +92,8 @@ type ExchangeAccountCurrencyInfo struct {
|
||||
Hold float64
|
||||
}
|
||||
|
||||
// GetEthereumBalance single or multiple address information as
|
||||
// EtherchainBalanceResponse
|
||||
func GetEthereumBalance(address []string) (EtherchainBalanceResponse, error) {
|
||||
for _, add := range address {
|
||||
valid, _ := common.IsValidCryptoAddress(add, "eth")
|
||||
@@ -88,7 +103,9 @@ func GetEthereumBalance(address []string) (EtherchainBalanceResponse, error) {
|
||||
}
|
||||
|
||||
addresses := common.JoinStrings(address, ",")
|
||||
url := fmt.Sprintf("%s/%s/%s", ETHERCHAIN_API_URL, ETHERCHAIN_ACCOUNT_MULTIPLE, addresses)
|
||||
url := fmt.Sprintf(
|
||||
"%s/%s/%s", etherchainAPIURL, etherchainAccountMultiple, addresses,
|
||||
)
|
||||
result := EtherchainBalanceResponse{}
|
||||
err := common.SendHTTPGetRequest(url, true, &result)
|
||||
if err != nil {
|
||||
@@ -100,13 +117,20 @@ func GetEthereumBalance(address []string) (EtherchainBalanceResponse, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetBlockrBalanceSingle queries Blockr for an address balance for either a
|
||||
// LTC or a BTC single address
|
||||
func GetBlockrBalanceSingle(address string, coinType string) (BlockrAddressBalanceSingle, error) {
|
||||
valid, _ := common.IsValidCryptoAddress(address, coinType)
|
||||
if !valid {
|
||||
return BlockrAddressBalanceSingle{}, errors.New(fmt.Sprintf("Not a %s address", common.StringToUpper(coinType)))
|
||||
return BlockrAddressBalanceSingle{}, fmt.Errorf(
|
||||
"Not a %s address", common.StringToUpper(coinType),
|
||||
)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("https://%s.%s/v%s/%s/%s", common.StringToLower(coinType), BLOCKR_API_URL, BLOCKR_API_VERSION, BLOCKR_ADDRESS_BALANCE, address)
|
||||
url := fmt.Sprintf(
|
||||
"https://%s.%s/v%s/%s/%s", common.StringToLower(coinType), blockrAPIURL,
|
||||
blockrAPIVersion, blockrAddressBalance, address,
|
||||
)
|
||||
result := BlockrAddressBalanceSingle{}
|
||||
err := common.SendHTTPGetRequest(url, true, &result)
|
||||
if err != nil {
|
||||
@@ -118,15 +142,22 @@ func GetBlockrBalanceSingle(address string, coinType string) (BlockrAddressBalan
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetBlockrAddressMulti queries Blockr for an address balance for either a LTC
|
||||
// or a BTC multiple addresses
|
||||
func GetBlockrAddressMulti(addresses []string, coinType string) (BlockrAddressBalanceMulti, error) {
|
||||
for _, add := range addresses {
|
||||
valid, _ := common.IsValidCryptoAddress(add, coinType)
|
||||
if !valid {
|
||||
return BlockrAddressBalanceMulti{}, errors.New(fmt.Sprintf("Not a %s address", common.StringToUpper(coinType)))
|
||||
return BlockrAddressBalanceMulti{}, fmt.Errorf(
|
||||
"Not a %s address", common.StringToUpper(coinType),
|
||||
)
|
||||
}
|
||||
}
|
||||
addressesStr := common.JoinStrings(addresses, ",")
|
||||
url := fmt.Sprintf("https://%s.%s/v%s/%s/%s", common.StringToLower(coinType), BLOCKR_API_URL, BLOCKR_API_VERSION, BLOCKR_ADDRESS_BALANCE, addressesStr)
|
||||
url := fmt.Sprintf(
|
||||
"https://%s.%s/v%s/%s/%s", common.StringToLower(coinType), blockrAPIURL,
|
||||
blockrAPIVersion, blockrAddressBalance, addressesStr,
|
||||
)
|
||||
result := BlockrAddressBalanceMulti{}
|
||||
err := common.SendHTTPGetRequest(url, true, &result)
|
||||
if err != nil {
|
||||
@@ -138,7 +169,9 @@ func GetBlockrAddressMulti(addresses []string, coinType string) (BlockrAddressBa
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) GetAddressBalance(address string) (float64, bool) {
|
||||
// GetAddressBalance acceses the portfolio base and returns the balance by passed
|
||||
// in address
|
||||
func (p *Base) GetAddressBalance(address string) (float64, bool) {
|
||||
for _, x := range p.Addresses {
|
||||
if x.Address == address {
|
||||
return x.Balance, true
|
||||
@@ -147,7 +180,8 @@ func (p *PortfolioBase) GetAddressBalance(address string) (float64, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) ExchangeExists(exchangeName string) bool {
|
||||
// ExchangeExists checks to see if an exchange exists in the portfolio base
|
||||
func (p *Base) ExchangeExists(exchangeName string) bool {
|
||||
for _, x := range p.Addresses {
|
||||
if x.Address == exchangeName {
|
||||
return true
|
||||
@@ -156,7 +190,9 @@ func (p *PortfolioBase) ExchangeExists(exchangeName string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) AddressExists(address string) bool {
|
||||
// AddressExists checks to see if there is an address associated with the
|
||||
// portfolio base
|
||||
func (p *Base) AddressExists(address string) bool {
|
||||
for _, x := range p.Addresses {
|
||||
if x.Address == address {
|
||||
return true
|
||||
@@ -165,7 +201,9 @@ func (p *PortfolioBase) AddressExists(address string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) ExchangeAddressExists(exchangeName, coinType string) bool {
|
||||
// ExchangeAddressExists checks to see if there is an exchange address
|
||||
// associated with the portfolio base
|
||||
func (p *Base) ExchangeAddressExists(exchangeName, coinType string) bool {
|
||||
for _, x := range p.Addresses {
|
||||
if x.Address == exchangeName && x.CoinType == coinType {
|
||||
return true
|
||||
@@ -174,32 +212,40 @@ func (p *PortfolioBase) ExchangeAddressExists(exchangeName, coinType string) boo
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) UpdateAddressBalance(address string, amount float64) {
|
||||
for x, _ := range p.Addresses {
|
||||
// UpdateAddressBalance updates the portfolio base balance
|
||||
func (p *Base) UpdateAddressBalance(address string, amount float64) {
|
||||
for x := range p.Addresses {
|
||||
if p.Addresses[x].Address == address {
|
||||
p.Addresses[x].Balance = amount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) UpdateExchangeAddressBalance(exchangeName, coinType string, balance float64) {
|
||||
for x, _ := range p.Addresses {
|
||||
// UpdateExchangeAddressBalance updates the portfolio balance when checked
|
||||
// against correct exchangeName and coinType.
|
||||
func (p *Base) UpdateExchangeAddressBalance(exchangeName, coinType string, balance float64) {
|
||||
for x := range p.Addresses {
|
||||
if p.Addresses[x].Address == exchangeName && p.Addresses[x].CoinType == coinType {
|
||||
p.Addresses[x].Balance = balance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) AddAddress(address, coinType, description string, balance float64) {
|
||||
// AddAddress adds an address to the portfolio base
|
||||
func (p *Base) AddAddress(address, coinType, description string, balance float64) {
|
||||
if !p.AddressExists(address) {
|
||||
p.Addresses = append(p.Addresses, PortfolioAddress{Address: address, CoinType: coinType, Balance: balance, Decscription: description})
|
||||
p.Addresses = append(
|
||||
p.Addresses, Address{Address: address, CoinType: coinType,
|
||||
Balance: balance, Decscription: description},
|
||||
)
|
||||
} else {
|
||||
p.UpdateAddressBalance(address, balance)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) UpdatePortfolio(addresses []string, coinType string) bool {
|
||||
if common.StringContains(common.JoinStrings(addresses, ","), PORTFOLIO_ADDRESS_EXCHANGE) || common.StringContains(common.JoinStrings(addresses, ","), PORTFOLIO_ADDRESS_PERSONAL) {
|
||||
// UpdatePortfolio adds to the portfolio addresses by coin type
|
||||
func (p *Base) UpdatePortfolio(addresses []string, coinType string) bool {
|
||||
if common.StringContains(common.JoinStrings(addresses, ","), PortfolioAddressExchange) || common.StringContains(common.JoinStrings(addresses, ","), portfolioAddressPersonal) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -210,7 +256,7 @@ func (p *PortfolioBase) UpdatePortfolio(addresses []string, coinType string) boo
|
||||
}
|
||||
|
||||
for _, x := range result.Data {
|
||||
p.AddAddress(x.Address, coinType, PORTFOLIO_ADDRESS_PERSONAL, x.Balance)
|
||||
p.AddAddress(x.Address, coinType, portfolioAddressPersonal, x.Balance)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -220,22 +266,25 @@ func (p *PortfolioBase) UpdatePortfolio(addresses []string, coinType string) boo
|
||||
return false
|
||||
}
|
||||
for _, x := range result.Data {
|
||||
p.AddAddress(x.Address, coinType, PORTFOLIO_ADDRESS_PERSONAL, x.Balance)
|
||||
p.AddAddress(x.Address, coinType, portfolioAddressPersonal, x.Balance)
|
||||
}
|
||||
} else {
|
||||
result, err := GetBlockrBalanceSingle(addresses[0], coinType)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
p.AddAddress(addresses[0], coinType, PORTFOLIO_ADDRESS_PERSONAL, result.Data.Balance)
|
||||
p.AddAddress(
|
||||
addresses[0], coinType, portfolioAddressPersonal, result.Data.Balance,
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) GetExchangePortfolio() map[string]float64 {
|
||||
// GetExchangePortfolio returns current portfolio base information
|
||||
func (p *Base) GetExchangePortfolio() map[string]float64 {
|
||||
result := make(map[string]float64)
|
||||
for _, x := range p.Addresses {
|
||||
if x.Decscription != PORTFOLIO_ADDRESS_EXCHANGE {
|
||||
if x.Decscription != PortfolioAddressExchange {
|
||||
continue
|
||||
}
|
||||
balance, ok := result[x.CoinType]
|
||||
@@ -248,10 +297,11 @@ func (p *PortfolioBase) GetExchangePortfolio() map[string]float64 {
|
||||
return result
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) GetPersonalPortfolio() map[string]float64 {
|
||||
// GetPersonalPortfolio returns current portfolio base information
|
||||
func (p *Base) GetPersonalPortfolio() map[string]float64 {
|
||||
result := make(map[string]float64)
|
||||
for _, x := range p.Addresses {
|
||||
if x.Decscription == PORTFOLIO_ADDRESS_EXCHANGE {
|
||||
if x.Decscription == PortfolioAddressExchange {
|
||||
continue
|
||||
}
|
||||
balance, ok := result[x.CoinType]
|
||||
@@ -264,7 +314,8 @@ func (p *PortfolioBase) GetPersonalPortfolio() map[string]float64 {
|
||||
return result
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) GetPortfolioSummary(coinFilter string) map[string]float64 {
|
||||
// GetPortfolioSummary rpoves a summary for your portfolio base
|
||||
func (p *Base) GetPortfolioSummary(coinFilter string) map[string]float64 {
|
||||
result := make(map[string]float64)
|
||||
for _, x := range p.Addresses {
|
||||
if coinFilter != "" && coinFilter != x.CoinType {
|
||||
@@ -280,10 +331,11 @@ func (p *PortfolioBase) GetPortfolioSummary(coinFilter string) map[string]float6
|
||||
return result
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) GetPortfolioGroupedCoin() map[string][]string {
|
||||
// GetPortfolioGroupedCoin returns portfolio base information grouped by coin
|
||||
func (p *Base) GetPortfolioGroupedCoin() map[string][]string {
|
||||
result := make(map[string][]string)
|
||||
for _, x := range p.Addresses {
|
||||
if common.StringContains(x.Decscription, PORTFOLIO_ADDRESS_EXCHANGE) || common.StringContains(x.Decscription, PORTFOLIO_ADDRESS_PERSONAL) {
|
||||
if common.StringContains(x.Decscription, PortfolioAddressExchange) || common.StringContains(x.Decscription, portfolioAddressPersonal) {
|
||||
continue
|
||||
}
|
||||
result[x.CoinType] = append(result[x.CoinType], x.Address)
|
||||
@@ -291,25 +343,34 @@ func (p *PortfolioBase) GetPortfolioGroupedCoin() map[string][]string {
|
||||
return result
|
||||
}
|
||||
|
||||
func (p *PortfolioBase) SeedPortfolio(port PortfolioBase) {
|
||||
// SeedPortfolio appends a portfolio base object with another base portfolio
|
||||
// addresses
|
||||
func (p *Base) SeedPortfolio(port Base) {
|
||||
p.Addresses = port.Addresses
|
||||
}
|
||||
|
||||
// StartPortfolioWatcher observes the portfolio object
|
||||
func StartPortfolioWatcher() {
|
||||
addrCount := len(Portfolio.Addresses)
|
||||
log.Printf("PortfolioWatcher started: Have %d entries in portfolio.\n", addrCount)
|
||||
log.Printf(
|
||||
"PortfolioWatcher started: Have %d entries in portfolio.\n", addrCount,
|
||||
)
|
||||
for {
|
||||
data := Portfolio.GetPortfolioGroupedCoin()
|
||||
for key, value := range data {
|
||||
success := Portfolio.UpdatePortfolio(value, key)
|
||||
if success {
|
||||
log.Printf("PortfolioWatcher: Successfully updated address balance for %s address(es) %s\n", key, value)
|
||||
log.Printf(
|
||||
"PortfolioWatcher: Successfully updated address balance for %s address(es) %s\n",
|
||||
key, value,
|
||||
)
|
||||
}
|
||||
}
|
||||
time.Sleep(time.Minute * 10)
|
||||
}
|
||||
}
|
||||
|
||||
func GetPortfolio() *PortfolioBase {
|
||||
// GetPortfolio returns a pointer to the portfolio base
|
||||
func GetPortfolio() *Base {
|
||||
return &Portfolio
|
||||
}
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
package portfolio
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetEthereumBalance(t *testing.T) {
|
||||
addresses := []string{"0xb794f5ea0ba39494ce839613fffba74279579268",
|
||||
"0xe853c56864a2ebe4576a807d26fdc4a0ada51919"}
|
||||
nonsenseAddress := []string{"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, 0xe853c56864a2ebe4576a807d26fdc4a0ada51919"}
|
||||
nonsenseAddress := []string{
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
||||
"0xe853c56864a2ebe4576a807d26fdc4a0ada51919",
|
||||
}
|
||||
|
||||
response, err := GetEthereumBalance(addresses)
|
||||
if err != nil {
|
||||
t.Errorf("Test Failed - Portfolio GetEthereumBalance() Error: %s", err)
|
||||
}
|
||||
if len(response.Data) != 2 {
|
||||
t.Error("Test Failed - Portfolio GetEthereumBalance() Error: Incorrect address")
|
||||
t.Error(
|
||||
"Test Failed - Portfolio GetEthereumBalance() Error: Incorrect address",
|
||||
)
|
||||
}
|
||||
|
||||
response, err = GetEthereumBalance(nonsenseAddress)
|
||||
@@ -54,13 +60,19 @@ func TestGetBlockrBalanceSingle(t *testing.T) {
|
||||
t.Errorf("Test Failed - Portfolio GetBlockrBalanceSingle() Error: %s", err)
|
||||
}
|
||||
if response.Status == "success" {
|
||||
t.Error("Test Failed - Portfolio GetBlockrBalanceSingle() Error: Incorrect status")
|
||||
t.Error(
|
||||
"Test Failed - Portfolio GetBlockrBalanceSingle() Error: Incorrect status",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBlockrAddressMulti(t *testing.T) {
|
||||
litecoinAddresses := []string{"LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL", "LVa8wZ983PvWtdwXZ8viK6SocMENLCXkEy"}
|
||||
bitcoinAddresses := []string{"3D2oetdNuZUqQHPJmcMDDHYoqkyNVsFk9r", "3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v"}
|
||||
litecoinAddresses := []string{
|
||||
"LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL", "LVa8wZ983PvWtdwXZ8viK6SocMENLCXkEy",
|
||||
}
|
||||
bitcoinAddresses := []string{
|
||||
"3D2oetdNuZUqQHPJmcMDDHYoqkyNVsFk9r", "3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v",
|
||||
}
|
||||
nonsenseAddresses := []string{"DingDong", "ningNang"}
|
||||
ltc := "LtC"
|
||||
btc := "bTc"
|
||||
@@ -85,7 +97,7 @@ func TestGetAddressBalance(t *testing.T) {
|
||||
description := "Description of Wallet"
|
||||
balance := float64(1000)
|
||||
|
||||
portfolio := PortfolioBase{}
|
||||
portfolio := Base{}
|
||||
portfolio.AddAddress(ltcAddress, ltc, description, balance)
|
||||
|
||||
addBalance, _ := portfolio.GetAddressBalance("LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL")
|
||||
@@ -102,59 +114,182 @@ func TestGetAddressBalance(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// func TestExchangeExists(t *testing.T) {
|
||||
// portfolio := PortfolioBase{}
|
||||
// portfolio.SeedPortfolio(port)
|
||||
// }
|
||||
func TestExchangeExists(t *testing.T) {
|
||||
newBase := Base{}
|
||||
newBase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02)
|
||||
if !newBase.ExchangeExists("someaddress") {
|
||||
t.Error("Test Failed - portfolio_test.go - AddressExists error")
|
||||
}
|
||||
if newBase.ExchangeExists("bla") {
|
||||
t.Error("Test Failed - portfolio_test.go - AddressExists error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddressExists(t *testing.T) {
|
||||
|
||||
newbase := Base{}
|
||||
newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02)
|
||||
if !newbase.AddressExists("someaddress") {
|
||||
t.Error("Test Failed - portfolio_test.go - AddressExists error")
|
||||
}
|
||||
if newbase.AddressExists("bla") {
|
||||
t.Error("Test Failed - portfolio_test.go - AddressExists error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExchangeAddressExists(t *testing.T) {
|
||||
newbase := Base{}
|
||||
newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02)
|
||||
if !newbase.ExchangeAddressExists("someaddress", "LTC") {
|
||||
t.Error("Test Failed - portfolio_test.go - ExchangeAddressExists error")
|
||||
}
|
||||
if newbase.ExchangeAddressExists("TEST", "LTC") {
|
||||
t.Error("Test Failed - portfolio_test.go - ExchangeAddressExists error")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestUpdateAddressBalance(t *testing.T) {
|
||||
newbase := Base{}
|
||||
newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02)
|
||||
newbase.UpdateAddressBalance("someaddress", 0.03)
|
||||
|
||||
value := newbase.GetPortfolioSummary("LTC")
|
||||
if value["LTC"] != 0.03 {
|
||||
t.Error("Test Failed - portfolio_test.go - UpdateUpdateAddressBalance error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateExchangeAddressBalance(t *testing.T) {
|
||||
newbase := Base{}
|
||||
newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02)
|
||||
portfolio := GetPortfolio()
|
||||
portfolio.SeedPortfolio(newbase)
|
||||
portfolio.UpdateExchangeAddressBalance("someaddress", "LTC", 0.04)
|
||||
|
||||
value := portfolio.GetPortfolioSummary("LTC")
|
||||
if value["LTC"] != 0.04 {
|
||||
t.Error("Test Failed - portfolio_test.go - UpdateExchangeAddressBalance error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddAddress(t *testing.T) {
|
||||
|
||||
newbase := Base{}
|
||||
newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02)
|
||||
portfolio := GetPortfolio()
|
||||
portfolio.SeedPortfolio(newbase)
|
||||
if !portfolio.AddressExists("someaddress") {
|
||||
t.Error("Test Failed - portfolio_test.go - AddAddress error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdatePortfolio(t *testing.T) {
|
||||
newbase := Base{}
|
||||
newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02)
|
||||
portfolio := GetPortfolio()
|
||||
portfolio.SeedPortfolio(newbase)
|
||||
|
||||
value := portfolio.UpdatePortfolio(
|
||||
[]string{"LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL"}, "LTC",
|
||||
)
|
||||
if !value {
|
||||
t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error")
|
||||
}
|
||||
value = portfolio.UpdatePortfolio([]string{"Testy"}, "LTC")
|
||||
if value {
|
||||
t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error")
|
||||
}
|
||||
value = portfolio.UpdatePortfolio(
|
||||
[]string{"LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL", "LVa8wZ983PvWtdwXZ8viK6SocMENLCXkEy"},
|
||||
"LTC",
|
||||
)
|
||||
if !value {
|
||||
t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error")
|
||||
}
|
||||
value = portfolio.UpdatePortfolio(
|
||||
[]string{"LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL", "Testy"}, "LTC",
|
||||
)
|
||||
if value {
|
||||
t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error")
|
||||
}
|
||||
value = portfolio.UpdatePortfolio(
|
||||
[]string{"0xb794f5ea0ba39494ce839613fffba74279579268",
|
||||
"0xe853c56864a2ebe4576a807d26fdc4a0ada51919"}, "ETH",
|
||||
)
|
||||
if !value {
|
||||
t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error")
|
||||
}
|
||||
value = portfolio.UpdatePortfolio(
|
||||
[]string{"0xb794f5ea0ba39494ce839613fffba74279579268", "TESTY"}, "ETH",
|
||||
)
|
||||
if value {
|
||||
t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetExchangePortfolio(t *testing.T) {
|
||||
|
||||
newbase := Base{}
|
||||
newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02)
|
||||
portfolio := GetPortfolio()
|
||||
portfolio.SeedPortfolio(newbase)
|
||||
value := portfolio.GetExchangePortfolio()
|
||||
_, ok := value["ANX"]
|
||||
if ok {
|
||||
t.Error("Test Failed - portfolio_test.go - GetExchangePortfolio error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPersonalPortfolio(t *testing.T) {
|
||||
|
||||
newbase := Base{}
|
||||
newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02)
|
||||
portfolio := GetPortfolio()
|
||||
portfolio.SeedPortfolio(newbase)
|
||||
value := portfolio.GetPersonalPortfolio()
|
||||
_, ok := value["LTC"]
|
||||
if !ok {
|
||||
t.Error("Test Failed - portfolio_test.go - GetPersonalPortfolio error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPortfolioSummary(t *testing.T) {
|
||||
|
||||
newbase := Base{}
|
||||
newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02)
|
||||
portfolio := GetPortfolio()
|
||||
portfolio.SeedPortfolio(newbase)
|
||||
value := portfolio.GetPortfolioSummary("LTC")
|
||||
if value["LTC"] != 0.02 {
|
||||
t.Error("Test Failed - portfolio_test.go - GetPortfolioGroupedCoin error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPortfolioGroupedCoin(t *testing.T) {
|
||||
|
||||
newbase := Base{}
|
||||
newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02)
|
||||
portfolio := GetPortfolio()
|
||||
portfolio.SeedPortfolio(newbase)
|
||||
value := portfolio.GetPortfolioGroupedCoin()
|
||||
if value["LTC"][0] != "someaddress" {
|
||||
t.Error("Test Failed - portfolio_test.go - GetPortfolioGroupedCoin error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSeedPortfolio(t *testing.T) {
|
||||
newbase := Base{}
|
||||
newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02)
|
||||
portfolio := GetPortfolio()
|
||||
portfolio.SeedPortfolio(newbase)
|
||||
|
||||
if !portfolio.AddressExists("someaddress") {
|
||||
t.Error("Test Failed - portfolio_test.go - SeedPortfolio error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStartPortfolioWatcher(t *testing.T) {
|
||||
|
||||
//Not until testTimeoutFeature and errors
|
||||
}
|
||||
|
||||
func TestGetPortfolio(t *testing.T) {
|
||||
|
||||
ptrBASE := GetPortfolio()
|
||||
if reflect.TypeOf(ptrBASE).String() != "*portfolio.Base" {
|
||||
t.Error("Test Failed - portfolio_test.go - GetoPortfolio error")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func main() {
|
||||
log.Fatal("File isn't in JSON format")
|
||||
}
|
||||
|
||||
port := portfolio.PortfolioBase{}
|
||||
port := portfolio.Base{}
|
||||
port.SeedPortfolio(cfg.Portfolio)
|
||||
result := port.GetPortfolioSummary("")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user