Ahr999 指標是由中國比特幣投資者 @ahr999 創建的一個比特幣價值評估工具。這個指標結合了比特幣的歷史價格數據和理論價值模型,用於判斷比特幣當前是被高估還是被低估。
Ahr999 指標主要用於長期投資決策,幫助投資者識別潛在的買入和賣出機會。它特別適合於識別比特幣市場周期中的極端情況,如牛市頂部和熊市底部。
Ahr999 指標由兩個子指標的乘積組成:
其中:
回歸擬合價格使用以下公式計算:
其中,比特幣年齡是從2009年1月3日(比特幣創世區塊)到當前日期的天數。
Ahr999 指標在歷史上表現出色,成功識別了多個重要的市場轉折點:
雖然Ahr999指標是一個強大的工具,但在使用時需要注意以下幾點:
import requests
import pandas as pd
import numpy as np
from datetime import datetime, timezone
def fetch_binance_data(symbol, interval, limit=200):
"""
從幣安API獲取K線數據。
:param symbol: 交易對,如'BTCUSDT'
:param interval: K線間隔,如'1d'表示一天
:param limit: 獲取的數據數量,默認200
:return: 包含交易數據的DataFrame
"""
url = "https://api.binance.com/api/v3/klines"
params = {
'symbol': symbol,
'interval': interval,
'limit': limit
}
response = requests.get(url, params=params)
if response.status_code == 200:
data = response.json()
df = pd.DataFrame(data, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume', 'close_time', 'quote_asset_volume', 'number_of_trades', 'taker_buy_base_asset_volume', 'taker_buy_quote_asset_volume', 'ignore'])
df['close'] = df['close'].astype(float)
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
return df
else:
return pd.DataFrame() # 返回空的DataFrame以表示錯誤
def calculate_geometric_mean(prices):
"""
計算給定價格的幾何平均值。
:param prices: 價格数组
:return: 幾何平均值
"""
prices = prices[~np.isnan(prices)]
return np.exp(np.mean(np.log(prices))) if len(prices) > 0 else np.nan
def estimate_bitcoin_price(age, k=5.84, b=-17.01):
"""
根据比特幣的年齡估算其價格。
:param age: 比特币自誕生以來的天數
:param k: 模型参数k
:param b: 模型参数b
:return: 估算價格
"""
return 10 ** (k * np.log10(age) + b)
def calculate_ahr999_index(current_price, geometric_mean, estimated_price):
"""
計算AHR999指數。
:param current_price: 當前價格
:param geometric_mean: 幾何平均價
:param estimated_price: 估算價格
:return: AHR999指數
"""
avg_index = current_price / geometric_mean
estimate_index = current_price / estimated_price
return avg_index * estimate_index
# 主邏輯實作
btc_data = fetch_binance_data('BTCUSDT', '1d')
if not btc_data.empty:
bitcoin_birthday = datetime(2009, 1, 3, tzinfo=timezone.utc)
current_date = datetime.now(timezone.utc)
bitcoin_age = (current_date - bitcoin_birthday).days
estimated_price = estimate_bitcoin_price(bitcoin_age)
current_price = btc_data['close'].iloc[-2] # 昨日收盤價
geometric_mean = calculate_geometric_mean(btc_data['close'].iloc[-202:-2]) # 排除最後一天
ahr999_index = calculate_ahr999_index(current_price, geometric_mean, estimated_price)
date_for_display = btc_data['timestamp'].iloc[-2].strftime('%Y-%m-%d')
print(f"日期: {date_for_display}")
print(f"AHR999指數: {ahr999_index}")
print(f"當前價格: {current_price}")
print(f"預估價格: {estimated_price}")
print(f"幾何平均價: {geometric_mean}")
else:
print("無法取得過去200天的數據。")
// 從 Bybit API 獲取K線數據
async function fetchBybitData(symbol, interval, limit = 200) {
try {
// 使用兩個請求來獲取足夠的數據,因為 Bybit 每次最多只能返回 200 筆數據
const now = Date.now();
const oneDayMs = 24 * 60 * 60 * 1000;
// 第一個請求:獲取最近 200 天的數據
const response = await axios.get('https://api.bybit.com/v5/market/kline', {
params: {
category: 'spot',
symbol: symbol,
interval: interval, // 'D' 表示日線
limit: limit // Bybit API 最多可獲取 200 筆數據
}
});
if (response.status !== 200 || !response.data || !response.data.result || !response.data.result.list || response.data.result.list.length === 0) {
throw new Error(`無法取得${symbol}數據`);
}
// 轉換數據格式,Bybit API 的數據是從新到舊排序的
const recentData = response.data.result.list.map(item => ({
timestamp: new Date(parseInt(item[0])), // Bybit 的時間戳是毫秒
close: parseFloat(item[4]) // 收盤價在第 5 個元素
}));
// 反轉數據使其從舊到新排序
const sortedData = recentData.slice().reverse();
// 如果需要更多數據,可以使用最舊的數據進行填充
if (sortedData.length < 202 && sortedData.length > 0) {
console.warn('數據不足 202 天,使用最舊的數據進行填充');
const oldestData = sortedData[0];
const requiredExtraDays = 202 - sortedData.length;
for (let i = 0; i < requiredExtraDays; i++) {
const prevDay = new Date(sortedData[0].timestamp);
prevDay.setDate(prevDay.getDate() - 1);
sortedData.unshift({
timestamp: prevDay,
close: oldestData.close // 使用最舊的收盤價
});
}
}
return sortedData;
} catch (error) {
console.error('獲取數據時出錯:', error);
return [];
}
}
// 計算幾何平均值
function calculateGeometricMean(prices) {
// 移除NaN值
const validPrices = prices.filter(price => !isNaN(price));
if (validPrices.length === 0) return NaN;
// 計算對數的平均值,然後取指數
const logSum = validPrices.reduce((sum, price) => sum + Math.log(price), 0);
return Math.exp(logSum / validPrices.length);
}
// 根據比特幣的年齡估算其價格
function estimateBitcoinPrice(age, k = 5.84, b = -17.01) {
return Math.pow(10, k * Math.log10(age) + b);
}
// 計算AHR999指數
function calculateAhr999Index(currentPrice, geometricMean, estimatedPrice) {
const avgIndex = currentPrice / geometricMean;
const estimateIndex = currentPrice / estimatedPrice;
return avgIndex * estimateIndex;
}
// 主函數
async function calculateAhr999() {
try {
// 獲取比特幣數據
const btcData = await fetchBybitData('BTCUSDT', 'D', 200);
if (btcData.length === 0) {
throw new Error('無法取得比特幣數據');
}
// 計算比特幣年齡
const bitcoinBirthday = new Date('2009-01-03T00:00:00Z');
const currentDate = new Date();
const bitcoinAge = Math.floor((currentDate - bitcoinBirthday) / (1000 * 60 * 60 * 24)); // 轉換為天數
// 計算估算價格
const estimatedPrice = estimateBitcoinPrice(bitcoinAge);
// 獲取昨日收盤價
const currentPrice = btcData[btcData.length - 2].close;
// 計算幾何平均價
const pricesForGeometricMean = btcData.slice(0, btcData.length - 2).map(item => item.close);
const geometricMean = calculateGeometricMean(pricesForGeometricMean);
// 計算AHR999指數
const ahr999Index = calculateAhr999Index(currentPrice, geometricMean, estimatedPrice);
// 獲取日期
const dateForDisplay = btcData[btcData.length - 2].timestamp.toLocaleDateString();
return {
date: dateForDisplay,
ahr999Index: ahr999Index.toFixed(2),
currentPrice: currentPrice.toFixed(2),
estimatedPrice: estimatedPrice.toFixed(2),
geometricMean: geometricMean.toFixed(2)
};
} catch (error) {
console.error('計算AHR999指數時出錯:', error);
return null;
}
}