WIP components (as built)
This commit is contained in:
112 files changed
+3607
-1241
No files matched your search
+18
-10
@@ -7,38 +7,46 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Candle is one period of trading: open, high, low, close and volume.
|
||||
// Candle holds OHLC prices, time, and volume.
|
||||
type Candle struct {
|
||||
Time time.Time
|
||||
Open, High, Low, Close float64
|
||||
Volume float64
|
||||
}
|
||||
|
||||
// marketCheckCandles panics on candles out of time order or with impossible prices.
|
||||
// marketCheckCandles validates chronological candles and finite OHLC values.
|
||||
func marketCheckCandles(candles []Candle) {
|
||||
for i, c := range candles {
|
||||
if c.Time.IsZero() || i > 0 && !c.Time.After(candles[i-1].Time) {
|
||||
panic(fmt.Sprintf("mujica: candle %d time is zero or not after the one before", i))
|
||||
}
|
||||
for _, v := range []float64{c.Open, c.High, c.Low, c.Close, c.Volume} {
|
||||
if math.IsNaN(v) || math.IsInf(v, 0) {
|
||||
panic("mujica: candle values must be finite")
|
||||
}
|
||||
}
|
||||
if !(c.Low <= min(c.Open, c.Close)) || !(c.High >= max(c.Open, c.Close)) || c.Volume < 0 || math.IsNaN(c.Volume) {
|
||||
panic(fmt.Sprintf("mujica: candle %d has impossible prices or volume", i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MarketView is the caller-held window of a market chart: zoom and pan.
|
||||
// MarketView holds the visible candle window.
|
||||
type MarketView struct {
|
||||
// Count is how many candles show; zero shows 120.
|
||||
Count int
|
||||
// End is one past the last shown candle; zero follows the newest.
|
||||
// End is exclusive; zero follows the newest candle.
|
||||
End int
|
||||
}
|
||||
|
||||
// marketWindow resolves the view to [from, to) over n candles, at most room wide.
|
||||
// marketWindow resolves the visible range, bounded by room.
|
||||
func marketWindow(v MarketView, n, room int) (from, to int) {
|
||||
if v.Count < 0 || v.End < 0 {
|
||||
panic("mujica: MarketView Count and End must not be negative")
|
||||
}
|
||||
if n == 0 {
|
||||
return 0, 0
|
||||
}
|
||||
count := v.Count
|
||||
if count == 0 {
|
||||
count = 120
|
||||
@@ -51,7 +59,7 @@ func marketWindow(v MarketView, n, room int) (from, to int) {
|
||||
return to - count, to
|
||||
}
|
||||
|
||||
// marketPan moves the view by delta candles; reaching the newest follows it again.
|
||||
// marketPan moves the window; the newest edge enables following.
|
||||
func marketPan(v *MarketView, n, room, delta int) {
|
||||
from, to := marketWindow(*v, n, room)
|
||||
v.Count = to - from
|
||||
@@ -63,7 +71,7 @@ func marketPan(v *MarketView, n, room, delta int) {
|
||||
}
|
||||
}
|
||||
|
||||
// marketZoom scales the shown count by f, keeping the newest shown candle, within 10 and room.
|
||||
// marketZoom changes visible count while preserving the right edge.
|
||||
func marketZoom(v *MarketView, n, room int, f float64) {
|
||||
from, to := marketWindow(*v, n, room)
|
||||
count := int(math.Round(float64(to-from) * f))
|
||||
@@ -76,18 +84,18 @@ func marketZoom(v *MarketView, n, room int, f float64) {
|
||||
}
|
||||
}
|
||||
|
||||
// marketIndexAt finds the candle at or before t, or -1 before the first.
|
||||
// marketIndexAt finds the candle at or before t.
|
||||
func marketIndexAt(candles []Candle, t time.Time) int {
|
||||
return sort.Search(len(candles), func(i int) bool { return candles[i].Time.After(t) }) - 1
|
||||
}
|
||||
|
||||
// Interval names a candle period: 1m 3m 5m 15m 30m 1h 2h 4h 6h 12h 1D 3D 1W 1M.
|
||||
// Interval names a supported candle period.
|
||||
type Interval string
|
||||
|
||||
// Intervals lists every Interval, shortest first.
|
||||
var Intervals = []Interval{"1m", "3m", "5m", "15m", "30m", "1h", "2h", "4h", "6h", "12h", "1D", "3D", "1W", "1M"}
|
||||
|
||||
// Close returns when the candle holding t closes: periods align to the clock in loc, weeks start Monday.
|
||||
// Close aligns periods locally; weeks start Monday.
|
||||
func (iv Interval) Close(t time.Time, loc *time.Location) time.Time {
|
||||
t = t.In(loc)
|
||||
day := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, loc)
|
||||
|
||||
Reference in new issue
Block a user