Golang实现平均真实范围(ATR)程序时遇到问题怎么解决

Golang实现平均真实范围(ATR)程序时遇到问题怎么解决 我正在尝试创建一个程序,用于返回某只股票15天的高点、低点、收盘价和开盘价。目前这部分功能正常,但计算股票的真实波幅时遇到了问题。

以下是需要计算的条件:

  1. 当日高点与当日低点之间的距离
  2. 昨日收盘价与当日高点之间的距离
  3. 昨日收盘价与当日低点之间的距离

我希望程序能计算这些条件,然后返回所有数值绝对值中的最大值。目前只有第一个条件能正常工作。问题出在后两个条件上,因为程序没有正确保存前一天的收盘价,导致无法进行后续计算。

如果有人愿意帮忙,我会贴出代码。我想先简要说明一下情况,而不是一股脑地抛出所有信息。

谢谢。


更多关于Golang实现平均真实范围(ATR)程序时遇到问题怎么解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

你是否遇到任何特定的错误信息或意外行为?如果可能,请分享确切的措辞。

更多关于Golang实现平均真实范围(ATR)程序时遇到问题怎么解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


根据你的描述,问题核心在于需要跨交易日保存前一天的收盘价数据。以下是针对此问题的解决方案,包含一个完整的ATR计算示例:

package main

import (
	"fmt"
	"math"
)

// PriceData 表示每日价格数据
type PriceData struct {
	Date   string
	High   float64
	Low    float64
	Close  float64
	Open   float64
	TR     float64 // 真实波幅
}

// 计算单日真实波幅
func calculateTrueRange(current, previous PriceData) float64 {
	// 条件1: 当日高点与当日低点之间的距离
	hl := current.High - current.Low
	
	// 条件2: 昨日收盘价与当日高点之间的距离
	hcp := math.Abs(previous.Close - current.High)
	
	// 条件3: 昨日收盘价与当日低点之间的距离
	lcp := math.Abs(previous.Close - current.Low)
	
	// 返回三个值中的最大值
	return math.Max(hl, math.Max(hcp, lcp))
}

// 计算ATR
func calculateATR(prices []PriceData, period int) []float64 {
	if len(prices) < period {
		return nil
	}
	
	atrValues := make([]float64, len(prices))
	
	// 计算第一个ATR(前period天的TR平均值)
	var sumTR float64
	for i := 0; i < period; i++ {
		if i > 0 {
			prices[i].TR = calculateTrueRange(prices[i], prices[i-1])
		} else {
			prices[i].TR = prices[i].High - prices[i].Low
		}
		sumTR += prices[i].TR
	}
	atrValues[period-1] = sumTR / float64(period)
	
	// 计算后续ATR值(使用平滑公式)
	for i := period; i < len(prices); i++ {
		currentTR := calculateTrueRange(prices[i], prices[i-1])
		prices[i].TR = currentTR
		
		// ATR平滑公式: 前一日ATR * (n-1) + 当前TR / n
		atrValues[i] = (atrValues[i-1]*float64(period-1) + currentTR) / float64(period)
	}
	
	return atrValues
}

func main() {
	// 示例数据(15个交易日)
	prices := []PriceData{
		{"2024-01-01", 150.0, 148.0, 149.0, 149.5},
		{"2024-01-02", 152.0, 149.0, 151.0, 149.0},
		{"2024-01-03", 153.0, 150.0, 152.0, 151.0},
		{"2024-01-04", 151.0, 148.0, 150.0, 152.0},
		{"2024-01-05", 155.0, 150.0, 154.0, 150.0},
		{"2024-01-06", 156.0, 153.0, 155.0, 154.0},
		{"2024-01-07", 154.0, 151.0, 152.0, 155.0},
		{"2024-01-08", 158.0, 152.0, 157.0, 152.0},
		{"2024-01-09", 159.0, 156.0, 158.0, 157.0},
		{"2024-01-10", 157.0, 154.0, 155.0, 158.0},
		{"2024-01-11", 161.0, 155.0, 160.0, 155.0},
		{"2024-01-12", 162.0, 159.0, 161.0, 160.0},
		{"2024-01-13", 160.0, 157.0, 158.0, 161.0},
		{"2024-01-14", 164.0, 158.0, 163.0, 158.0},
		{"2024-01-15", 165.0, 162.0, 164.0, 163.0},
	}
	
	// 计算14日ATR(通常ATR使用14日周期)
	period := 14
	atrValues := calculateATR(prices, period)
	
	// 输出结果
	fmt.Println("ATR计算结果:")
	for i := period - 1; i < len(atrValues); i++ {
		fmt.Printf("日期: %s, ATR(14): %.4f\n", prices[i].Date, atrValues[i])
	}
	
	// 输出每日真实波幅
	fmt.Println("\n每日真实波幅(TR):")
	for i := 1; i < len(prices); i++ {
		tr := calculateTrueRange(prices[i], prices[i-1])
		fmt.Printf("%s -> %s: TR = %.4f\n", 
			prices[i-1].Date, prices[i].Date, tr)
	}
}

关键解决方案:

  1. 数据结构设计:使用PriceData结构体存储每日价格数据,确保能访问前一日收盘价
  2. 计算逻辑calculateTrueRange函数明确处理三种情况:
    • 当日高低点差
    • 昨日收盘与当日高点绝对差
    • 昨日收盘与当日低点绝对差
  3. 数据连续性:通过数组/切片顺序存储,确保能通过索引i-1访问前一日数据
  4. 边界处理:第一个交易日没有前一日数据,使用高低点差作为初始TR

如果你的数据获取方式不同,需要确保在计算TR时能正确获取到前一天的收盘价数据。

回到顶部