2
fokus pada
410
Pengikut

Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet?

Dibuat di: 2025-12-25 14:35:55, diperbarui pada: 2026-01-09 11:16:40
comments   0
hits   189

[TOC]

Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet?

📢 Armor Berlapis

Artikel ini adalahSebuah Tinjauan Ilmiah Populer tentang Transformasi Wavelet untuk Praktik PerdaganganKode ini adalah versi pengajaran yang disederhanakan (menghilangkan langkah-langkah kompleks seperti dekomposisi multi-level, peredaman derau ambang batas, dan rekonstruksi transformasi invers dari wavelet standar), hanya mempertahankan ide-ide intinya:Gunakan koefisien wavelet untuk melakukan penghalusan multi-skala pada harga guna mengekstrak informasi tren.Cocok untuk pengembangan strategi dan validasi cepat, tetapi tidak untuk penelitian akademis atau publikasi makalah.


I. Pendahuluan: Membongkar Mitos tentang “Guru Zhihu” (Pakar)

Mereka yang sering menjelajahi topik keuangan dan kuantitatif di Zhihu pasti pernah melihat skenario ini:

Beberapa “pakar” terus mengatakan:

  • Pengurangan kebisingan transformasi wavelet
  • Periode ekstraksi transformasi Fourier
  • Penghalusan Laplace menghilangkan data pencilan.

Dia membuat semua orang tercengang, seolah-olah dia telah menguasai senjata nuklir berupa perdagangan kuantitatif.

Tapi kamu ingin dia menunjukkan kodenya padamu?
“Ini… adalah rahasia dagang, dan saya tidak dapat mengungkapkannya.”

Mintalah dia untuk menjelaskan prinsipnya.
“Ini… melibatkan matematika tingkat lanjut, kamu tidak akan mengerti meskipun aku menjelaskannya kepadamu.”

Hari ini, kita akan menjelajahi topik-topik yang sering disebutkan oleh para “pakar Zhihu” ini, memperkenalkan aplikasi praktis transformasi wavelet di pasar keuangan, dan membantu semua orang mengembangkan pemahaman yang benar tentang teknologi ini.


II. Apa sebenarnya transformasi wavelet itu?

Penjelasan sederhana

Bayangkan Anda sedang mendengarkan sebuah lagu, tetapi ada suara bising di latar belakang rekaman tersebut:

Rekaman asli = suara manusia + kebisingan latar belakang + statis

Transformasi wavelet itu sepertiFilter Pintar

  • Jaga suara
  • Saring kebisingan.
  • Ini juga dapat memberi tahu Anda bagian mana yang merupakan chorus dan bagian mana yang merupakan verse.

Beralihlah ke pasar keuangan:

Harga Asli = Tren Sebenarnya + Fluktuasi Jangka Pendek + Gangguan Acak

Transformasi wavelet dapat membantu Anda:

  • Mengungkap tren sebenarnya(Arah jangka panjang)
  • Menyaring fluktuasi jangka pendek(Fluktuasi intraday)
  • Mengidentifikasi titik-titik perubahan penting(Pembalikan Tren)

Konsep inti: Dekomposisi fungsi basis

Inti sari dari transformasi wavelet adalahUraikan sinyal asli menggunakan serangkaian “fungsi basis” (wavelet) tertentu.

Bayangkan Anda ingin mendeskripsikan penampilan seseorang:

  • Metode tradisional: mendeskripsikan piksel demi piksel, yang sangat membosankan.
  • Metode wavelet: menggunakan faktor-faktor seperti “ukuran mata, tinggi hidung, dan kontur wajah”fiturUntuk menggabungkan deskripsi

Dalam harga finansial:

Seri harga asli = Fungsi basis 1 × Bobot 1 + Fungsi basis 2 × Bobot 2 + … + Derau

Fungsi basis adalah “template” yang sesuai dengan koefisien wavelet.Berbagai jenis wavelet (Haar, Daubechies, Mexican Hat, dll.) menggunakan templat yang berbeda, sama seperti menggunakan “ekstraktor fitur” yang berbeda untuk menguraikan harga.

Filter: Sebuah saringan dalam domain frekuensi

Transformasi wavelet pada dasarnya adalah…Bank filter multiskala:

Filter frekuensi tinggi → Mampu menangkap fluktuasi cepat (noise harian, fluktuasi tingkat tick) Filter frekuensi menengah → Menangkap tren jangka menengah (rentang waktu dari beberapa jam hingga beberapa hari). Filter frekuensi rendah → Menangkap tren jangka panjang (tren mingguan dan bulanan).

Mengapa disebut “wavelet”?

  • Transformasi Fourier tradisional menggunakanGelombang sinus yang sangat panjangSeperti penggaris yang panjangnya tak terbatas.
  • Transformasi wavelet digunakanGelombang “kecil” dengan panjang terbatasSeperti seperangkat penggaris dengan panjang yang berbeda.

Masalah dengan menggunakan gelombang sinus untuk menganalisis harga keuangan: Gelombang sinus mengasumsikan bahwa sinyal tersebut berulang secara periodik, tetapi pasar keuangan tidak! BTC mungkin naik 10% hari ini dan turun 8% besok, tanpa siklus sama sekali.

Keunggulan wavelet:Analisis lokalisasiIni dapat memberi tahu Anda “tren harga sebagian besar naik antara pukul 3 sore dan 5 sore pada tanggal 20 Desember 2025”, daripada kesimpulan umum seperti “pasar secara keseluruhan berfluktuasi”.

Rekonstruksi: Dari Dekomposisi ke Rekonstruksi

Transformasi wavelet adalahDapat dibalikIni sangat penting!

Harga asli —> Dekomposisi wavelet —> Komponen tren + Komponen volatilitas + Komponen noise Komponen tren + komponen volatilitas + komponen noise —> rekonstruksi wavelet —> harga asli

Proses refactoringTujuannya adalah untuk menguraikan komponen-komponen individual.Gabungkan kembali secara selektif

  • Komponen tren =[99800, 99850, 99900, 99950, …] # Apa yang kita inginkan
  • Komponen fluktuasi =[+200, -150, +180, -120, …] # Mungkin berguna
  • Komponen kebisingan =[±10, ±15, ±8, ±12, …] # Buang!

Hanya gunakan komponen tren selama rekonstruksi.

Setelah dekomposisi, diperoleh hasil sebagai berikut.

  • Harga yang Direkonstruksi = Komponen Tren + Komponen Volatilitas Parsial

Dalam transaksi sebenarnya, kita biasanyaRekonstruksi hanya bagian frekuensi rendah.(Tren) Komponen frekuensi tinggi (noise) langsung dibuang. Inilah prinsip “pengurangan noise” wavelet.

Prinsip-prinsip Matematika (Versi Sederhana)

Mari kita lewati rumus integral yang rumit dan jelaskan dengan bahasa yang mudah dipahami:

Transformasi wavelet = rata-rata tertimbang dari rangkaian harga menggunakan serangkaian “koefisien wavelet”

Rumus dasar:

Meratakan harga[i] = Σ(harga asli)[i-j] × koefisien wavelet[j]) / Σ(koefisien wavelet)[j])

Perspektif filter

Harga asli disaring melalui filter wavelet → komponen dengan frekuensi berbeda “dipilih”.

Kuncinya adalahPemilihan koefisien wavelet

  • Wavelet yang berbeda = karakteristik filter yang berbeda = respons frekuensi yang berbeda
  • Tingkat yang berbeda = skala waktu yang berbeda = siklus tren yang berbeda

Misalnya

Dengan asumsi Anda menggunakan wavelet Daubechies 4, koefisiennya adalah[0.483, 0.837, 0.224, -0.129]:

Kumpulan koefisien ini mendefinisikan sebuah filter:

  • Koefisien positif (0,483, 0,837, 0,224) → Pertahankan harga untuk posisi ini.
  • Koefisien negatif (-0,129) → Menekan pergerakan harga sebelumnya
  • Pembobotan koefisien → menentukan kontribusi setiap harga.

Transformasi wavelet selesai ketika Anda “menggeser” filter ini di seluruh rangkaian harga. Setiap pergeseran melibatkan perhitungan.Rata-rata tertimbang harga dalam periode waktu saat iniBobot tersebut adalah koefisien wavelet.

Mengapa ia dapat “menguraikan” sinyal?

Karena dapat dibuktikan secara matematis bahwa:Sinyal apa pun dapat direpresentasikan sebagai kombinasi linier dari fungsi basis wavelet.Sama seperti warna apa pun dapat dibuat dengan mencampur tiga warna primer RGB, rangkaian harga apa pun dapat diperoleh dengan menggabungkan fungsi basis wavelet. Berbagai jenis wavelet menyediakan “perpustakaan fungsi basis” yang berbeda, yang cocok untuk berbagai jenis analisis sinyal.


III. Upaya Ini: Aplikasi Praktis dari 7 Transformasi Wavelet

Pendekatan Aplikasi: Penyederhanaan dari Teori ke Praktik

Dalam buku teks pemrosesan sinyal, transformasi wavelet biasanya melibatkan hal-hal yang kompleks…Dekomposisi multi-level, rekonstruksi, dan pengurangan derau ambang batasTangga:

Alur kerja analisis wavelet lengkap:

  1. Dekomposisi multi-skala → menghasilkan koefisien aproksimasi dan koefisien detail.
  2. Ambang batas → Ambang batas lunak/keras untuk koefisien detail guna mengurangi kebisingan
  3. Rekonstruksi transformasi invers → mengembalikan koefisien yang telah diproses ke sinyal.
  4. Perluasan batas → Penanganan efek batas sinyal
  5. Normalisasi energi → memastikan konservasi energi sebelum dan sesudah transformasi

TetapiPenerapan praktis transaksi keuanganDi Tiongkok, kita tidak perlu membuatnya serumit itu. Karena:

1. Trading hanya membutuhkan arah tren; rekonstruksi sempurna tidak diperlukan.

Penelitian akademis mungkin memerlukan kesalahan rekonstruksi kurang dari 0,01%, tetapi dalam perdagangan, hal itu sudah cukup untuk menentukan apakah harga akan naik atau turun. Bahkan jika rekonstruksi memiliki kesalahan 5%, strategi tersebut masih dapat menguntungkan selama arah trennya benar.

2. Persyaratan waktu nyata menyederhanakan perhitungan.

Dekomposisi wavelet lengkap memerlukan perhitungan rekursif dari beberapa lapisan koefisien, yang dapat menyebabkan latensi dalam perdagangan frekuensi tinggi. Konvolusi langsung, di sisi lain, dapat diselesaikan dalam hitungan milidetik, memenuhi kebutuhan perdagangan langsung.

3. Karakteristik Khusus Sinyal Keuangan

Harga keuangan bukanlah sinyal yang stabil dan tidak menunjukkan siklus yang ketat. Dekomposisi frekuensi yang kompleks tidak terlalu berarti di sini; ekstraksi tren sederhana lebih praktis.

Strategi penyederhanaan ini

Oleh karena itu, artikel iniMengekstraksi esensi dari transformasi wavelet.Berfokus pada aspek-aspek paling praktis dari pasar keuangan:

Penyederhanaan Inti 1: Gunakan hanya koefisien perkiraan (tren frekuensi rendah)

Dekomposisi wavelet tradisional → koefisien aproksimasi + koefisien detail (multi-layer) Aplikasi ini: Hanya mempertahankan koefisien perkiraan → langsung mendapatkan tren yang dihaluskan.

Penyederhanaan Inti 2: Konvolusi Langsung, tanpa Pengurangan Derau Ambang Batas

Dekomposisi wavelet tradisional → penentuan ambang batas koefisien detail → rekonstruksi Aplikasi ini: Konvolusi langsung → untuk mendapatkan harga yang dihaluskan

Penyederhanaan Inti 3: Abaikan Pemrosesan Batas

Wavelet tradisional memerlukan pemrosesan seperti perluasan simetris dan perluasan periodik dari batas sinyal. Aplikasi ini hanya berfokus pada bagian tengah; kesalahan pada bagian batas dapat diterima.

Metode implementasi: Konvolusi filter

def convolve(src, coeffs, step):
    """
    核心算法:用小波系数对价格序列做加权平均
    
    src: 价格序列 [100000, 101000, 99000, ...]
    coeffs: 小波系数 [0.483, 0.837, 0.224, -0.129]
    step: 采样步长(用于多层级)
    """
    sum_val = 0.0   # 加权和
    sum_w = 0.0     # 权重和
    
    for i, weight in enumerate(coeffs):
        idx = i * step
        if idx < len(src):
            sum_val += src[idx] * weight
            sum_w += weight
    
    return sum_val / sum_w  # 归一化

Fungsi ini adalah…Inti dari filter wavelet

  • Untuk setiap candlestick, ia melihat ke belakang sebanyak N candlestick (N = jumlah koefisien wavelet).
  • Hitung rata-rata tertimbang menggunakan koefisien wavelet sebagai bobot.
  • Dengan menyesuaikanstepParameter memungkinkan penghalusan multi-level (Level 1/2/3…).

Mengapa penyederhanaan ini masuk akal?

Karena persyaratan penting dari transaksi adalah:Menemukan Tren dalam KebisinganKoefisien aproksimasi transformasi wavelet itu sendiri merupakan “filter lolos rendah” untuk sinyal, yang mempertahankan komponen tren frekuensi rendah, yang正是 apa yang kita butuhkan.

Meskipun analisis wavelet lengkap lebih akurat, dalam perdagangan keuangan:

  • Keuntungan berasal dari arah tren.Hal itu bukan berasal dari keakuratan rekonstruksi.
  • Metode yang lebih sederhana lebih andal.Model yang kompleks rentan terhadap overfitting.
  • Kecepatan perhitungan lebih penting.Dalam perdagangan nyata, setiap milidetik adalah uang.

Akuisisi Data: Kemudahan Platform FMZ

menggunakanMesin pengujian balik lokal dari platform Inventor Quantization (FMZ)Mendapatkan data sangat mudah!

'''backtest
start: 2025-12-17 00:00:00
end: 2025-12-23 08:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT","fee":[0,0]}]
'''
from fmz import *

task = VCtx(__doc__)

def main():
    exchange.SetCurrency("BTC_USDT")
    exchange.SetContractType("swap")
    
    records = exchange.GetRecords(PERIOD_H1, 500)
    return records

records = main()

Tidak diperlukan integrasi API yang kompleks atau pembersihan data; data candlestick standar dapat diperoleh secara langsung. Hal ini memungkinkan kita untuk dengan cepat memverifikasi efek sebenarnya dari tujuh jenis wavelet, daripada terjebak dalam pemrosesan data.

Target uji

Dengan membandingkan kinerja tujuh jenis wavelet umum (Haar, Daubechies 4, Symlet 4, Biorthogonal 3.3, Mexican Hat, Morlet, dan Discrete Meyer) pada harga mata uang kripto, demonstrasi visual berikut disajikan:

  • Perbedaan intensitas penghalusan di antara berbagai wavelet
  • Variasi efek pada level berbeda dari wavelet yang sama
  • Wavelet mana yang cocok untuk trading jangka pendek, dan wavelet mana yang cocok untuk mengikuti tren?

Fokusnya bukanlah pada ketelitian penurunan matematis, tetapi pada perbandingan visual dari hasil praktis.Hal ini membantu para trader mengembangkan pemahaman intuitif dan memilih jenis wavelet yang sesuai dengan strategi mereka.


IV. Penjelasan Detail tentang 7 Jenis Wavelet

1. Haar wavelet - rata-rata paling sederhana

Wavelet Haar adalah jenis wavelet paling dasar, hanya memiliki dua koefisien:[0.5, 0.5]Pada dasarnya, ini adalah rata-rata sederhana dari dua harga yang berdekatan.

Kode inti:

coeffs = [0.5, 0.5]

# 对价格序列 [100000, 101000, 99000, 102000, 98000] 处理
def smooth(prices, i):
    return (prices[i] * 0.5 + prices[i-1] * 0.5) / 1.0

# 结果:[100000, 100500, 100000, 100500, 100000]

Seperti yang Anda lihat, harga yang awalnya berfluktuasi liar (dari 99.000 hingga 102.000) menjadi relatif stabil setelah pemrosesan Haar. Ini adalah efek dari “penghilangan noise” wavelet - menghaluskan fluktuasi jangka pendek yang hebat, memungkinkan Anda untuk melihat tren harga yang lebih halus.

Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet?


2. Daubechies 4 - Umumnya Digunakan dalam Proyek Teknik

Daubechies 4 (disingkat db4) adalah salah satu wavelet yang paling umum digunakan dalam bidang teknik. Koefisiennya adalah:[0.483, 0.837, 0.224, -0.129]Perhatikan bahwa koefisien terakhir adalah…angka negatifItulah yang membuatnya unik.

Kode inti:

coeffs = [0.483, 0.837, 0.224, -0.129]

# 处理第i个价格点
def smooth(prices, i):
    weighted_sum = (prices[i]   * 0.483 +    # 当前价格
                   prices[i-1] * 0.837 +     # 前1根,权重最大!
                   prices[i-2] * 0.224 +     # 前2根
                   prices[i-3] * (-0.129))   # 前3根,负权重
    
    weight_sum = 0.483 + 0.837 + 0.224 + (-0.129)  # = 1.415
    return weighted_sum / weight_sum

# 示例:smooth([100000, 101000, 99000, 102000], 3) ≈ 100251

Fitur Utama:Bobot candlestick sebelumnya (0,837) lebih besar daripada bobot harga saat ini (0,483)! Ini berarti bahwa db4 lebih menekankan pada “harga yang baru saja terjadi”, dan koefisien bobot negatif akan memiliki efek “penyeimbang” pada harga sebelumnya, sehingga semakin meningkatkan kelancaran pergerakan harga.

Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet?


3. Symlet 4 - Versi Simetris yang Ditingkatkan

Symlet 4 adalah versi perbaikan dari Daubechies, yang bertujuan untuk simetri yang lebih baik. Koefisien:[-0.076, -0.030, 0.498, 0.804, 0.298, -0.099, -0.013, 0.032]

Kode inti:

coeffs = [-0.076, -0.030, 0.498, 0.804, 0.298, -0.099, -0.013, 0.032]

# 向前看8根K线
def smooth(prices, i):
    weighted_sum = sum(prices[i-j] * coeffs[j] for j in range(8))
    weight_sum = sum(coeffs)
    return weighted_sum / weight_sum

# 平滑效果比Haar和db4都强,但反应速度更慢

Fitur Utama:Jendela dengan panjang 8 candlestick memungkinkan “memori” harga yang lebih panjang. Pembalikan tren yang sebenarnya mungkin tidak terlihat pada kurva yang mulus hingga setelah 8 candlestick berlalu.

Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet?


4. Biorthogonal 3.3 - Simetri Sempurna

Biorthogonal 3.3 (disingkat sebagai bior3.3) adalah wavelet yang simetris sempurna dengan koefisien:[-0.066, 0.283, 0.637, 0.283, -0.066]

Kode inti:

coeffs = [-0.066, 0.283, 0.637, 0.283, -0.066]
#           ↑              中心↑              ↑
#         完全对称的两端

# 处理中间价格点
def smooth(prices, i):
    # 实际应用:只向前看,不使用未来数据
    weighted_sum = (prices[i-4] * (-0.066) +   # 前4根
                   prices[i-3] * 0.283 +       # 前3根
                   prices[i-2] * 0.637 +       # 前2根,权重最大
                   prices[i-1] * 0.283 +       # 前1根
                   prices[i]   * (-0.066))     # 当前
    
    weight_sum = sum(coeffs)  # = 1.071
    return weighted_sum / weight_sum

Fitur Utama:Simetri memastikan tidak adanya “distorsi fase” - kurva yang dihaluskan tidak akan bergeser ke kiri atau ke kanan tanpa alasan yang jelas.

Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet?


5. Mexican Hat - Turning Point Hunter

Koefisien Mexican Hat (juga disebut wavelet Ricker):[-0.1, 0.0, 0.4, 0.8, 0.4, 0.0, -0.1]Bentuknya seperti topi sombrero Meksiko.

Kode inti:

coeffs = [-0.1, 0.0, 0.4, 0.8, 0.4, 0.0, -0.1]
#         负值  零  正值  最大  正值  零  负值
#         ↓                            ↓
#       "惩罚"两端,增强拐点检测能力

def smooth(prices, i):
    weighted_sum = (prices[i-6] * (-0.1) +     # 左3,负权重
                   prices[i-5] * 0.0 +         # 左2
                   prices[i-4] * 0.4 +         # 左1
                   prices[i-3]   * 0.8 +         # 中心,权重最大
                   prices[i-2] * 0.4 +         # 右1
                   prices[i-1] * 0.0 +         # 右2
                   prices[i] * (-0.1))       # 右3,负权重
    
    weight_sum = sum(coeffs)
    return weighted_sum / weight_sum

Fitur Utama:Struktur “besar di tengah, negatif di kedua ujungnya” membuatnya sangat baik dalam pendeteksian.titik infleksi- Momen kritis ketika harga berbalik dari tren naik menjadi tren turun (atau sebaliknya). Koefisien pembobotan negatif “menghukum” harga yang jauh, dengan cepat menangkap perubahan tren.

Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet?


6. Morlet - Raja Penghalusan Gaussian

Wavelet Morlet didasarkan pada distribusi Gaussian (normal), dengan koefisien:[0.0625, 0.25, 0.375, 0.25, 0.0625]

Kode inti:

coeffs = [0.0625, 0.25, 0.375, 0.25, 0.0625]
#          ↓      ↓      ↓中心   ↓      ↓
#        远端   近端   最高    近端   远端
#         完美的高斯钟形曲线

def smooth(prices, i):
    weighted_sum = (prices[i-4] * 0.0625 +     # 左2,6.25%
                   prices[i-3] * 0.25 +        # 左1,25%
                   prices[i-2]   * 0.375 +       # 中心,37.5%
                   prices[i-1] * 0.25 +        # 右1,25%
                   prices[i] * 0.0625)       # 右2,6.25%
    
    # 权重和正好 = 1.0,无需除法
    return weighted_sum

Fitur Utama:Wavelet ini adalah yang paling “lembut” di antara semua wavelet, tidak memiliki bobot negatif, dan semua harga dimasukkan secara perlahan ke dalam perhitungan. Kurva yang dihasilkan sangat halus, tetapi kekurangannya adalah respons yang lambat – perubahan harga yang tiba-tiba mungkin tidak tercermin hingga beberapa candlestick kemudian.

Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet?


7. Discrete Meyer - Penghalusan Terbaik

Wavelet Meyer diskrit adalah wavelet yang paling kompleks, dengan koefisien:[-0.015, -0.025, 0.0, 0.28, 0.52, 0.28, 0.0, -0.025, -0.015]

Kode inti:

coeffs = [-0.015, -0.025, 0.0, 0.28, 0.52, 0.28, 0.0, -0.025, -0.015]
#           ↑       ↑            ↑    ↑中心↑   ↑            ↑       ↑
#                        完全对称,中心权重超过50%

def smooth(prices, i):
    # 向前看9根K线
    weighted_sum = sum(prices[i-j] * coeffs[j] for j in range(9))
    weight_sum = sum(coeffs)  # = 1.0
    return weighted_sum

# 注意:第4根之前的K线权重是0.52,超过50%!
# 实际上在告诉你"4根K线之前的中期趋势"

Fitur Utama:Ia memiliki koefisien terbanyak (9), data historis terpanjang, dan efek penghalusan terkuat. Ia cocok untuk mengekstrak “tren mingguan,” tetapi ada penundaan yang sangat besar - bahkan jika harga telah turun 10%, kurvanya mungkin masih menunjukkan “terus naik.”

Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet?


5. Mengapa terdapat perbedaan dalam efek penghalusan?

Setelah meninjau tujuh jenis wavelet, Anda seharusnya telah memperhatikan sebuah pola:

Koefisien lebih banyak = lihat lebih lanjut = penghalusan lebih kuat = latensi lebih besar

Haar (2 koefisien) → Hanya melihat 1 batang → Hampir tidak halus Daubechies 4 (4 buah) → Lihat 3 sebelumnya → Sedikit halus Topi Meksiko (7) → Lihat 6 sebelumnya → Penghalusan sedang Meyer Diskrit (9) → Sebelum melihat 8 batang → Penghalusan berat

Efek dari bobot negatif adalah untuk meningkatkan sensitivitas dan mempermudah pendeteksian perubahan.

Haar/Morlet (tanpa bobot negatif) → Lembut dan halus, tidak sensitif Topi Meksiko (negatif di kedua ujung) → Sensitif terhadap titik infleksi Daubechies 4 (negatif) → Sensitif terhadap perubahan tren

Peran simetri = tidak ada distorsi = mempertahankan bentuk asli

Asimetri (Daubechies) → Dapat bergeser ke kiri/kanan Simetri (Biorthogonal/Meyer) → Mempertahankan posisi tengah


VI. Dampak Tingkat Penghalusan

Transformasi wavelet dapat diterapkan secara rekursif, seperti boneka bersarang. Penerapan pertama disebut Level 1, menerapkannya lagi pada hasil Level 1 disebut Level 2, dan seterusnya.

Skala waktu yang terlihat pada berbagai tingkatan:

Dengan asumsi kita menggunakan grafik candlestick 1 jam untuk perdagangan BTC:

Level 1 → Amati fluktuasi jangka pendek selama 2-4 jam Level 2 → Amati tren selama 4-8 jam Level 3 → Amati tren jangka menengah selama 1-2 hari (strategi yang umum digunakan) Level 4 → Amati rentang harga 2-4 hari Level 5 → Amati tren utama selama 4-8 hari

Perbandingan hasil aktual:

Harga BTC asli (grafik 1 jam):99500, 99800, 99200, 100200, 99800, 100500, 100100, ...

Pemrosesan Level 1: 99600, 99650, 99500, 99900, 99950, 100200, 100250, … (Sedikit dihaluskan, tetapi fluktuasi masih terlihat)

Pemrosesan Level 3: 99620, 99650, 99700, 99800, 99950, 100100, 100200, … (Dihaluskan, menunjukkan tren jangka menengah)

Pemrosesan Level 5: 99630, 99640, 99660, 99700, 99760, 99840, 99930, … (Sangat halus, hanya menunjukkan arah umum)

Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet? Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet? Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet? Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet? Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet?

Prinsip pemilihannya sederhana: gunakan Level yang sesuai berdasarkan periode kepemilikan Anda.

Scalping 15 menit → Level 1-2
Perdagangan intraday → Level 2-3
Lakukan latihan ayunan selama beberapa hari → Level 3-4
Analisis tren jangka panjang → Level 4-5


VII. Ide Penerapan Praktis

Penerapan transformasi wavelet dalam perdagangan sangat langsung: gunakan kurva harga yang dihaluskan yang dihasilkannya untuk menentukan arah tren, dan lakukan perdagangan ketika tren berubah. Secara spesifik, jika harga penutupan yang dihaluskan lebih tinggi dari harga sebelumnya, itu menunjukkan tren naik, jadi lakukan posisi beli (long); jika harga penutupan yang dihaluskan lebih rendah dari harga sebelumnya, itu menunjukkan tren turun, jadi tutup posisi atau lakukan posisi jual (short). Logika ini efektif karena wavelet telah menyaring fluktuasi acak jangka pendek, sehingga menyisakan “naik” atau “turun” sebagai probabilitas tinggi dari perubahan tren yang sebenarnya, bukan sinyal palsu yang disebabkan oleh noise.

# 执行小波变换
transformed = transformer.transform_ohlc(df)

# 获取最近两根K线的平滑收盘价
w_close_current = transformed['w_close'].values[-1]  # 当前平滑收盘价
w_close_prev = transformed['w_close'].values[-2]     # 前一根平滑收盘价

# 判断趋势方向
signal = 0
if w_close_current > w_close_prev:
    signal = 1   # 平滑价格向上 → 做多
elif w_close_current < w_close_prev:
    signal = -1  # 平滑价格向下 → 做空

# 获取账户信息
account = exchange.GetAccount()
ticker = exchange.GetTicker()

if not account or not ticker:
    Log("[Warning] Failed to get account/ticker info")
    Sleep(5000)
    continue

current_price = ticker['Last']

Log(f"[Price] 原始: {df['Close'].values[-1]:.2f}, "
    f"平滑当前: {w_close_current:.2f}, 平滑前值: {w_close_prev:.2f}")
Log(f"[Trend] {'↑ 向上' if signal == 1 else '↓ 向下' if signal == -1 else '→ 横盘'}")

# 执行交易逻辑
if signal == 1 and position != 1:
    # 平滑价格向上 → 做多
    Log(f"[信号] 趋势向上,开多 @ {current_price:.2f}")
    
    if position == -1:
        # 先平空仓
        exchange.SetDirection("closesell")
        exchange.Buy(current_price, 1)
        Log(f"[平仓] 平空仓")
    
    # 开多仓
    exchange.SetDirection("buy")
    exchange.Buy(current_price, 1)
    Log(f"[开仓] 开多仓")
    position = 1
    
elif signal == -1 and position != -1:
    # 平滑价格向下 → 做空
    Log(f"[信号] 趋势向下,开空 @ {current_price:.2f}")
    
    if position == 1:
        # 先平多仓
        exchange.SetDirection("closebuy")
        exchange.Sell(current_price, 1)
        Log(f"[平仓] 平多仓")
    
    # 开空仓
    exchange.SetDirection("sell")
    exchange.Sell(current_price, 1)
    Log(f"[开仓] 开空仓")
    position = -1

else:
    Log(f"[持仓] 当前{'多头' if position == 1 else '空头' if position == -1 else '空仓'},无需操作")

Mengungkap Tiga Teknik Esensial Pengolahan Data Keuangan: Apa Sebenarnya Transformasi Wavelet?

Tentu saja, dalam praktiknya, hal itu tidak sesederhana itu. Anda dapat menggunakan beberapa level wavelet secara bersamaan, seperti Level 2 yang menunjukkan tren jangka pendek dan Level 4 yang menunjukkan tren jangka panjang. Buka posisi hanya ketika keduanya bergerak ke arah yang sama, yang secara signifikan mengurangi sinyal palsu. Anda juga dapat menambahkan kondisi penyaringan lainnya, seperti mensyaratkan peningkatan volume perdagangan, volatilitas yang cukup tinggi, atau breakout harga di atas level kunci; semua ini dapat meningkatkan tingkat kemenangan. Untuk order stop-loss, Anda dapat mengaturnya secara dinamis menggunakan rentang fluktuasi harga yang dihaluskan wavelet; misalnya, stop-loss jika harga turun di bawah harga yang dihaluskan dikurangi 2 kali ATR. Dalam manajemen posisi, semakin jelas trennya (semakin curam kemiringan harga yang dihaluskan), semakin besar ukuran posisi; jika trennya tidak jelas, gunakan posisi yang lebih ringan atau tetap berada di luar pasar.

Namun ide intinya tetap sama: gunakan wavelet untuk mengubah harga yang berfluktuasi menjadi tren yang jelas, lalu buat penilaian berdasarkan tren yang jelas tersebut. Ini jauh lebih andal daripada melihat langsung kenaikan dan penurunan pada grafik candlestick asli, karena grafik candlestick asli mungkin naik 3% hari ini, turun 2% besok, dan naik 4% lusa. Anda tidak dapat membedakan apakah itu tren atau fluktuasi. Kurva yang diproses oleh wavelet akan memberi tahu Anda “tren keseluruhan selama periode ini adalah naik, meskipun ada fluktuasi di antaranya”.


VIII. Kesimpulan: Pandangan Rasional tentang “Pendekatan Tiga Arah”

Dalam hal efek penghalusan praktis, transformasi wavelet memang dapat berperan dalam pemrosesan data keuangan: ia dapat menyaring beberapa noise jangka pendek dan membantu mengekstrak informasi tren yang relatif jelas. Namun, teknik ini juga memiliki keterbatasan yang signifikan—Masalah lag tidak dapat dihindari sepenuhnya.Namun, metode ini hanya dapat memproses data historis dan tidak dapat memprediksi tren masa depan. Selain itu, efek penggunaan transformasi wavelet saja relatif terbatas; metode ini perlu dikombinasikan dengan metode analitik lain dan langkah-langkah pengendalian risiko untuk membangun sistem perdagangan yang lengkap.

Alasan utama keterbatasan ini terletak pada sifat unik pasar keuangan. Dalam bidang pemrosesan sinyal tradisional seperti pengenalan suara dan pemrosesan gambar, karakteristik derau relatif stabil, dan pola sinyal cenderung berulang. Oleh karena itu, transformasi wavelet dapat secara efektif memisahkan sinyal dari derau. Namun, pasar keuangan sangat berbeda: fluktuasi yang dianggap “derau” hari ini mungkin menjadi “sinyal” yang mencerminkan perubahan pasar besok; model analitis yang efektif sekarang mungkin menjadi tidak efektif di masa depan.Pasar itu sendiri bersifat tidak statis dan berubah secara dinamis.Tidak ada hukum yang tidak berubah dalam transformasi wavelet, yang mengharuskan penerapan transformasi wavelet di bidang keuangan harus disesuaikan secara fleksibel sesuai dengan lingkungan pasar tertentu.

Ketika Anda melihat seseorang melebih-lebihkan efek sebenarnya dari transformasi wavelet dan transformasi Fourier, cobalah mengajukan pertanyaan-pertanyaan ini: Jenis wavelet apa yang digunakan? Apa dasar pemilihan jenis ini dibandingkan jenis lainnya? Bagaimana tingkat penghalusannya ditetapkan? Apakah ada hasil pengujian balik dan prosedur pemilihan parameter yang sesuai?Mereka yang benar-benar memiliki pengetahuan profesional akan mampu menjelaskan detail teknis penting ini dengan jelas.

Berdasarkan pengetahuan kami yang terbatas, kami melakukan eksplorasi praktis ini.Ide intinya adalah untuk membagikan konsep aplikasi transformasi wavelet dengan cara yang sederhana dan mudah dipahami.Artikel ini bertujuan untuk membantu pembaca memperoleh pemahaman dasar tentang teknologi ini. Kami sangat menghargai para peneliti kuantitatif yang terlibat secara mendalam di bidang ini; jika Anda seorang ahli di bidang ini, Anda dipersilakan untuk menunjukkan kekurangan apa pun dalam artikel ini—seperti dasar teoritis untuk pemilihan parameter wavelet, metode optimasi untuk kombinasi multi-skala, dan jalur implementasi untuk pemilihan wavelet adaptif. Kami akan dengan rendah hati menerima saran Anda dan terus meningkatkan kontennya.

Fungsi plotting: Diterapkan pada mesin backtesting lokal penemu.

'''backtest
start: 2025-12-17 00:00:00
end: 2025-12-23 08:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT","fee":[0,0]}]
'''
from fmz import *
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

task = VCtx(__doc__)

# ==================== 小波系数库 ====================
class WaveletCoefficients:
    """Wavelet Coefficients Definition"""
    
    @staticmethod
    def get_coeffs(wavelet_name):
        """Get coefficients for different wavelet types"""
        coeffs = {
            "Haar": [0.5, 0.5],
            
            "Daubechies 4": [
                0.48296291314453414,
                0.8365163037378079,
                0.22414386804201339,
                -0.12940952255126037
            ],
            
            "Symlet 4": [
                -0.05357, -0.02096, 0.35238,
                0.56833, 0.21062, -0.07007,
                -0.01941, 0.03268
            ],
            
            "Biorthogonal 3.3": [
                -0.06629, 0.28289, 0.63678,
                0.28289, -0.06629
            ],
            
            "Mexican Hat (Ricker)": [
                -0.1, 0.0, 0.4, 0.8, 0.4, 0.0, -0.1
            ],
            
            "Morlet (Gaussian)": [
                0.0625, 0.25, 0.375, 0.25, 0.0625
            ],
            
            "Discrete Meyer (Dmey)": [
                -0.015, -0.025, 0.0,
                0.28, 0.52, 0.28,
                0.0, -0.025, -0.015
            ]
        }
        
        return coeffs.get(wavelet_name, coeffs["Mexican Hat (Ricker)"])


# ==================== 小波变换引擎 ====================
class WaveletTransform:
    """Wavelet Transform Engine"""
    
    def __init__(self, wavelet_type="Mexican Hat (Ricker)", smoothing_level=3):
        self.wavelet_type = wavelet_type
        self.smoothing_level = smoothing_level
        self.coeffs = WaveletCoefficients.get_coeffs(wavelet_type)
    
    def convolve(self, src, coeffs, step):
        """
        Convolution operation - Core algorithm
        
        Args:
            src: Source data sequence
            coeffs: Wavelet coefficients
            step: Sampling step
        
        Returns:
            Convolved value
        """
        sum_val = 0.0
        sum_w = 0.0
        
        for i, weight in enumerate(coeffs):
            idx = i * step
            if idx < len(src):
                val = src[idx]
                sum_val += val * weight
                sum_w += weight
        
        # Normalization - Critical fix
        return sum_val / sum_w if sum_w != 0 else sum_val
    
    def calc_level(self, data, target_level):
        """
        Calculate wavelet transform for specified level
        
        Args:
            data: Original data array
            target_level: Target smoothing level
        
        Returns:
            Transformed data array
        """
        result = []
        coeffs = self.coeffs
        
        for i in range(len(data)):
            # Get data from current position backwards
            src = data[max(0, i - 50):i + 1][::-1]
            
            # Level 1
            val = self.convolve(src, coeffs, 1)
            
            # Level 2
            if target_level >= 2:
                src_temp = [val] + [self.convolve(data[max(0, j - 50):j + 1][::-1], coeffs, 1) 
                                   for j in range(max(0, i - 10), i)][::-1]
                val = self.convolve(src_temp, coeffs, 2)
            
            # Level 3
            if target_level >= 3:
                val = self.convolve([val] * len(coeffs), coeffs, 4)
            
            # Level 4+
            if target_level >= 4:
                val = self.convolve([val] * len(coeffs), coeffs, 8)
            
            result.append(val)
        
        return np.array(result)
    
    def transform_ohlc(self, df):
        """
        Perform wavelet transform on OHLC data
        
        Args:
            df: DataFrame with Open/High/Low/Close
        
        Returns:
            Transformed DataFrame
        """
        result_df = df.copy()
        
        # Transform each price series
        result_df['w_open'] = self.calc_level(df['Open'].values, self.smoothing_level)
        result_df['w_high'] = self.calc_level(df['High'].values, self.smoothing_level)
        result_df['w_low'] = self.calc_level(df['Low'].values, self.smoothing_level)
        result_df['w_close'] = self.calc_level(df['Close'].values, self.smoothing_level)
        
        # Reconstruct logically consistent candlesticks
        result_df['real_high'] = result_df[['w_high', 'w_low', 'w_open', 'w_close']].max(axis=1)
        result_df['real_low'] = result_df[['w_high', 'w_low', 'w_open', 'w_close']].min(axis=1)
        
        return result_df


# ==================== K线图可视化工具 ====================
class WaveletCandlestickVisualizer:
    """Wavelet Candlestick Visualization"""
    
    @staticmethod
    def plot_single_wavelet(df, wavelet_type, smoothing_level=3, n_bars=200):
        """
        Plot single wavelet type comparison
        
        Args:
            df: Original candlestick data
            wavelet_type: Wavelet type
            smoothing_level: Smoothing level
            n_bars: Number of bars to display
        """
        # Take only last n_bars
        df_plot = df.iloc[-n_bars:].copy()
        
        # Create figure
        fig, ax = plt.subplots(figsize=(20, 8))
        
        # Perform wavelet transform
        transformer = WaveletTransform(wavelet_type, smoothing_level)
        transformed = transformer.transform_ohlc(df)
        transformed_plot = transformed.iloc[-n_bars:].copy()
        
        # Draw original candlesticks (gray background)
        WaveletCandlestickVisualizer._draw_candlesticks(
            ax, df_plot, 
            color_up='lightgray', 
            color_down='lightgray',
            alpha=0.3,
            label='Original Candles'
        )
        
        # Draw wavelet smoothed candlesticks
        WaveletCandlestickVisualizer._draw_candlesticks(
            ax, transformed_plot,
            use_wavelet=True,
            color_up='#26A69A',  # Green
            color_down='#EF5350',  # Red
            alpha=0.9,
            linewidth=1.2,
            label=f'{wavelet_type} Smoothed (Level {smoothing_level})'
        )
        
        # Set title and labels
        ax.set_title(f'{wavelet_type} Wavelet (Level {smoothing_level}) - Candlestick Comparison', 
                    fontsize=16, fontweight='bold', pad=20)
        ax.set_ylabel('Price (USDT)', fontsize=13)
        ax.set_xlabel('Time', fontsize=13)
        ax.grid(True, alpha=0.2, linestyle='--')
        ax.legend(loc='upper left', fontsize=12)
        
        # Format x-axis
        ax.set_xlim(-1, len(df_plot))
        ax.set_xticks(range(0, len(df_plot), max(1, len(df_plot) // 10)))
        ax.set_xticklabels([df_plot.index[i].strftime('%m-%d %H:%M') 
                           for i in range(0, len(df_plot), max(1, len(df_plot) // 10))], 
                          rotation=45, ha='right')
        
        plt.tight_layout()
        plt.show()
        return fig
    
    @staticmethod
    def plot_single_level(df, wavelet_type, level, n_bars=200):
        """
        Plot single smoothing level
        
        Args:
            df: Original candlestick data
            wavelet_type: Wavelet type
            level: Smoothing level
            n_bars: Number of bars to display
        """
        # Take only last n_bars
        df_plot = df.iloc[-n_bars:].copy()
        
        # Create figure
        fig, ax = plt.subplots(figsize=(20, 8))
        
        # Perform wavelet transform
        transformer = WaveletTransform(wavelet_type, level)
        transformed = transformer.transform_ohlc(df)
        transformed_plot = transformed.iloc[-n_bars:].copy()
        
        # Draw original candlesticks
        WaveletCandlestickVisualizer._draw_candlesticks(
            ax, df_plot,
            color_up='lightgray',
            color_down='lightgray',
            alpha=0.3,
            label='Original Candles'
        )
        
        # Draw wavelet smoothed candlesticks
        WaveletCandlestickVisualizer._draw_candlesticks(
            ax, transformed_plot,
            use_wavelet=True,
            color_up='#26A69A',
            color_down='#EF5350',
            alpha=0.9,
            linewidth=1.2,
            label=f'Level {level} Smoothed'
        )
        
        # Set title and labels
        ax.set_title(f'{wavelet_type} - Smoothing Level {level} Effect', 
                    fontsize=16, fontweight='bold', pad=20)
        ax.set_ylabel('Price (USDT)', fontsize=13)
        ax.set_xlabel('Time', fontsize=13)
        ax.grid(True, alpha=0.2, linestyle='--')
        ax.legend(loc='upper left', fontsize=12)
        
        # Format x-axis
        ax.set_xlim(-1, len(df_plot))
        ax.set_xticks(range(0, len(df_plot), max(1, len(df_plot) // 10)))
        ax.set_xticklabels([df_plot.index[i].strftime('%m-%d %H:%M') 
                           for i in range(0, len(df_plot), max(1, len(df_plot) // 10))], 
                          rotation=45, ha='right')
        
        plt.tight_layout()
        plt.show()
        return fig
    
    @staticmethod
    def _draw_candlesticks(ax, df, use_wavelet=False, color_up='green', 
                          color_down='red', alpha=1.0, linewidth=1.0, label=''):
        """
        Draw candlestick chart
        
        Args:
            ax: Matplotlib axis
            df: Data DataFrame
            use_wavelet: Whether to use wavelet data
            color_up: Up color
            color_down: Down color
            alpha: Transparency
            linewidth: Line width
            label: Legend label
        """
        if use_wavelet:
            opens = df['w_open'].values
            highs = df['real_high'].values
            lows = df['real_low'].values
            closes = df['w_close'].values
        else:
            opens = df['Open'].values
            highs = df['High'].values
            lows = df['Low'].values
            closes = df['Close'].values
        
        for i in range(len(df)):
            x = i
            open_price = opens[i]
            high_price = highs[i]
            low_price = lows[i]
            close_price = closes[i]
            
            color = color_up if close_price >= open_price else color_down
            
            # Draw wick
            ax.plot([x, x], [low_price, high_price], 
                   color=color, linewidth=linewidth, alpha=alpha)
            
            # Draw body
            height = abs(close_price - open_price)
            bottom = min(open_price, close_price)
            
            rect = Rectangle((x - 0.3, bottom), 0.6, height,
                           facecolor=color, edgecolor=color,
                           alpha=alpha, linewidth=linewidth)
            ax.add_patch(rect)
        
        # Add legend (only once)
        if label:
            ax.plot([], [], color=color_up, linewidth=3, alpha=alpha, label=label)


# ==================== 主函数 ====================
def main():
    """Main execution flow"""
    exchange.SetCurrency("BTC_USDT")
    exchange.SetContractType("swap")
    
    # Get candlestick data
    records = exchange.GetRecords(PERIOD_H1, 500)
    
    # Convert to DataFrame
    df = pd.DataFrame(records, columns=['Time', 'Open', 'High', 'Low', 'Close', 'Volume'])
    df['Time'] = pd.to_datetime(df['Time'], unit='ms')
    df.set_index('Time', inplace=True)
    
    print(f"Data loaded: {len(df)} bars")
    print(f"Time range: {df.index[0]} to {df.index[-1]}")
    print(f"Price range: ${df['Low'].min():.2f} - ${df['High'].max():.2f}")
    
    return df


# ==================== 执行绘图 ====================
try:
    # Get candlestick data
    kline = main()
    
    print("\n" + "="*70)
    print("Generating Wavelet Candlestick Charts (Each in Separate Window)...")
    print("="*70)
    
    # ========== Chart Series 1: Different Wavelet Types ==========
    print("\n[Series 1] Comparing Different Wavelet Types")
    print("-" * 70)
    
    wavelet_types = [
        "Haar",
        "Daubechies 4",
        "Symlet 4",
        "Biorthogonal 3.3",
        "Mexican Hat (Ricker)",
        "Morlet (Gaussian)",
        "Discrete Meyer (Dmey)"  # ✅ 添加了 Discrete Meyer
    ]
    
    for i, wavelet_type in enumerate(wavelet_types, 1):
        print(f"  Chart {i}/{len(wavelet_types)}: {wavelet_type}")
        fig = WaveletCandlestickVisualizer.plot_single_wavelet(
            kline, 
            wavelet_type=wavelet_type,
            smoothing_level=3, 
            n_bars=150
        )
    
    # ========== Chart Series 2: Different Smoothing Levels ==========
    print("\n[Series 2] Comparing Different Smoothing Levels")
    print("-" * 70)
    
    levels = [1, 2, 3, 4, 5]
    
    for i, level in enumerate(levels, 1):
        print(f"  Chart {i}/5: Level {level}")
        fig = WaveletCandlestickVisualizer.plot_single_level(
            kline, 
            wavelet_type="Mexican Hat (Ricker)",
            level=level,
            n_bars=150
        )
    
    print("\n" + "="*70)
    print("All charts generated successfully!")
    print(f"Total charts: {len(wavelet_types) + len(levels)} ({len(wavelet_types)} wavelets + {len(levels)} levels)")
    print("="*70)
    
except Exception as e:
    print(f"Error: {str(e)}")
    import traceback
    print(traceback.format_exc())
finally:
    print("\nStrategy testing completed.")

Fungsi transaksi: Diterapkan pada platform Penemu

'''backtest
start: 2025-01-17 00:00:00
end: 2025-12-23 08:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT","fee":[0,0]}]
'''

import numpy as np
import pandas as pd

# ==================== 小波系数库 ====================
class WaveletCoefficients:
    """与上部分函数一致"""

# ==================== 小波变换引擎 ====================
class WaveletTransform:
    """与上部分函数一致"""
 
def main():
    """小波交易主函数 - 基于平滑价格趋势"""
    
    # ========== 配置参数 ==========
    WAVELET_TYPE = "Mexican Hat (Ricker)"  # 小波类型
    SMOOTHING_LEVEL = 1                     # 平滑阶数
    
    # 初始化
    exchange.SetCurrency("BTC_USDT")
    exchange.SetContractType("swap")
    
    Log(f"=" * 70)
    Log(f"Wavelet Trend Following Strategy")
    Log(f"Wavelet: {WAVELET_TYPE}, Level: {SMOOTHING_LEVEL}")
    Log(f"Logic: 平滑收盘价向上→做多, 平滑收盘价向下→做空")
    Log(f"=" * 70)
    
    # 初始化小波变换器
    transformer = WaveletTransform(WAVELET_TYPE, SMOOTHING_LEVEL)
    
    # 持仓状态
    position = 0  # 0: 无持仓, 1: 多头, -1: 空头
    
    while True:

        # 获取K线数据
        records = exchange.GetRecords(PERIOD_H1, 500)
        if not records:
            Log("[Warning] Failed to get kline data")
            Sleep(5000)
            continue
        
        df = pd.DataFrame(records, columns=['Time', 'Open', 'High', 'Low', 'Close', 'Volume'])
        df['Time'] = pd.to_datetime(df['Time'], unit='ms')
        df.set_index('Time', inplace=True)
        
        # 执行小波变换
        transformed = transformer.transform_ohlc(df)
        
        # 获取最近两根K线的平滑收盘价
        w_close_current = transformed['w_close'].values[-1]  # 当前平滑收盘价
        w_close_prev = transformed['w_close'].values[-2]     # 前一根平滑收盘价
        
        # 判断趋势方向
        signal = 0
        if w_close_current > w_close_prev:
            signal = 1   # 平滑价格向上 → 做多
        elif w_close_current < w_close_prev:
            signal = -1  # 平滑价格向下 → 做空
        
        # 获取账户信息
        account = exchange.GetAccount()
        ticker = exchange.GetTicker()
        
        if not account or not ticker:
            Log("[Warning] Failed to get account/ticker info")
            Sleep(5000)
            continue
        
        current_price = ticker['Last']
        
        Log(f"[Price] 原始: {df['Close'].values[-1]:.2f}, "
            f"平滑当前: {w_close_current:.2f}, 平滑前值: {w_close_prev:.2f}")
        Log(f"[Trend] {'↑ 向上' if signal == 1 else '↓ 向下' if signal == -1 else '→ 横盘'}")
        
        # 执行交易逻辑
        if signal == 1 and position != 1:
            # 平滑价格向上 → 做多
            Log(f"[信号] 趋势向上,开多 @ {current_price:.2f}")
            
            if position == -1:
                # 先平空仓
                exchange.SetDirection("closesell")
                exchange.Buy(current_price, 1)
                Log(f"[平仓] 平空仓")
            
            # 开多仓
            exchange.SetDirection("buy")
            exchange.Buy(current_price, 1)
            Log(f"[开仓] 开多仓")
            position = 1
            
        elif signal == -1 and position != -1:
            # 平滑价格向下 → 做空
            Log(f"[信号] 趋势向下,开空 @ {current_price:.2f}")
            
            if position == 1:
                # 先平多仓
                exchange.SetDirection("closebuy")
                exchange.Sell(current_price, 1)
                Log(f"[平仓] 平多仓")
            
            # 开空仓
            exchange.SetDirection("sell")
            exchange.Sell(current_price, 1)
            Log(f"[开仓] 开空仓")
            position = -1
        
        else:
            Log(f"[持仓] 当前{'多头' if position == 1 else '空头' if position == -1 else '空仓'},无需操作")
        
        Log(f"[账户] 余额: {account['Balance']:.2f}, 权益: {account['Equity']:.2f}")
        Log("-" * 70)
        
        Sleep(60000 * 60)