Skip to content

Commit

Permalink
Not perfect but it works
Browse files Browse the repository at this point in the history
  • Loading branch information
saintmalik committed Aug 4, 2022
0 parents commit e9f79ce
Show file tree
Hide file tree
Showing 14 changed files with 1,028 additions and 0 deletions.
Empty file added LICENSE
Empty file.
22 changes: 22 additions & 0 deletions api_services/percentage_change.go
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
}
134 changes: 134 additions & 0 deletions cmd/config.go
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)
}

}
35 changes: 35 additions & 0 deletions cmd/root.go
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() {
}


143 changes: 143 additions & 0 deletions cmd/run.go
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
}
}
1 change: 1 addition & 0 deletions config.json
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"}
1 change: 1 addition & 0 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"api":"dvasfdsdf","secretkey":"dvdsavasdcadv"}
36 changes: 36 additions & 0 deletions go.mod
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
)
Loading

0 comments on commit e9f79ce

Please sign in to comment.