diff --git a/README.md b/README.md new file mode 100755 index 0000000..73705b7 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# 小工具---自动生成虚拟币收益数据 +## 下载 +- [windows](https://github.com/K1ngram4/CoinRecord/releases/download/V1.0/CoinRecord_win.zip) +- [osx](https://github.com/K1ngram4/CoinRecord/releases/download/V1.0/CoinRecord_macos.zip) + +执行可执行文件即可在records目录下生成md文件,记录收益数据 + +- 效果 + +| 币种 | 持有数量 | 现价 | 总金额 | 持仓均价 | 成本 | 利润 | 收益率 | +| ---- | -------------- | ------------ | ----------- | ------------ | ----------- | --------- | ------ | +| btc | 0.013343 | 45168.320300 | 602.680898 | 41737.240501 | 556.900000 | 45.780898 | 8.22% | +| doge | 8058.726300 | 0.299873 | 2416.596306 | 0.297150 | 2394.650000 | 21.946306 | 0.92% | +| icp | 0.718261 | 57.868641 | 41.564765 | 57.138036 | 41.040000 | 0.524765 | 1.28% | +| shib | 3460860.410000 | 0.000008 | 28.326569 | 0.000008 | 28.240000 | 0.086569 | 0.31% | +| win | 9991.000000 | 0.000635 | 6.340803 | 0.000621 | 6.200000 | 0.140803 | 2.27% | + + +## 配置说明 +- 配置文件在holds目录下,json格式,多条记录分开 +```json +{ + "name": "btc", + "records": [ + { + "operate": "+", + "amount": 0.01329424, + "sum": 613.82 + }, + { + "operate": "-", + "amount": 0.01329424, + "sum": 613.82 + } + ] +} +``` +- name 币种 +- records 表示操作记录 + - opetare 操作 “+”买入 “-”卖出 + - amount 数量 + - sum 总金额 单位usdt + +**一个币种一个json文件** \ No newline at end of file diff --git a/coinPrice/coinMarketCap.go b/coinPrice/coinMarketCap.go new file mode 100644 index 0000000..38ed0b7 --- /dev/null +++ b/coinPrice/coinMarketCap.go @@ -0,0 +1,119 @@ +package coinPrice + +type CoinMarketCapLastListResult struct { + Data []SingleCoinInfo `json:"data"` + Status State `json:"status"` +} + +type State struct { + Timestamp string `json:"timestamp"` + ErrorCode int `json:"error_code"` + ErrorMessage string `json:"error_message"` + Elapsed int `json:"elapsed"` + CreditCount int `json:"credit_count"` +} + +type SingleCoinInfo struct { + ID int `json:"id"` + Name string `json:"name"` + Symbol string `json:"symbol"` + Slug string `json:"slug"` + //市值排名 + CmcRank int `json:"cmc_rank"` + NumMarketPairs int `json:"num_market_pairs"` + CirculatingSupply float64 `json:"circulating_supply"` + //目前存在的硬币总量 + TotalSupply float64 `json:"total_supply"` + + MaxSupply float64 `json:"max_supply"` + LastUpdated string `json:"last_updated"` + DateAdded string `json:"date_added"` + Tags []string `json:"tags"` + Platform quoteInfo `json:"-"` + Quote quoteInfos `json:"quote"` +} + +type quoteInfos struct { + BTC quoteInfo + USD quoteInfo +} + +type quoteInfo struct { + //价格 + Price float64 `json:"price"` + // 24小时交易量 + Volume24H float64 `json:"volume_24h"` + //1小时变化 + PercentChange1H float64 `json:"percent_change_1h"` + //24小时变化 + PercentChange24H float64 `json:"percent_change_24h"` + //7天变化 + PercentChange7D float64 `json:"percent_change_7d"` + //市值 + MarketCap float64 `json:"market_cap"` + MarketCapDominance float64 `json:"market_cap_dominance"` + FullyDilutedMarketCap float64 `json:"fully_diluted_market_cap"` + LastUpdated string `json:"last_updated"` +} + +//=========== +type GlobalMetricsResult struct { + Data GlobalMetricsData `json:"data"` + Status State `json:"status"` + LastUpdated string `json:"last_updated"` +} + +type GlobalMetricsData struct { + ActiveCryptocurrencies int `json:"active_cryptocurrencies"` + TotalCryptocurrencies int `json:"total_cryptocurrencies"` + ActiveMarketPairs int `json:"active_market_pairs"` + ActiveExchanges int `json:"active_exchanges"` + TotalExchanges int `json:"total_exchanges"` + EthDominance float64 `json:"eth_dominance"` + BtcDominance float64 `json:"btc_dominance"` + EthDominanceYesterday float64 `json:"eth_dominance_yesterday"` + BtcDominanceYesterday float64 `json:"btc_dominance_yesterday"` + EthDominance24HPercentageChange float64 `json:"eth_dominance_24h_percentage_change"` + BtcDominance24HPercentageChange float64 `json:"btc_dominance_24h_percentage_change"` + DefiVolume24H float64 `json:"defi_volume_24h"` + DefiVolume24HReported float64 `json:"defi_volume_24h_reported"` + DefiMarketCap float64 `json:"defi_market_cap"` + Defi24HPercentageChange float64 `json:"defi_24h_percentage_change"` + StablecoinVolume24H float64 `json:"stablecoin_volume_24h"` + StablecoinVolume24HReported float64 `json:"stablecoin_volume_24h_reported"` + StablecoinMarketCap float64 `json:"stablecoin_market_cap"` + Stablecoin24HPercentageChange float64 `json:"stablecoin_24h_percentage_change"` + DerivativesVolume24H float64 `json:"derivatives_volume_24h"` + DerivativesVolume24HReported float64 `json:"derivatives_volume_24h_reported"` + Derivatives24HPercentageChange float64 `json:"derivatives_24h_percentage_change"` + Quote GlobalMetricsQuoteInfo `json:"quote"` +} + +type GlobalMetricsQuoteInfo struct { + USD GlobalMetricsQuoteInfoUsd +} + +type GlobalMetricsQuoteInfoUsd struct { + TotalMarketCap float64 `json:"total_market_cap"` + TotalVolume24H float64 `json:"total_volume_24h"` + TotalVolume24HReported float64 `json:"total_volume_24h_reported"` + AltcoinVolume24H float64 `json:"altcoin_volume_24h"` + AltcoinVolume24HReported float64 `json:"altcoin_volume_24h_reported"` + AltcoinMarketCap float64 `json:"altcoin_market_cap"` + DefiVolume24H float64 `json:"defi_volume_24h"` + DefiVolume24HReported float64 `json:"defi_volume_24h_reported"` + Defi24HPercentageChange float64 `json:"defi_24h_percentage_change"` + DefiMarketCap float64 `json:"defi_market_cap"` + StablecoinVolume24H float64 `json:"stablecoin_volume_24h"` + StablecoinVolume24HReported float64 `json:"stablecoin_volume_24h_reported"` + Stablecoin24HPercentageChange float64 `json:"stablecoin_24h_percentage_change"` + StablecoinMarketCap float64 `json:"stablecoin_market_cap"` + DerivativesVolume24H float64 `json:"derivatives_volume_24h"` + DerivativesVolume24HReported float64 `json:"derivatives_volume_24h_reported"` + Derivatives24HPercentageChange float64 `json:"derivatives_24h_percentage_change"` + LastUpdated string `json:"last_updated"` + TotalMarketCapYesterday float64 `json:"total_market_cap_yesterday"` + TotalVolume24HYesterday float64 `json:"total_volume_24h_yesterday"` + TotalMarketCapYesterdayPercentageChange float64 `json:"total_market_cap_yesterday_percentage_change"` + TotalVolume24HYesterdayPercentageChange float64 `json:"total_volume_24h_yesterday_percentage_change"` +} diff --git a/coinPrice/coinMarketCap_test.go b/coinPrice/coinMarketCap_test.go new file mode 100644 index 0000000..9537fc6 --- /dev/null +++ b/coinPrice/coinMarketCap_test.go @@ -0,0 +1,27 @@ +package coinPrice + +import ( + "CoinRecord/httpUtil" + "encoding/json" + "fmt" + "testing" +) + +func TestGetCoinPrice(t *testing.T) { + url := "https://pro-api.coinmarketcap.com/v1/global-metrics/quotes/latest" + m := make(map[string]string) + m2 := make(map[string]string) + //m["start"] = "1" + //m["limit"] = "100" + b, err := httpUtil.HttpGet(url, m, m2) + if err != nil { + fmt.Printf("%+v", err) + } + //fmt.Println(string(b)) + res := &GlobalMetricsResult{} + err = json.Unmarshal(b, res) + if err != nil { + fmt.Printf("%+v",err) + } + fmt.Printf("%+v",res) +} diff --git a/coinPrice/coinPrice.go b/coinPrice/coinPrice.go new file mode 100755 index 0000000..8d5b746 --- /dev/null +++ b/coinPrice/coinPrice.go @@ -0,0 +1,72 @@ +package coinPrice + +import ( + "CoinRecord/httpUtil" + "encoding/json" + "fmt" + "strings" + "time" +) + +// coincap.io +//var url = "https://api.coincap.io/v2/assets" +var url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest" +var coinMarketCapUrl = "https://pro-api.coinmarketcap.com/v1/global-metrics/quotes/latest" + +var res CoinMarketCapLastListResult +var GRes GlobalMetricsResult + +func GetAllCoinPrice() error { + //api比较卡,简单加个重试机制 + var count int + var params = make(map[string]string) + params["limit"] = "1000" + params["start"] = "1" + var headers = make(map[string]string) + for { + if count > 10 { + break + } + resBytes, err := httpUtil.HttpGet(url, params, headers) + if err != nil { + count++ + fmt.Printf("%+v \n", err) + time.Sleep(time.Millisecond * 10) + continue + } + + err = json.Unmarshal(resBytes, &res) + if err != nil { + count++ + fmt.Printf("%+v \n", err) + time.Sleep(time.Millisecond * 10) + continue + } + break + } + return nil +} + +func GetCoinPrice(id string) SingleCoinInfo { + for _, coinInfo := range res.Data { + if coinInfo.Name == id || coinInfo.Slug == id || coinInfo.Symbol == strings.ToUpper(id) { + return coinInfo + } + } + + return SingleCoinInfo{} +} + +func GetCoinMarketCap () error { + var params = make(map[string]string) + var headers = make(map[string]string) + resBytes, err := httpUtil.HttpGet(coinMarketCapUrl, params, headers) + if err != nil { + return err + } + err = json.Unmarshal(resBytes, &GRes) + if err != nil { + return err + } + return nil +} \ No newline at end of file diff --git a/floatprocess.go b/floatprocess.go new file mode 100755 index 0000000..9afce42 --- /dev/null +++ b/floatprocess.go @@ -0,0 +1,17 @@ +package main + +import ( + "fmt" + "math/big" + "strconv" +) + +func ProcessFloat(f float64) float64 { + num2, _ := strconv.ParseFloat(fmt.Sprintf("%.8f", f), 64) + return num2 +} + +//big.NewRat(1, 1).SetFloat64(coinPrice.GRes.Data.Quote.USD.TotalVolume24H).FloatString(0) +func ConvertFloatToString(f float64) string{ + return big.NewRat(1, 1).SetFloat64(f).FloatString(0) +} \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100755 index 0000000..43aa4ac --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module CoinRecord + +go 1.16 + +require github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum new file mode 100755 index 0000000..7c401c3 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/holds/bitcoin.json b/holds/bitcoin.json new file mode 100755 index 0000000..74e32ec --- /dev/null +++ b/holds/bitcoin.json @@ -0,0 +1,10 @@ +{ + "name": "btc", + "records": [ + { + "operate": "+", + "amount": 0.002185, + "sum": 100 + } + ] +} \ No newline at end of file diff --git a/holds/bnb.json b/holds/bnb.json new file mode 100644 index 0000000..e3b6f86 --- /dev/null +++ b/holds/bnb.json @@ -0,0 +1,10 @@ +{ + "name": "bnb", + "records": [ + { + "operate": "+", + "amount": 0.095403, + "sum": 40 + } + ] +} \ No newline at end of file diff --git a/holds/dot.json b/holds/dot.json new file mode 100644 index 0000000..954b03c --- /dev/null +++ b/holds/dot.json @@ -0,0 +1,10 @@ +{ + "name": "dot", + "records": [ + { + "operate": "+", + "amount": 1.559096, + "sum": 40 + } + ] +} \ No newline at end of file diff --git a/holds/eth.json b/holds/eth.json new file mode 100644 index 0000000..5fc0cc7 --- /dev/null +++ b/holds/eth.json @@ -0,0 +1,10 @@ +{ + "name": "eth", + "records": [ + { + "operate": "+", + "amount": 0.032844, + "sum": 100 + } + ] +} \ No newline at end of file diff --git a/holds/ftt.json b/holds/ftt.json new file mode 100644 index 0000000..c247e53 --- /dev/null +++ b/holds/ftt.json @@ -0,0 +1,10 @@ +{ + "name": "ftt", + "records": [ + { + "operate": "+", + "amount": 0.840243, + "sum": 40 + } + ] +} \ No newline at end of file diff --git a/holds/link.json b/holds/link.json new file mode 100644 index 0000000..8b68c87 --- /dev/null +++ b/holds/link.json @@ -0,0 +1,10 @@ +{ + "name": "link", + "records": [ + { + "operate": "+", + "amount": 1.526624, + "sum": 40 + } + ] +} \ No newline at end of file diff --git a/holds/uni.json b/holds/uni.json new file mode 100644 index 0000000..d7f75b7 --- /dev/null +++ b/holds/uni.json @@ -0,0 +1,10 @@ +{ + "name": "uni", + "records": [ + { + "operate": "+", + "amount": 1.497, + "sum": 40 + } + ] +} \ No newline at end of file diff --git a/httpUtil/httpUtil.go b/httpUtil/httpUtil.go new file mode 100755 index 0000000..fda8755 --- /dev/null +++ b/httpUtil/httpUtil.go @@ -0,0 +1,59 @@ +package httpUtil + +import ( + "context" + "fmt" + "github.com/pkg/errors" + "io/ioutil" + "net" + "net/http" + "time" +) + +func HttpGet(url string, params map[string]string, headers map[string]string) ([]byte, error) { + c := http.Client{ + Transport: &http.Transport{ + DialContext: (&net.Dialer{ + Timeout: time.Second, + }).DialContext, + }, + } + ctx, cancel := context.WithTimeout(context.Background(), 2000*time.Millisecond) + defer cancel() + //new request + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return []byte{}, errors.New("new request is fail ") + } + req.Header.Set("Accepts", "application/json") + req.Header.Add("X-CMC_PRO_API_KEY", "27f65df8-ff71-49a9-829f-176b3a41426b") + //add params + q := req.URL.Query() + if params != nil { + for key, val := range params { + q.Add(key, val) + } + req.URL.RawQuery = q.Encode() + } + //add headers + if headers != nil { + for key, val := range headers { + req.Header.Add(key, val) + } + } + //http client + fmt.Printf("Go %s URL : %s \n", http.MethodGet, req.URL.String()) + do, err := c.Do(req.WithContext(ctx)) + if err != nil { + return []byte{}, errors.Wrap(err, "do req failed.") + } + defer do.Body.Close() + + bytesBody, err := ioutil.ReadAll(do.Body) + if err != nil { + return []byte{}, errors.New("read body failed") + } + + fmt.Printf("HttpGet receive : %s \n", string(bytesBody)) + return bytesBody, nil +} diff --git a/main.go b/main.go new file mode 100755 index 0000000..dc970eb --- /dev/null +++ b/main.go @@ -0,0 +1,231 @@ +package main + +import ( + "CoinRecord/coinPrice" + "CoinRecord/models" + "embed" + "encoding/json" + "fmt" + "html/template" + "io/ioutil" + "log" + "os" + "path/filepath" + "strings" + "time" +) + +const StartTime = "2021-08-19" + +//go:embed template/* +var fs embed.FS + +func main() { + + err := coinPrice.GetAllCoinPrice() + err = coinPrice.GetCoinMarketCap() + if err != nil { + log.Fatal(err) + return + } + + var getCurrentDirectory = func() string { + dir, err := filepath.Abs(filepath.Dir(os.Args[0])) + if err != nil { + log.Fatal(err) + } + return strings.Replace(dir, "\\", "/", -1) + } + + currentDir := getCurrentDirectory() + fmt.Println("current DIR:", currentDir) + + holdsDir := filepath.Join(currentDir, "holds") + + rd, err := ioutil.ReadDir(holdsDir) + if err != nil { + log.Fatal(err) + return + } + + var allHolds []models.Holds + for _, fi := range rd { + if fi.IsDir() { + continue + } + fmt.Println(fi.Name()) + filePath := filepath.Join(holdsDir, fi.Name()) + f, err := os.Open(filePath) + if err != nil { + log.Fatal(err) + return + } + content, err := ioutil.ReadAll(f) + if err != nil { + log.Fatal(err) + return + } + var holds models.Holds + err = json.Unmarshal(content, &holds) + if err != nil { + log.Fatal(err) + return + } + fmt.Printf("%+v \n", holds) + allHolds = append(allHolds, holds) + } + + var coinInfoVos []models.CoinInfoVo + for i, v := range allHolds { + fmt.Printf("id: %d,value:%+v \n", i, v) + //遍历所有记录计算投资总额,成本价,币的数量 + var coinAmount float64 + var name string + var avgPrice float64 + var coinCost float64 + var coinSum float64 + var profit float64 + var yield float64 + var priceUsd float64 + for _, coin := range v.Records { + switch coin.Operate { + case "+": + coinAmount += coin.Amount + coinCost += coin.Sum + case "-": + coinAmount -= coin.Amount + coinCost -= coin.Sum + } + } + name = v.Name + // 单个币平均成本价格 = 总成本/币的数量 + avgPrice = coinCost / coinAmount + coinInfo := coinPrice.GetCoinPrice(name) + priceUsd = ProcessFloat(coinInfo.Quote.USD.Price) + coinSum = priceUsd * coinAmount + // 利润 = 持仓现价 - 投资总额 + profit = coinSum - coinCost + // 收益率 = 利润/投资总额 + yield = profit / coinCost + coinInfoVo := models.CoinInfoVo{ + Name: name, + Amount: ProcessFloat(coinAmount), + Sum: ProcessFloat(coinSum), + NowPrice: ProcessFloat(priceUsd), + AvgPrice: ProcessFloat(avgPrice), + Cost: ProcessFloat(coinCost), + Profit: ProcessFloat(profit), + Yield: fmt.Sprintf("%.2f", yield*100) + "%", + CmcRank: coinInfo.CmcRank, + } + coinInfoVo.MarketCap = ConvertFloatToString(coinInfo.Quote.USD.MarketCap) + coinInfoVo.Volume24H = ConvertFloatToString(coinInfo.Quote.USD.Volume24H) + per24h := coinInfo.Quote.USD.PercentChange24H + per7d := coinInfo.Quote.USD.PercentChange7D + coinInfoVo.PercentChange24H= fmt.Sprintf("%.2f",per24h)+"%" + coinInfoVo.PercentChange7D= fmt.Sprintf("%.2f",per7d)+"%" + //原单价 = 现单价 / (1+昨日涨幅) + //(现单价 - 原单价) * 持有数量 = 昨日收益 + yesPrice := coinInfo.Quote.USD.Price / (1+(per24h * 0.01)) + coinInfoVo.Profit24h = ProcessFloat((coinInfo.Quote.USD.Price - yesPrice) * coinAmount) + + coinInfoVo.Change24hColor = models.ShallowRed + coinInfoVo.DeepChange24hColor = models.ShallowRed + coinInfoVo.YieldColor = models.ShallowRed + coinInfoVo.DeepYieldColor = models.Red + coinInfoVo.DeepChange7DColor = models.Red + if per24h > 0{ + coinInfoVo.Change24hColor = models.ShallowGreen + coinInfoVo.DeepChange24hColor = models.Green + } + + if per7d > 0 { + coinInfoVo.DeepChange7DColor = models.Green + } + + if yield > 0 { + coinInfoVo.YieldColor = models.ShallowGreen + coinInfoVo.DeepYieldColor = models.Green + } + coinInfoVos = append(coinInfoVos, coinInfoVo) + } + + mdDir := filepath.Join(currentDir, "records") + _ = os.MkdirAll(mdDir, 0666) + mdFileName := time.Now().Format("20060102150405") + ".md" + mdFilePath := filepath.Join(mdDir, mdFileName) + fmt.Println(mdFilePath) + mdFile, err := os.OpenFile(mdFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666) + if err != nil { + log.Fatal(err) + } + defer mdFile.Close() + + var totalProfit float64 + var totalCost float64 + var totalYield float64 + var totalSum float64 + var yesProfit float64 + for _, v := range coinInfoVos { + totalProfit += v.Profit + totalCost += v.Cost + totalSum += v.Sum + yesProfit += v.Profit24h + } + totalYield = totalProfit / totalCost + totalYieldString := fmt.Sprintf("%.2f", totalYield*100) + "%" + var templateValue = models.TemplateValue { + StartTime: StartTime, + NowTime: TimeFormat(time.Now()), + NowDay: time.Now().Format("2006-01-02"), + TotalProfit: ProcessFloat(totalProfit), + TotalCost: ProcessFloat(totalCost), + TotalYield: totalYieldString, + TotalSum: ProcessFloat(totalSum), + } + templateValue.IncomeData = coinInfoVos + templateValue.YesterdayProfit = yesProfit + templateValue.Days = timeSub(time.Now(), StringToTime(StartTime)) + templateValue.YesterdayProfitColor = models.Red + templateValue.TotalYieldClolor = models.Red + if totalYield > 0 { + templateValue.TotalYieldClolor = models.Green + } + if templateValue.YesterdayProfit> 0 { + templateValue.YesterdayProfitColor = models.Green + } + //保存行情信息 + + templateValue.TotalMarketCap = ConvertFloatToString(coinPrice.GRes.Data.Quote.USD.TotalMarketCap) + tmcpc := coinPrice.GRes.Data.Quote.USD.TotalMarketCapYesterdayPercentageChange + if tmcpc > 0 { + templateValue.TotalMarketColor = models.Green + } else { + templateValue.TotalMarketColor = models.Red + } + templateValue.TotalMarketCapYesterdayPercentageChange = fmt.Sprintf("%.2f",tmcpc)+"%" + + templateValue.TotalVolume24h = ConvertFloatToString(coinPrice.GRes.Data.Quote.USD.TotalVolume24H) + tvcpc := coinPrice.GRes.Data.Quote.USD.TotalVolume24HYesterdayPercentageChange + if tvcpc > 0 { + templateValue.TotalVolumeColor = models.Green + } else { + templateValue.TotalVolumeColor = models.Red + } + templateValue.TotalVolume24hYesterdayPercentageChange = fmt.Sprintf("%.2f",tmcpc)+"%" + + // 把模板编进二进制文件中 + tmpl, err := template.ParseFS(fs, "template/*.tmpl") + if err != nil { + log.Fatal(err) + return + } + err = tmpl.Execute(mdFile, templateValue) + if err != nil { + log.Fatal(err) + return + } + fmt.Println("按任意键继续...") + var input string + _, _ = fmt.Scanln(&input) +} diff --git a/models/record.go b/models/record.go new file mode 100755 index 0000000..07f2aee --- /dev/null +++ b/models/record.go @@ -0,0 +1,97 @@ +package models + +type Holds struct { + Name string `json:"name"` + Records []Record `json:"records"` +} + +type Record struct { + Operate string `json:"operate"` + Amount float64 `json:"amount"` + Sum float64 `json:"sum"` +} + +const ( + Green = "#00EC00" + ShallowGreen = "#F0FFF0" + Red = "#FF0000" + ShallowRed = "#FFECEC" +) + +type CoinInfoVo struct { + //币种 + Name string + //持有数量 + Amount float64 + //现价 + NowPrice float64 + //现在的总金额 + Sum float64 + //成本单价 + AvgPrice float64 + //成本 + Cost float64 + //利润 + Profit float64 + //收益率 + Yield string + //颜色 + YieldColor string + DeepYieldColor string + Change24hColor string + DeepChange24hColor string + DeepChange7DColor string + //排名 + CmcRank int + //市值 + MarketCap string + //24小时交易量 + Volume24H string + //24小时变化 + PercentChange24H string + //7天变化 + PercentChange7D string + Profit24h float64 +} + +type TemplateValue struct { + // 总市值 + TotalMarketCap string + //总交易量 + TotalVolume24h string + TotalVolumeColor string + TotalMarketColor string + //较昨日总交易量变化百分比 + TotalVolume24hYesterdayPercentageChange string + //较昨日总市值变化百分比 + TotalMarketCapYesterdayPercentageChange string + // defi总市值 + DefiMarketCap float64 + //defi交易量 + DefiVolume24h float64 + //defi总市值变化 + Defi24hPercentageChange string + //开始时间 + StartTime string + //定投天数 + Days int + //当前时间 + NowTime string + //今天日期 + NowDay string + //24h收益 + YesterdayProfit float64 + YesterdayProfitColor string + //总利润 + TotalProfit float64 + //总成本 + TotalCost float64 + //总收益率 + TotalYield string + //总价值 + TotalSum float64 + //字体颜色 + TotalYieldClolor string + //收益数据 + IncomeData []CoinInfoVo +} diff --git a/records/.DS_Store b/records/.DS_Store new file mode 100644 index 0000000..7a3e897 Binary files /dev/null and b/records/.DS_Store differ diff --git a/records/20210821002355.md b/records/20210821002355.md new file mode 100644 index 0000000..5494327 --- /dev/null +++ b/records/20210821002355.md @@ -0,0 +1,199 @@ +--- +title: "2021-08-21 数字货币定投日记,收益率:8.51%" +author: "Kingram" +date: "2021-08-21" +lastmod: "2021-08-21" +tags: [ + "投资", + "虚拟币", +] +--- + +## 📊 今日行情 +### 截止 **2021-08-21 00:23:55** +- 🍖 全球加密市场总市值为: **2099373330217** USDT,24h内变化: **7.65%** + +- 🍤 24h总交易量为: **113661280175** USDT,24h内变化: **7.65%** + +## 🎨 我的持仓占比 +```mermaid +pie title 我的持仓 +"btc" : 100 +"bnb" : 40 +"dot" : 40 +"eth" : 100 +"ftt" : 40 +"link" : 40 +"uni" : 40 +``` + +## 📋 我的定投策略 +📎 我的定投策略制定于 **2021-08-19**,今天是我开始定投的第 **2** 天 + +
由于我在币圈总是被割韭菜,深知自己XJB投资的策略有很大问题,在这个24小时不停盘的d场,我自认为抵制不住人性的贪婪和恐惧;我摊牌了,不装了,我认怂。 +所以我制定了自己的定投策略,看策略就知道我这个定投计划还是非常非常保守的。我将以月为单位,每月定投 400 USDT(根据行情不同可能有波动,各项波动不超过50%),一年内暂不考虑卖出。看看一年后会有什么样的市场行情。
+ +- 🥇 当月市值最高的币种 100USDT +- 🥈 当月市值第2高的币种 100USDT +- 🥉 当月市值前20选4个币种,合计 160USDT +- 🏅 (可选,不选这个就投1个第3项的币种)感兴趣(被CX)或者社区治理优秀(SB多)的1~2个币种,合计40USDT + +## ⏰ 24小时收益情况 +📌 过去的24小时我的持仓总收益为:**33.11000247** USDT + +👉 每个币种的详细数据如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
币种排名市值(USDT)24h交易量(USDT)24h%7d%24h收益
btc1919552625517352492641936.94%5.61%6.94189446
bnb47600451677724391859327.10%14.43%2.85729193
dot827644556680252269073710.01%29.66%3.97014147
eth2385501909089197197658567.41%2.52%7.45810615
ftt31503043155033125884912.05%0.33%4.81626831
link1212920498596181203557510.29%10.31%4.11066
uni11170464609884719728257.30%-1.35%2.95564015
+ +## 🎯 持仓整体收益数据 + +🔒 我的持仓总成本为:**400** USDT,截止 **2021-08-21 00:23:55**,总价值为:**434.0507552** USDT + +💰 利润: **34.0507552** USDT,收益率:**8.51%** + +👉 每个币种的详细收益数据如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
币种持有数量(个)现价(USDT)总金额(USDT)持仓均价(USDT)成本(USDT)利润(USDT)收益率
btc0.00218548933.32653168106.9193184745766.590389021006.919318476.92%
bnb0.095403452.0391139643.12588759419.27402702403.125887597.81%
dot1.55909627.9922394743.6425885925.6558929403.642588599.11%
eth0.0328443289.69444704108.046724423044.696139331008.046724428.05%
ftt0.84024353.3184289344.8004366847.60527609404.8004366812.00%
link1.52662428.8720061644.0766975326.20160563404.0766975310.19%
uni1.49729.0174361543.4391019226.72010688403.439101928.60%
+ +## ⚠️ 风险友情提示 +❤️ 本篇文章仅作为个人投资记录使用,区块链投资风险巨大,请管好你自己的钱袋子呦~ ❤️ \ No newline at end of file diff --git a/records/20210821152950.md b/records/20210821152950.md new file mode 100644 index 0000000..5713104 --- /dev/null +++ b/records/20210821152950.md @@ -0,0 +1,200 @@ +{ + "title":"2021-08-21 数字货币定投日记,收益率:8.45%", + "tags":[ + "投资", + "虚拟币" + ], + "date":"2021-08-21", + "lastmod":"2021-08-21", + "draft":"false", + "author":"kingram" +} + +## 📊 今日行情 +### 截止 **2021-08-21 15:29:50** +- 🍖 全球加密市场总市值为: **2101755608148** USDT,24h内变化: **3.10%** + +- 🍤 24h总交易量为: **111762157749** USDT,24h内变化: **3.10%** + +## 🎨 我的持仓占比 +```mermaid +pie title 我的持仓 +"btc" : 100 +"bnb" : 40 +"dot" : 40 +"eth" : 100 +"ftt" : 40 +"link" : 40 +"uni" : 40 +``` + +## 📋 我的定投策略 +📎 我的定投策略制定于 **2021-08-19**,今天是我开始定投的第 **2** 天 + +
由于我在币圈总是被割韭菜,深知自己XJB投资的策略有很大问题,在这个24小时不停盘的d场,我自认为抵制不住人性的贪婪和恐惧;我摊牌了,不装了,我认怂。 +所以我制定了自己的定投策略,看策略就知道我这个定投计划还是非常非常保守的。我将以月为单位,每月定投 400 USDT(根据行情不同可能有波动,各项波动不超过50%),一年内暂不考虑卖出。看看一年后会有什么样的市场行情。
+ +- 🥇 当月市值最高的币种 100USDT +- 🥈 当月市值第2高的币种 100USDT +- 🥉 当月市值前20选4个币种,合计 160USDT +- 🏅 (可选,不选这个就投1个第3项的币种)感兴趣(被CX)或者社区治理优秀(SB多)的1~2个币种,合计40USDT + +## ⏰ 24小时收益情况 +📌 过去的24小时我的持仓总收益为:**17.24395709** USDT + +👉 每个币种的详细数据如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
币种排名市值(USDT)24h交易量(USDT)24h%7d%24h收益
btc1919052433737381893899983.95%2.54%4.0567011
bnb47678207318724968850396.86%9.50%2.79765083
dot82856206760225388627118.37%25.96%3.48261227
eth2385197963065210096255422.02%-0.98%2.1345665
ftt3347584335998200491370.44%0.04%0.18628369
link131289969585616673419225.85%3.56%2.43145867
uni11172422598844468570435.16%-3.28%2.15468403
+ +## 🎯 持仓整体收益数据 + +🔒 我的持仓总成本为:**400** USDT,截止 **2021-08-21 15:29:50**,总价值为:**433.79191867** USDT + +💰 利润: **33.79191867** USDT,收益率:**8.45%** + +👉 每个币种的详细收益数据如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
币种持有数量(个)现价(USDT)总金额(USDT)持仓均价(USDT)成本(USDT)利润(USDT)收益率
btc0.00218548905.29605288106.8580718845766.590389021006.858071886.86%
bnb0.095403456.6636537343.56708256419.27402702403.567082568.92%
dot1.55909628.9212898345.0910672925.6558929405.0910672912.73%
eth0.0328443286.8751786107.954128373044.696139331007.954128377.95%
ftt0.84024350.4354748142.3780546647.60527609402.378054665.95%
link1.52662428.8255205844.0057315326.20160563404.0057315310.01%
uni1.49729.3505560343.9377823826.72010688403.937782389.84%
+ +## ⚠️ 风险友情提示 +❤️ 本篇文章仅作为个人投资记录使用,区块链投资风险巨大,请管好你自己的钱袋子呦~ ❤️ \ No newline at end of file diff --git a/template/blog.tmpl b/template/blog.tmpl new file mode 100755 index 0000000..f262c28 --- /dev/null +++ b/template/blog.tmpl @@ -0,0 +1,86 @@ +{ + "title":"{{.NowDay}} 数字货币定投日记,收益率:{{.TotalYield}}", + "tags":[ + "投资", + "虚拟币" + ], + "date":"{{.NowDay}}", + "lastmod":"{{.NowDay}}", + "draft":"false", + "author":"kingram" +} + +## 📊 今日行情 +### 截止 **{{.NowTime}}** +- 🍖 全球加密市场总市值为: **{{.TotalMarketCap}}** USDT,24h内变化: **{{.TotalMarketCapYesterdayPercentageChange}}** + +- 🍤 24h总交易量为: **{{.TotalVolume24h}}** USDT,24h内变化: **{{.TotalVolume24hYesterdayPercentageChange}}** + +## 🎨 我的持仓占比 +```mermaid +pie title 我的持仓 +{{- range .IncomeData}} +"{{.Name}}" : {{.Cost}} +{{- end}} +``` + +## 📋 我的定投策略 +📎 我的定投策略制定于 **{{.StartTime}}**,今天是我开始定投的第 **{{.Days}}** 天 + +
由于我在币圈总是被割韭菜,深知自己XJB投资的策略有很大问题,在这个24小时不停盘的d场,我自认为抵制不住人性的贪婪和恐惧;我摊牌了,不装了,我认怂。 +所以我制定了自己的定投策略,看策略就知道我这个定投计划还是非常非常保守的。我将以月为单位,每月定投 400 USDT(根据行情不同可能有波动,各项波动不超过50%),一年内暂不考虑卖出。看看一年后会有什么样的市场行情。
+ +- 🥇 当月市值最高的币种 100USDT +- 🥈 当月市值第2高的币种 100USDT +- 🥉 当月市值前20选4个币种,合计 160USDT +- 🏅 (可选,不选这个就投1个第3项的币种)感兴趣(被CX)或者社区治理优秀(SB多)的1~2个币种,合计40USDT + +## ⏰ 24小时收益情况 +📌 过去的24小时我的持仓总收益为:**{{.YesterdayProfit}}** USDT + +👉 每个币种的详细数据如下: + + + + {{- range .IncomeData}} + + + + + + + + + + {{- end}} + +
币种排名市值(USDT)24h交易量(USDT)24h%7d%24h收益
{{.Name}}{{.CmcRank}}{{.MarketCap}}{{.Volume24H}}{{.PercentChange24H}}{{.PercentChange7D}}{{.Profit24h}}
+ +## 🎯 持仓整体收益数据 + +🔒 我的持仓总成本为:**{{.TotalCost}}** USDT,截止 **{{.NowTime}}**,总价值为:**{{.TotalSum}}** USDT + +💰 利润: **{{.TotalProfit}}** USDT,收益率:**{{.TotalYield}}** + +👉 每个币种的详细收益数据如下: + + + + + {{- range .IncomeData}} + + + + + + + + + + + {{- end}} + +
币种持有数量(个)现价(USDT)总金额(USDT)持仓均价(USDT)成本(USDT)利润(USDT)收益率
{{.Name}}{{.Amount}}{{.NowPrice}}{{.Sum}}{{.AvgPrice}}{{.Cost}}{{.Profit}}{{.Yield}}
+ +## ⚠️ 风险友情提示 +❤️ 本篇文章仅作为个人投资记录使用,区块链投资风险巨大,请管好你自己的钱袋子呦~ ❤️ \ No newline at end of file diff --git a/timeprocess.go b/timeprocess.go new file mode 100644 index 0000000..2446374 --- /dev/null +++ b/timeprocess.go @@ -0,0 +1,24 @@ +package main + +import "time" + +const timeTemplate1 = "2006-01-02 15:04:05" //常规类型 + +func StringToTime(t1 string) time.Time { + if len(t1) < len(timeTemplate1) { + t1 += " 00:00:00" + } + stamp, _ := time.ParseInLocation(timeTemplate1, t1, time.Local) + return stamp +} + +func TimeFormat(t time.Time) string { + return t.Format(timeTemplate1) +} + +func timeSub(t1, t2 time.Time) int { + t1 = time.Date(t1.Year(), t1.Month(), t1.Day(), 0, 0, 0, 0, time.Local) + t2 = time.Date(t2.Year(), t2.Month(), t2.Day(), 0, 0, 0, 0, time.Local) + + return int(t1.Sub(t2).Hours() / 24) +} diff --git a/timeprocess_test.go b/timeprocess_test.go new file mode 100644 index 0000000..d414b37 --- /dev/null +++ b/timeprocess_test.go @@ -0,0 +1,10 @@ +package main + +import ( + "fmt" + "testing" +) + +func TestTimeFormat(t *testing.T) { + fmt.Println(StringToTime(StartTime)) +}