blockchain/internal/lib/strategy/ema.go

67 lines
2.4 KiB
Go
Raw Normal View History

2025-08-14 23:41:29 +00:00
package strategy
import "github.com/shopspring/decimal"
2025-08-15 01:36:36 +00:00
/*
EMA全名為指數移動平均線Exponential Moving Average用於平滑價格波動幫助識別市場趨勢
它與簡單移動平均線SMA不同EMA 更注重近期價格因此對價格變動的反應更迅速能更快地反映市場趨勢
EMA 的主要特點和作用
更快速的反應
EMA SMA 更快地反映價格變動因為它給予近期數據更高的權重
識別趨勢
通過平滑價格波動EMA 有助於識別市場的整體趨勢判斷是上升趨勢還是下降趨勢
輔助交易決策
EMA 的使用可以幫助交易者判斷買入和賣出的時機例如當股價高於EMA 可能被視為買入信號反之則可能被視為賣出信號
適合短線交易
由於EMA 對價格變動的敏感性它更適合於短線交易者能更快地捕捉市場的短期波動
EMA 的計算方法
EMA 的計算涉及一個平滑因子和一個初始值然後每天更新 具體公式可以參考專業的金融網站或交易平台提供的資料
總結
EMA 是一種有用的技術分析工具尤其適合於快速變動的市場它可以幫助交易者更好地理解市場趨勢並制定相應的交易策略
*/
2025-08-14 23:41:29 +00:00
type EMA struct {
2025-08-15 01:36:36 +00:00
n uint
2025-08-14 23:41:29 +00:00
alp decimal.Decimal // 平滑係數 α = 2 / (n + 1)
val decimal.Decimal // 當前EMA值
2025-08-15 01:36:36 +00:00
ok bool // 內部旗標,用於判斷是否為第一筆資料
2025-08-14 23:41:29 +00:00
}
2025-08-15 01:36:36 +00:00
// NewEMA 建立EMA計算器
func NewEMA(n uint) *EMA {
return &EMA{
n: n,
alp: decimal.NewFromInt(2).Div(decimal.NewFromInt(int64(n + 1))),
ok: false,
}
2025-08-14 23:41:29 +00:00
}
2025-08-15 01:36:36 +00:00
// Push 輸入收盤價返回當前EMA值
2025-08-14 23:41:29 +00:00
func (e *EMA) Push(close decimal.Decimal) (decimal.Decimal, bool) {
2025-08-15 01:36:36 +00:00
// 如果 n 無效,永遠回傳無效狀態
if e.n == 0 {
return decimal.Zero, false
}
2025-08-14 23:41:29 +00:00
if !e.ok {
2025-08-15 01:36:36 +00:00
// 第一筆資料直接當作EMA初始值並將狀態設為 ok
2025-08-14 23:41:29 +00:00
e.val = close
e.ok = true
2025-08-15 01:36:36 +00:00
} else {
// 後續資料使用 EMA 計算公式
// EMA = α * close + (1 - α) * prev_EMA
e.val = e.alp.Mul(close).Add(decimal.NewFromInt(1).Sub(e.alp).Mul(e.val))
}
// EMA 從第一筆資料開始就是有效的
return e.val, true
}
// GetEMA 取得目前 EMA 值
func (e *EMA) GetEMA() (decimal.Decimal, bool) {
if !e.ok {
return decimal.Zero, false // 尚未初始化
2025-08-14 23:41:29 +00:00
}
return e.val, true
}