package cryptomarket import ( "fmt" "math" "strings" "time" ) // Chart uses one column per completed daily candle, auto-scales for BTC and // tiny tokens alike, and delegates color to the player's configured palette. func Chart(candles []Candle, width int, unicode bool, paint func(string, bool) string) []string { width = max(12, min(80, width)) label := 12 count := width - label - 2 if count < 2 || len(candles) < 2 { return []string{"Not enough completed daily candles."} } if len(candles) > count { candles = candles[len(candles)-count:] } type bar struct{ o, h, l, c float64 } bars := []bar{} low, high := math.Inf(1), math.Inf(-1) for _, c := range candles { if c.Validate() != nil { return []string{"Invalid candle history."} } o, _ := rat(c.Open).Float64() h, _ := rat(c.High).Float64() l, _ := rat(c.Low).Float64() v, _ := rat(c.Close).Float64() bars = append(bars, bar{o, h, l, v}) low = math.Min(low, l) high = math.Max(high, h) } if high == low { padding := math.Max(high*0.01, 1e-18) low -= padding high += padding } const height = 10 row := func(p float64) int { return max(0, min(height-1, int(math.Round((high-p)/(high-low)*(height-1))))) } grid := make([][]string, height) for y := range grid { grid[y] = make([]string, len(bars)) for x := range grid[y] { grid[y][x] = " " } } wick, body, doji, axis := "|", "#", "-", "|" if unicode { wick, body, doji, axis = "│", "█", "━", "│" } for x, b := range bars { top, bottom := min(row(b.o), row(b.c)), max(row(b.o), row(b.c)) for y := row(b.h); y <= row(b.l); y++ { ch := wick if y >= top && y <= bottom { ch = body if top == bottom { ch = doji } } if paint != nil { ch = paint(ch, b.c >= b.o) } grid[y][x] = ch } } out := []string{"USD / credits; daily candles (UTC). Up/down colored; body=open-close, wick=range."} for y := range grid { v := high - float64(y)*(high-low)/(height-1) out = append(out, fmt.Sprintf("%11.5g %s%s", v, axis, strings.Join(grid[y], ""))) } out = append(out, fmt.Sprintf("%s to %s", time.Unix(candles[0].Time, 0).UTC().Format("2006-01-02"), time.Unix(candles[len(candles)-1].Time, 0).UTC().Format("2006-01-02"))) return out }