Skip to content

Commit

Permalink
Changing CLI engine to cobra
Browse files Browse the repository at this point in the history
Reasons for this change:
1. allow the bot to have more functions in the future
  • Loading branch information
saniales committed Jun 2, 2017
1 parent be4704c commit 1370467
Show file tree
Hide file tree
Showing 15 changed files with 344 additions and 70 deletions.
12 changes: 6 additions & 6 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -652,12 +652,12 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
under certain conditions; type 'show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
The hypothetical commands 'show w' and 'show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

Expand Down
7 changes: 2 additions & 5 deletions botHelpers/bot_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ func InitArgs() (CommandLineOptions, error) {

//InitExchange initialize a new ExchangeWrapper binded to the specified exchange provided.
func InitExchange(exchangeConfig exchangeWrappers.ExchangeConfig) exchangeWrappers.ExchangeWrapper {
switch exchangeName {
switch exchangeConfig.ExchangeName {
case "bittrex":
return exchangeWrappers.NewBittrexWrapper(publicKey, secretKey)
return exchangeWrappers.NewBittrexWrapper(exchangeConfig.PublicKey, exchangeConfig.SecretKey)
case "poloniex":
return nil
default:
Expand All @@ -37,6 +37,3 @@ func InitExchange(exchangeConfig exchangeWrappers.ExchangeConfig) exchangeWrappe
func InitMarkets(exchange exchangeWrappers.ExchangeWrapper) ([]environment.Market, error) {
return exchange.GetMarkets()
}

//InitFromConfigFile
func InitExchangesFromConfig()
156 changes: 156 additions & 0 deletions cmd/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// Copyright © 2017 Alessandro Sanino <saninoale@gmail.com>
// {{.copyright}}
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package cmd

import (
"fmt"
"io/ioutil"

yaml "gopkg.in/yaml.v2"

"github.com/AlessandroSanino1994/gobot/environment"
"github.com/spf13/cobra"
)

var initFlags struct {
ConfigFile string
Exchange string
Strategies []struct {
Market string
Strategy string
}
BTCAddress string
}

// initCmd represents the init command
var initCmd = &cobra.Command{
Use: "init",
Short: "Initializes the bot to trade",
Long: `Initializes the trading bot: it will ask several questions to properly create a conf file.
It must be run prior any other command if config file is not present.`,
Run: executeInitCommand,
}

func init() {
RootCmd.AddCommand(initCmd)
initCmd.Flags().StringVar(&initFlags.ConfigFile, "import", "", "imports configuration from a file.")
}

func executeInitCommand(cmd *cobra.Command, args []string) {
initConfig()
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
if initFlags.ConfigFile != "" {
//try first to unmarshal the file to check if it is correct format.
content, err := ioutil.ReadFile(initFlags.ConfigFile)
if err != nil {
fmt.Print("Error while opening the config file provided")
if GlobalFlags.Verbose {
fmt.Printf(": %s", err.Error())
}
fmt.Println()
return
}
var checker environment.BotConfig
err = yaml.Unmarshal(content, &checker)
if err != nil {
fmt.Print("Cannot load provided configuration file")
if GlobalFlags.Verbose {
fmt.Printf(": %s", err.Error())
}
fmt.Println()
return
}
err = ioutil.WriteFile("./.gobot", content, 0666)
if err != nil {
fmt.Print("Cannot write new configuration file")
if GlobalFlags.Verbose {
fmt.Printf(": %s", err.Error())
}
fmt.Println()
return
}
} else {
generateInitFile()
}
}

func generateInitFile() {
configs := environment.BotConfig{}
fmt.Println("Which exchange are you going to use?")
fmt.Scanln(&configs.Exchange.ExchangeName)
fmt.Println("Please provide Public Key for that exchange.")
fmt.Scanln(&configs.Exchange.PublicKey)
fmt.Println("Please provide Secret Key for that exchange.")
fmt.Scanln(&configs.Exchange.SecretKey)

for {
var YesNo string
for YesNo != "Y" && YesNo != "n" {
fmt.Println("Do you want to add a strategy binded to a market? (Y/n)")
fmt.Scanln(&YesNo)
}
if YesNo == "n" {
break
}
var tempStrategyAppliance environment.StrategyAppliance
fmt.Println("Please Enter Market Name using short notation " +
"(e.g. BTC-ETH for a Bitcoin-Ethereum market).")
fmt.Scanln(&tempStrategyAppliance.Market)
fmt.Println("Please Enter The Name of the strategy you want to use\n" +
"in this market (must be in the system)")
fmt.Scanln(&tempStrategyAppliance.Strategy)
configs.Strategies = append(configs.Strategies, tempStrategyAppliance)
}

//preview the contents of the file to be written, then creates a new file in .
contentToBeWritten, err := yaml.Marshal(configs)
if err != nil {
fmt.Print("Error while creating the content for the new config file")
if GlobalFlags.Verbose {
fmt.Printf(": %s", err.Error())
}
fmt.Println()
return
}
fmt.Println("The following content:")
fmt.Println(string(contentToBeWritten))
fmt.Println("is going to be written on ./.gobot, is it ok? (Y/n)")

var YesNo string
for YesNo != "Y" && YesNo != "n" {
fmt.Scanln(&YesNo)
}
if YesNo == "Y" {
err := ioutil.WriteFile("./.gobot", contentToBeWritten, 0666)
if err != nil {
fmt.Print("Error while writing content to new config file")
if GlobalFlags.Verbose {
fmt.Printf(": %s", err.Error())
}
fmt.Println()
} else {
fmt.Println("Config file created on ./.gobot\nNow you can use gobot with this configuration.\nHappy Trading, folk :)")
}
return
}
fmt.Println("You chose not to write the content to configuration file.\n" +
"You can relaunch this command again to create another configuration.\n" +
"This bot won't work until it has a valid configuration file.")
}
56 changes: 56 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright © 2017 Alessandro Sanino <saninoale@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package cmd

import (
"os"

"github.com/spf13/cobra"
)

var cfgFile string

//GlobalFlags provides flag definitions valid for the whole system.
var GlobalFlags struct {
Verbose bool //Tells the program to print everything to screen.
}

//rootFlags provides flag definitions valid for root command.
var rootFlags struct {
Version bool
}

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: "gobot",
Short: "USAGE gobot [OPTIONS].",
Long: `USAGE gobot [OPTIONS] : see --help for details`,
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := RootCmd.Execute(); err != nil {
//fmt.Println(err)
os.Exit(1)
}
}

func init() {
RootCmd.PersistentFlags().BoolVar(&GlobalFlags.Verbose, "verbose", false, "show verbose information (default = false) when trading.")

RootCmd.Flags().BoolVar(&rootFlags.Version, "version", false, "show version information (default = false).")
}
52 changes: 52 additions & 0 deletions cmd/strategy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright © 2017 Alessandro Sanino <saninoale@gmail.com>
// {{.copyright}}
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package cmd

import (
"fmt"

"github.com/spf13/cobra"
)

// strategyCmd represents the strategy command
var strategyCmd = &cobra.Command{
Use: "strategy",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("strategy called")
},
}

func init() {
RootCmd.AddCommand(strategyCmd)

// Here you will define your flags and configuration settings.

// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// strategyCmd.PersistentFlags().String("foo", "", "A help for foo")

// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// strategyCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
5 changes: 2 additions & 3 deletions environment/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package environment
//CandleStick represents a single candle in the graph.
import "time"

//CandleStick represents a single candlestick in a chart.
type CandleStick struct {
High float64 //Represents the highest value obtained during candle period.
Open float64 //Represents the first value of the candle period.
Expand All @@ -12,9 +13,7 @@ type CandleStick struct {

//CandleStickChart represents a chart of a market expresed using Candle Sticks.
type CandleStickChart struct {
CandlePeriod time.Duration //Represents the candle period (expressed in time.Duration)
MarketName string //Represents the name of the market (e.g. BTC-LTC)
CandlePeriod time.Duration //Represents the candle period (expressed in time.Duration).
CandleSticks []CandleStick //Represents the last Candle Sticks used for evaluation of current state.
Volume float64 //Represents the volume of the considered interval of the chart.
OrderBook []Order //Represents the Book of current trades.
}
24 changes: 24 additions & 0 deletions environment/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package environment

//ExchangeConfig Represents a configuration for an API Connection to an exchange.
//
//Can be used to generate an ExchangeWrapper.
type ExchangeConfig struct {
ExchangeName string `yaml:"exchange"` //Represents the exchange name.
PublicKey string `yaml:"public_key"` //Represents the public key used to connect to Exchange API.
SecretKey string `yaml:"secret_key"` //Represents the secret key used to connect to Exchange API.
}

// StrategyAppliance contains where a strategy will be applied in the specified exchange.
type StrategyAppliance struct {
Market string `yaml:"market"` //Represents the market where the strategy is applied.
Strategy string `yaml:"strategy"` //Represents the applied strategy name: must be one in the system.
}

// BotConfig contains all config data of the bot, which can be also loaded from config file.
type BotConfig struct {
Exchange ExchangeConfig `yaml:"exchange_config"` //Represents the current exchange configuration.
Strategies []StrategyAppliance `yaml:"strategies"` //Represents the current strategies adopted by the bot.
}

//type Configs []ExchangeConfig
14 changes: 8 additions & 6 deletions environment/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ package environment
type OrderType int16

const (
Ask OrderType = iota //Represents an ASK Order.
Bid OrderType = iota //Represents a BID Order.
//Ask Represents an ASK Order.
Ask OrderType = iota
//Bid Represents a BID Order.
Bid OrderType = iota
)

//Order represents a single order in the Order Book for a market.
type Order struct {
Type OrderType
Value float64
Quantity float64
OrderNumber string
Type OrderType //Type of the order. Can be Ask or Bid.
Value float64 //Value of the trade : e.g. in a BTC ETH is the value of a single ETH in BTC.
Quantity float64 //Quantity of Coins of this order.
OrderNumber string //[optional]Order number as seen in echange archives.
}

//Total returns order total in base currency.
Expand Down
Loading

0 comments on commit 1370467

Please sign in to comment.