-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e9f79ce
Showing
14 changed files
with
1,028 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package api_service | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"net/http" | ||
) | ||
|
||
func PercentageData(id string) ([]byte, error) { | ||
//get historical data of coin | ||
res, err := http.Get("https://api.binance.com/api/v3/ticker/24hr?symbol=" + id) | ||
if err != nil { | ||
fmt.Println("No response from request") | ||
} | ||
defer res.Body.Close() | ||
percentage_data_body, err := io.ReadAll(res.Body) | ||
if err != nil { | ||
fmt.Println("error:", err) | ||
} | ||
|
||
return percentage_data_body, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"os" | ||
"os/exec" | ||
"runtime" | ||
"text/template" | ||
|
||
"github.com/saintmalik/dca-tool/model" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// configCmd represents the config command | ||
var configCmd = &cobra.Command{ | ||
Use: "config", | ||
Short: "A brief description of your command", | ||
Long: `A longer description that spans multiple lines and likely contains examples.`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
setApi, _ := cmd.Flags().GetString("credapi") | ||
if setApi == "reset" { | ||
openbrowser("http://localhost:4046/api") | ||
http.HandleFunc("/api", creds) | ||
fmt.Println("Starting Server to set Binance API and Secret") | ||
panic(http.ListenAndServe("localhost:4046", nil)) | ||
} else { | ||
main() | ||
} | ||
}, | ||
} | ||
|
||
var tpl *template.Template | ||
|
||
|
||
func init() { | ||
rootCmd.AddCommand(configCmd) | ||
configCmd.PersistentFlags().String("credapi", "", "Set your credentials") | ||
tpl = template.Must(template.ParseGlob("templates/*.html")) | ||
} | ||
|
||
|
||
func main() { | ||
openbrowser("http://localhost:4046/") | ||
http.HandleFunc("/", form) | ||
fmt.Println("Starting Server to set Configurations") | ||
panic(http.ListenAndServe("localhost:4046", nil)) | ||
} | ||
|
||
|
||
func creds(w http.ResponseWriter, r *http.Request) { | ||
model.Bapi = r.FormValue("bapi") | ||
model.Bsecret = r.FormValue("bsecret") //picking up the value from the form | ||
|
||
f, err := os.Create("config.yaml") | ||
if err != nil { | ||
fmt.Println(err) | ||
return | ||
} | ||
|
||
l, err := f.WriteString(`{"api":"` + model.Bapi + `","secretkey":"` + model.Bsecret + `"}`) | ||
if err != nil { | ||
fmt.Println("Error Writing to the Config.yaml file", err) | ||
f.Close() | ||
return | ||
} | ||
|
||
fmt.Println(l, "Your Binance API and Secret are set, dont let anyone access this file on your") | ||
err = f.Close() | ||
if err != nil { | ||
fmt.Println(err) | ||
return | ||
} | ||
|
||
err = tpl.ExecuteTemplate(w, "creds.html", nil) | ||
if err != nil { | ||
fmt.Println(err) | ||
} | ||
|
||
} | ||
|
||
func form(w http.ResponseWriter, r *http.Request) { | ||
model.Coinid = r.FormValue("coinid") | ||
model.Amount = r.FormValue("amount") | ||
model.Alloted = r.FormValue("allottedpercent") | ||
model.Buyinterval = r.FormValue("buyingintervals") | ||
model.Fee = r.FormValue("feepercent") | ||
model.Testvalue = r.FormValue("testing") //picking up the value from the form | ||
|
||
f, err := os.Create("config.json") | ||
if err != nil { | ||
fmt.Println(err) | ||
return | ||
} | ||
|
||
l, err := f.WriteString(`{"coins":"` + model.Coinid + `","amount":"` + model.Amount + `","percent":"` + model.Alloted + `","fee":"` + model.Fee + `","testing":"` + model.Testvalue + `","buyintervals":"` + model.Buyinterval + `"}`) | ||
if err != nil { | ||
fmt.Println("Your Binance API and Secret are set, dont let anyone access this file on you", err) | ||
f.Close() | ||
return | ||
} | ||
|
||
fmt.Println(l, "Your DCA Configurations are set, quit the server and and run dca run") | ||
err = f.Close() | ||
if err != nil { | ||
fmt.Println(err) | ||
return | ||
} | ||
|
||
err = tpl.ExecuteTemplate(w, "index.html", nil) | ||
if err != nil { | ||
fmt.Println(err) | ||
} | ||
|
||
} | ||
|
||
func openbrowser(url string) { | ||
var err error | ||
switch runtime.GOOS { | ||
case "linux": | ||
err = exec.Command("xdg-open", url).Start() | ||
case "windows": | ||
err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() | ||
case "darwin": | ||
err = exec.Command("open", url).Start() | ||
default: | ||
err = fmt.Errorf("unsupported platform") | ||
} | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
Copyright © 2022 NAME HERE <EMAIL ADDRESS> | ||
*/ | ||
package cmd | ||
|
||
import ( | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
// rootCmd represents the base command when called without any subcommands | ||
var rootCmd = &cobra.Command{ | ||
Use: "dca", | ||
Short: "A brief description of your application", | ||
Long: `A longer description that spans multiple lines and likely contains.`, | ||
// Uncomment the following line if your bare application | ||
// has an action associated with it: | ||
// Run: func(cmd *cobra.Command, args []string) { }, | ||
} | ||
|
||
// Execute adds all child commands to the root command and sets flags appropriately. | ||
// This is called by main.main(). It only needs to happen once to the rootCmd. | ||
func Execute() { | ||
err := rootCmd.Execute() | ||
if err != nil { | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
func init() { | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
package cmd | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"strconv" | ||
"time" | ||
|
||
"github.com/adshao/go-binance/v2" | ||
api_service "github.com/saintmalik/dca-tool/api_services" | ||
"github.com/saintmalik/dca-tool/model" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
// runCmd represents the run command | ||
var runCmd = &cobra.Command{ | ||
Use: "run", | ||
Short: "A brief description of your command", | ||
Long: `A longer description that.`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
perform() | ||
}, | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(runCmd) | ||
viper.SetConfigName("config") // name of config file (without extension) | ||
viper.SetConfigType("json") // REQUIRED if the config file does not have the extension in the name | ||
viper.AddConfigPath(".") // optionally look for config in the working directory | ||
err := viper.ReadInConfig() // Find and read the config file | ||
if err != nil { // Handle errors reading the config file | ||
panic(fmt.Errorf("fatal error config file: %w", err)) | ||
} | ||
} | ||
|
||
func perform() { | ||
time.Sleep(time.Hour * 6) | ||
model.Testvalue = viper.GetString("testing") | ||
if model.Testvalue == "true" { | ||
fmt.Println("Real orders cannot be made in testing mode") | ||
crap() | ||
return | ||
} else { // if testing is false, then we are in production | ||
|
||
model.Coinid = viper.GetString("coins") + "USDT" | ||
percentage_data_res_body, err := api_service.PercentageData(model.Coinid) //get current data of coin | ||
if err != nil { | ||
log.Fatal("No response from request") | ||
} | ||
|
||
var reading model.CoinPercentageData | ||
err = json.Unmarshal(percentage_data_res_body, &reading) // unmarshal JSON into Go value | ||
if err != nil { | ||
fmt.Println("error:", err) | ||
} | ||
var lik string = reading.PriceChangePercent | ||
pil, _ := strconv.ParseFloat(lik, 64) | ||
fmt.Println("percentage change", pil) | ||
|
||
//check type of percentage change | ||
switch { | ||
case pil < 0: | ||
fmt.Println("Coin is down") | ||
dcaBuy() | ||
case pil >= 0 && pil < 1.5: | ||
fmt.Println("Your weight is normal") | ||
dcaBuy() | ||
case pil >= 1.6 && pil < 2: | ||
fmt.Println("Coin is up") | ||
dcaBuy() | ||
default: | ||
fmt.Println("You're obese") | ||
} | ||
} | ||
} | ||
|
||
func dcaBuy() { | ||
model.Coinid = viper.GetString("coins") + "USDT" | ||
model.Config_buyintervals = viper.GetInt("buyintervals") | ||
model.Config_amount = viper.GetFloat64("amount") | ||
model.Config_allocated = viper.GetFloat64("percent") | ||
model.Config_fee = viper.GetFloat64("fee") | ||
|
||
purchasing_amount := (model.Config_allocated / 100) * model.Config_amount // amount of coins to buy per interval | ||
|
||
purchasing_fee := (model.Config_fee / 100) * model.Config_amount //total price of coins to buy based on percentage of coins to buy | ||
|
||
purchasing_amount_perbuy := purchasing_amount / float64(model.Config_buyintervals) // amount of coins to buy per interval | ||
|
||
purchasing_fee_perbuy := purchasing_fee / float64(model.Config_buyintervals) //total price of coins to buy based on percentage of coins to buy | ||
|
||
buying_pricing := purchasing_amount_perbuy + purchasing_fee_perbuy //total price of coins to buy based on percentage of coins to buy | ||
|
||
model.Priceperbuy = strconv.FormatFloat(buying_pricing, 'f', 2, 64) //convert float to string | ||
|
||
fmt.Println("Price per buy:", model.Priceperbuy) | ||
|
||
viper.SetConfigFile("./config.yaml") | ||
viper.ReadInConfig() | ||
|
||
client := binance.NewClient(viper.GetString("api"), viper.GetString("secretkey")) | ||
order, err := client.NewCreateOrderService().Symbol(model.Coinid). | ||
Side(binance.SideTypeBuy).Type(binance.OrderTypeMarket).QuoteOrderQty(model.Priceperbuy).Do(context.Background()) | ||
if err != nil { | ||
fmt.Println("Order Failed", err) | ||
return | ||
} | ||
fmt.Println(order) | ||
} | ||
|
||
func crap() { | ||
model.Coinid = viper.GetString("coins") + "USDT" | ||
model.Config_buyintervals = viper.GetInt("buyintervals") | ||
model.Config_amount = viper.GetFloat64("amount") | ||
model.Config_allocated = viper.GetFloat64("percent") | ||
model.Config_fee = viper.GetFloat64("fee") | ||
|
||
purchasing_amount := (model.Config_allocated / 100) * model.Config_amount // amount of coins to buy per interval | ||
|
||
purchasing_fee := (model.Config_fee / 100) * model.Config_amount //total price of coins to buy based on percentage of coins to buy | ||
|
||
purchasing_amount_perbuy := purchasing_amount / float64(model.Config_buyintervals) // amount of coins to buy per interval | ||
|
||
purchasing_fee_perbuy := purchasing_fee / float64(model.Config_buyintervals) //total price of coins to buy based on percentage of coins to buy | ||
|
||
buying_pricing := purchasing_amount_perbuy + purchasing_fee_perbuy //total price of coins to buy based on percentage of coins to buy | ||
|
||
model.Priceperbuy = strconv.FormatFloat(buying_pricing, 'f', 2, 64) //convert float to string | ||
|
||
fmt.Println("Price per buy:", model.Priceperbuy) | ||
|
||
client := binance.NewClient(viper.GetString("api"), viper.GetString("secretkey")) | ||
|
||
err := client.NewCreateOrderService().Symbol(model.Coinid). | ||
Side(binance.SideTypeBuy).Type(binance.OrderTypeMarket).QuoteOrderQty(model.Priceperbuy).Test(context.Background()) | ||
if err != nil { | ||
fmt.Println("Test Order Failed", err) | ||
return | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"coins":"ETH","amount":"1000","percent":"10","fee":"0.10","testing":"false","buyintervals":"4"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"api":"dvasfdsdf","secretkey":"dvdsavasdcadv"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
module github.com/saintmalik/dca-tool | ||
|
||
go 1.17 | ||
|
||
require ( | ||
github.com/adshao/go-binance/v2 v2.3.8 | ||
github.com/spf13/cobra v1.5.0 | ||
) | ||
|
||
require ( | ||
github.com/bitly/go-simplejson v0.5.0 // indirect | ||
github.com/fsnotify/fsnotify v1.5.4 // indirect | ||
github.com/gorilla/websocket v1.5.0 // indirect | ||
github.com/hashicorp/hcl v1.0.0 // indirect | ||
github.com/inconshreveable/mousetrap v1.0.0 // indirect | ||
github.com/json-iterator/go v1.1.12 // indirect | ||
github.com/kr/pretty v0.3.0 // indirect | ||
github.com/magiconair/properties v1.8.6 // indirect | ||
github.com/mitchellh/mapstructure v1.5.0 // indirect | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||
github.com/modern-go/reflect2 v1.0.2 // indirect | ||
github.com/pelletier/go-toml v1.9.5 // indirect | ||
github.com/pelletier/go-toml/v2 v2.0.1 // indirect | ||
github.com/spf13/afero v1.8.2 // indirect | ||
github.com/spf13/cast v1.5.0 // indirect | ||
github.com/spf13/jwalterweatherman v1.1.0 // indirect | ||
github.com/spf13/pflag v1.0.5 // indirect | ||
github.com/spf13/viper v1.12.0 // indirect | ||
github.com/stretchr/testify v1.7.1 // indirect | ||
github.com/subosito/gotenv v1.3.0 // indirect | ||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect | ||
golang.org/x/text v0.3.7 // indirect | ||
gopkg.in/ini.v1 v1.66.4 // indirect | ||
gopkg.in/yaml.v2 v2.4.0 // indirect | ||
gopkg.in/yaml.v3 v3.0.0 // indirect | ||
) |
Oops, something went wrong.