การวิเคราะห์ข้อมูลคริปโตเคอร์เรนซี (Cryptocurrency) เป็นหนึ่งในทักษะที่มีความต้องการสูงมากในปัจจุบัน ไม่ว่าจะเป็นนักลงทุนที่ต้องการสร้างโมเดลทำนายราคา หรือนักพัฒนาที่ต้องการสร้างระบบเทรดอัตโนมัติ สิ่งที่ขาดไม่ได้คือข้อมูลอนุกรมเวลา (Time Series Data) ที่มีคุณภาพ ในบทความนี้ผมจะพาทุกท่านเรียนรู้การเตรียมข้อมูลอนุกรมเวลาคริปโตตั้งแต่เริ่มต้น โดยไม่จำเป็นต้องมีประสบการณ์การใช้ API มาก่อนเลย

ทำความรู้จักกับข้อมูลอนุกรมเวลาคริปโต

ก่อนจะเริ่มลงมือทำ เรามาทำความเข้าใจกันก่อนว่าข้อมูลอนุกรมเวลาของคริปโตเคอร์เรนซีคืออะไร และทำไมการเตรียมข้อมูลให้ถูกต้องถึงมีความสำคัญมาก

ข้อมูลอนุกรมเวลาคืออะไร

ข้อมูลอนุกรมเวลาคือชุดข้อมูลที่ถูกจัดเก็บตามลำดับเวลา เช่น ราคา Bitcoin ที่ถูกบันทึกทุกๆ 1 นาที, 1 ชั่วโมง หรือ 1 วัน ตัวอย่างข้อมูลที่เราจะได้รับ ได้แก่ ราคาเปิด (Open), ราคาปิด (Close), ราคาสูงสุด (High), ราคาต่ำสุด (Low) และปริมาณการซื้อขาย (Volume)

ทำไมต้องเตรียมข้อมูลให้ดี

จากประสบการณ์ของผมที่เคยพัฒนาโมเดล Machine Learning สำหรับทำนายราคาคริปโตมาหลายปี พบว่า 80% ของเวลาทั้งหมดจะใช้ไปกับการเตรียมข้อมูล ไม่ใช่การสร้างโมเดล ข้อมูลที่ไม่สมบูรณ์หรือไม่ถูกต้องจะทำให้โมเดลให้ผลลัพธ์ที่ผิดพลาดได้ เช่น โมเดลอาจเรียนรู้จากข้อมูลที่ผิดปกติ (Outliers) และให้การทำนายที่คลาดเคลื่อนมาก

เครื่องมือที่ต้องเตรียมพร้อม

สำหรับผู้เริ่มต้น ผมแนะนำให้ติดตั้ง Python 3.8 ขึ้นไป พร้อมกับไลบรารีสำคัญดังนี้

# คำสั่งติดตั้งเครื่องมือที่จำเป็น
pip install pandas numpy requests matplotlib

หรือถ้าใช้ Anaconda

conda install pandas numpy requests matplotlib

การดึงข้อมูลจากแหล่งที่เชื่อถือได้

การได้ข้อมูลที่ถูกต้องเป็นจุดเริ่มต้นที่สำคัญมาก ผมเคยลองใช้หลายแหล่งข้อมูล ตั้งแต่การดึงจากเว็บไซต์โดยตรง ไปจนถึงการใช้ API ของตลาดต่างๆ พบว่าการใช้ API ที่เสถียรและมีความหน่วงต่ำ (Low Latency) จะให้ข้อมูลที่ทันสมัยและถูกต้องกว่า

วิธีเรียกใช้ HolySheep AI API สำหรับข้อมูลคริปโต

ในการเรียกใช้ HolySheep AI ซึ่งเป็นแพลตฟอร์ม AI ที่มีประสิทธิภาพสูงและราคาประหยัด ท่านสามารถสมัครได้ที่ สมัครที่นี่ เพื่อรับเครดิตฟรีเมื่อลงทะเบียน ระบบรองรับการชำระเงินผ่าน WeChat และ Alipay อีกด้วย

import requests
import json

ตั้งค่าการเชื่อมต่อกับ HolySheep AI API

หมายเหตุ: ค่า Latency ของระบบน้อยกว่า 50 มิลลิวินาที ทำให้การดึงข้อมูลรวดเร็วมาก

BASE_URL = "https://api.holysheep.ai/v1" API_KEY = "YOUR_HOLYSHEEP_API_KEY" # แทนที่ด้วย API Key ของคุณ headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" }

ตัวอย่างการดึงข้อมูลราคา Bitcoin

ระบบ HolySheep รองรับการประมวลผลข้อมูลอนุกรมเวลาได้อย่างมีประสิทธิภาพ

response = requests.get( f"{BASE_URL}/crypto/ohlcv", headers=headers, params={ "symbol": "BTC/USDT", # คู่เทรด "interval": "1h", # ช่วงเวลา 1 ชั่วโมง "limit": 1000 # จำนวนข้อมูล 1000 จุด } ) data = response.json() print(f"ได้รับข้อมูล {len(data)} จุด") print(data[:5]) # แสดง 5 จุดแรก

โครงสร้างข้อมูลที่ได้รับ

เมื่อเรียกใช้ API สำเร็จ เราจะได้ข้อมูลในรูปแบบ JSON ที่มีโครงสร้างดังนี้

# ตัวอย่างโครงสร้างข้อมูล JSON ที่ได้รับ
sample_data = [
    {
        "timestamp": 1704067200,      # Unix Timestamp
        "open": 42350.50,
        "high": 42500.00,
        "low": 42100.25,
        "close": 42450.75,
        "volume": 12500.5            # ปริมาณการซื้อขาย
    },
    {
        "timestamp": 1704070800,
        "open": 42450.75,
        "high": 42680.00,
        "low": 42320.50,
        "close": 42600.00,
        "volume": 15800.3
    }
]

การแปลงข้อมูล JSON เป็น DataFrame สำหรับการประมวลผล

import pandas as pd df = pd.DataFrame(sample_data) df['datetime'] = pd.to_datetime(df['timestamp'], unit='s') print(df.head())

การทำความสะอาดข้อมูล (Data Cleaning)

หลังจากได้ข้อมูลมาแล้ว ขั้นตอนต่อไปคือการทำความสะอาดข้อมูล ซึ่งเป็นขั้นตอนที่สำคัญมากและต้องใช้ความละเอียด

การจัดการค่าที่หายไป (Missing Values)

ค่าที่หายไปเป็นปัญหาที่พบบ่อยมากในข้อมูลอนุกรมเวลา เกิดจากหลายสาเหตุ เช่น ระบบขัดข้องชั่วคราว หรือตลาดปิดทำการ มีหลายวิธีในการจัดการกับค่าที่หายไป

import pandas as pd
import numpy as np

สร้าง DataFrame ตัวอย่างที่มีค่าที่หายไป

df = pd.DataFrame({ 'datetime': pd.date_range('2024-01-01', periods=10, freq='h'), 'close': [42350, 42400, np.nan, 42500, 42450, np.nan, 42600, 42550, 42700, 42650] }) print("ข้อมูลก่อนทำความสะอาด:") print(df)

วิธีที่ 1: เติมค่าด้วยค่าเฉลี่ย (ใช้เมื่อมีค่าหายไปน้อย)

df['close_mean'] = df['close'].fillna(df['close'].mean())

วิธีที่ 2: เติมค่าด้วยการ interpolate (แนะนำสำหรับข้อมูลอนุกรมเวลา)

df['close_interpolate'] = df['close'].interpolate(method='linear')

วิธีที่ 3: เติมค่าด้วย Forward Fill (ใช้ค่าก่อนหน้า)

df['close_ffill'] = df['close'].ffill()

วิธีที่ 4: เติมค่าด้วย Backward Fill (ใช้ค่าถัดไป)

df['close_bfill'] = df['close'].bfill() print("\nข้อมูลหลังทำความสะอาด:") print(df[['datetime', 'close', 'close_interpolate']].head(10))

การตรวจจับและจัดการค่าผิดปกติ (Outliers)

ค่าผิดปกติคือค่าที่แตกต่างจากค่าทั่วไปอย่างมาก อาจเกิดจากข้อผิดพลาดในการบันทึกข้อมูล หรือเหตุการณ์พิเศษในตลาด วิธีตรวจจับที่นิยมใช้คือ IQR Method

def detect_outliers_iqr(data, column, threshold=1.5):
    """
    ตรวจจับค่าผิดปกติด้วย IQR Method
    threshold: ค่าตัวคูณ IQR (ค่าแนะนำ 1.5 ถึง 3)
    """
    Q1 = data[column].quantile(0.25)
    Q3 = data[column].quantile(0.75)
    IQR = Q3 - Q1
    
    lower_bound = Q1 - threshold * IQR
    upper_bound = Q3 + threshold * IQR
    
    outliers = data[(data[column] < lower_bound) | (data[column] > upper_bound)]
    
    print(f"Q1: {Q1:.2f}, Q3: {Q3:.2f}, IQR: {IQR:.2f}")
    print(f"ขอบเขตล่าง: {lower_bound:.2f}, ขอบเขตบน: {upper_bound:.2f}")
    print(f"พบค่าผิดปกติ {len(outliers)} จุด")
    
    return outliers, lower_bound, upper_bound

ตัวอย่างการใช้งาน

sample_prices = [42350, 42400, 50000, 42500, 42450, 49000, 42600, 42550, 42700, 42650] df_test = pd.DataFrame({'close': sample_prices}) outliers, lower, upper = detect_outliers_iqr(df_test, 'close', threshold=1.5)

วิธีจัดการกับ Outliers

วิธีที่ 1: แทนที่ด้วยค่าขอบเขต

df_test['close_clipped'] = df_test['close'].clip(lower=lower, upper=upper)

วิธีที่ 2: แทนที่ด้วยค่าเฉลี่ย (ไม่รวม outliers)

mask = (df_test['close'] >= lower) & (df_test['close'] <= upper) mean_value = df_test.loc[mask, 'close'].mean() df_test['close_mean_replaced'] = df_test['close'].apply( lambda x: mean_value if x < lower or x > upper else x ) print("\nผลลัพธ์:") print(df_test)

การสร้างฟีเจอร์สำหรับโมเดล Machine Learning

การสร้างฟีเจอร์ (Feature Engineering) เป็นศาสตร์และศิลป์ในการแปลงข้อมูลดิบให้เป็นข้อมูลที่โมเดลสามารถเรียนรู้ได้ดีขึ้น ผมจะแบ่งปันเทคนิคที่ใช้มาจากประสบการณ์ตรง

ฟีเจอร์พื้นฐานที่ควรมี

import pandas as pd
import numpy as np

def create_basic_features(df, price_col='close'):
    """
    สร้างฟีเจอร์พื้นฐานสำหรับข้อมูลอนุกรมเวลาคริปโต
    """
    df = df.copy()
    
    # 1. ผลตอบแทน (Returns)
    df['returns'] = df[price_col].pct_change()
    
    # 2. ผลตอบแทนสะสม (Cumulative Returns)
    df['cumulative_returns'] = (1 + df['returns']).cumprod() - 1
    
    # 3. ความผันผวน (Volatility) - ค่าเบี่ยงเบนมาตรฐานของผลตอบแทน
    df['volatility_7d'] = df['returns'].rolling(window=7).std()
    df['volatility_30d'] = df['returns'].rolling(window=30).std()
    
    # 4. ค่าเฉลี่ยเคลื่อนที่ (Moving Averages)
    df['ma_7'] = df[price_col].rolling(window=7).mean()
    df['ma_25'] = df[price_col].rolling(window=25).mean()
    df['ma_99'] = df[price_col].rolling(window=99).mean()
    
    # 5. อัตราส่วนราคาต่อ MA (Price to MA Ratio)
    df['price_to_ma7'] = df[price_col] / df['ma_7']
    df['price_to_ma25'] = df[price_col] / df['ma_25']
    
    # 6. RSI (Relative Strength Index)
    delta = df[price_col].diff()
    gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
    rs = gain / loss
    df['rsi'] = 100 - (100 / (1 + rs))
    
    # 7. Bollinger Bands
    df['bb_middle'] = df[price_col].rolling(window=20).mean()
    df['bb_std'] = df[price_col].rolling(window=20).std()
    df['bb_upper'] = df['bb_middle'] + (df['bb_std'] * 2)
    df['bb_lower'] = df['bb_middle'] - (df['bb_std'] * 2)
    df['bb_position'] = (df[price_col] - df['bb_lower']) / (df['bb_upper'] - df['bb_lower'])
    
    # 8. MACD
    exp1 = df[price_col].ewm(span=12, adjust=False).mean()
    exp2 = df[price_col].ewm(span=26, adjust=False).mean()
    df['macd'] = exp1 - exp2
    df['macd_signal'] = df['macd'].ewm(span=9, adjust=False).mean()
    df['macd_histogram'] = df['macd'] - df['macd_signal']
    
    return df

ตัวอย่างการใช้งาน

สมมติว่ามี DataFrame ชื่อ df ที่มีคอลัมน์ 'close'

df_featured = create_basic_features(df)

print(df_featured.head(30))

ฟีเจอร์ขั้นสูงจากประสบการณ์

def create_advanced_features(df, price_col='close', volume_col='volume'):
    """
    สร้างฟีเจอร์ขั้นสูงที่ผมใช้ในโปรเจกต์จริง
    """
    df = df.copy()
    
    # 1. Momentum Indicators
    # ROC (Rate of Change)
    df['roc_10'] = ((df[price_col] - df[price_col].shift(10)) / df[price_col].shift(10)) * 100
    df['roc_20'] = ((df[price_col] - df[price_col].shift(20)) / df[price_col].shift(20)) * 100
    
    # Stochastic Oscillator
    low_14 = df['low'].rolling(window=14).min()
    high_14 = df['high'].rolling(window=14).max()
    df['stoch_k'] = 100 * ((df[price_col] - low_14) / (high_14 - low_14))
    df['stoch_d'] = df['stoch_k'].rolling(window=3).mean()
    
    # 2. Volume Indicators
    # OBV (On Balance Volume)
    df['obv'] = (np.sign(df[volume_col].diff()) * df[volume_col]).fillna(0).cumsum()
    
    # Volume MA
    df['volume_ma'] = df[volume_col].rolling(window=20).mean()
    df['volume_ratio'] = df[volume_col] / df['volume_ma']
    
    # 3. Time-based Features
    if 'datetime' in df.columns:
        df['hour'] = df['datetime'].dt.hour
        df['day_of_week'] = df['datetime'].dt.dayofweek
        df['day_of_month'] = df['datetime'].dt.day
        df['month'] = df['datetime'].dt.month
        df['is_weekend'] = df['day_of_week'].isin([5, 6]).astype(int)
    
    # 4. Lag Features (ค่าในอดีต)
    for lag in [1, 2, 3, 5, 7, 14]:
        df[f'returns_lag_{lag}'] = df['returns'].shift(lag)
        df[f'close_lag_{lag}'] = df[price_col].shift(lag)
    
    # 5. Rolling Statistics
    for window in [7, 14, 30]:
        df[f'close_skew_{window}'] = df[price_col].rolling(window=window).skew()
        df[f'close_kurt_{window}'] = df[price_col].rolling(window=window).kurt()
    
    # 6. Cross-sectional Features
    df['high_low_ratio'] = df['high'] / df['low']
    df['close_open_diff'] = df['close'] - df['open']
    df['close_open_ratio'] = df['close'] / df['open']
    
    return df

หมายเหตุ: ฟังก์ชันนี้ต้องการข้อมูล 'high' และ 'low' ด้วย

df_advanced = create_advanced_features(df)

print(f"จำนวนฟีเจอร์ทั้งหมด: {len(df_advanced.columns)}")

การปรับขนาดข้อมูล (Data Scaling)

การปรับขนาดข้อมูลเป็นขั้นตอนสำคัญที่ช่วยให้โมเดล Machine Learning ทำงานได้ดีขึ้น เนื่องจากฟีเจอร์ต่างๆ มีมาตราส่วนที่แตกต่างกันมาก เช่น ราคา Bitcoin อยู่ที่หลายหมื่น แต่ RSI อยู่ที่ 0-100

from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler

def scale_features(df, feature_cols, method='standard'):
    """
    ปรับขนาดฟีเจอร์ด้วยวิธีต่างๆ
    
    Parameters:
    - method: 'standard' (Z-score), 'minmax' (0-1), 'robust' (ใช้ median)
    """
    df = df.copy()
    
    # เลือก Scaler ตามวิธีที่ต้องการ
    if method == 'standard':
        scaler = StandardScaler()
    elif method == 'minmax':
        scaler