Biarkan saya mengambil contoh nyata untuk menjawab pertanyaan ini
Saya perlu menghitung rata-rata bergerak tertimbang pada data ohlc saya, saya memiliki sekitar 134.000 lilin dengan simbol untuk masing-masing melakukannya
- Opsi 1 Lakukan dengan Python / Node dll
- Opsi 2 Lakukan dalam SQL itu sendiri!
Mana yang lebih baik?
- Jika saya harus melakukan ini dengan Python, pada dasarnya, saya harus mengambil semua catatan yang disimpan di terburuk, kasus, melakukan perhitungan dan menyimpan semuanya kembali yang menurut saya merupakan pemborosan besar IO
- Perubahan rata-rata bergerak tertimbang setiap kali Anda mendapatkan lilin baru yang berarti saya akan melakukan sejumlah besar IO secara berkala yang bukan pendapat yang baik dalam pertanda saya.
- Dalam SQL, yang harus saya lakukan mungkin adalah menulis pemicu yang menghitung dan menyimpan semuanya jadi hanya perlu mengambil nilai WMA akhir untuk setiap pasangan setiap sekarang dan kemudian dan itu jauh lebih efisien
Persyaratan
- Jika saya harus menghitung WMA untuk setiap lilin dan menyimpannya, saya akan melakukannya dengan Python
- Tetapi karena saya hanya membutuhkan nilai terakhir, SQL jauh lebih cepat daripada Python
Untuk memberi Anda dorongan, ini adalah versi Python untuk melakukan moving average tertimbang
WMA dilakukan melalui kode
import psycopg2
import psycopg2.extras
from talib import func
import timeit
import numpy as np
with psycopg2.connect('dbname=xyz user=xyz') as conn:
with conn.cursor() as cur:
t0 = timeit.default_timer()
cur.execute('select distinct symbol from ohlc_900 order by symbol')
for symbol in cur.fetchall():
cur.execute('select c from ohlc_900 where symbol = %s order by ts', symbol)
ohlc = np.array(cur.fetchall(), dtype = ([('c', 'f8')]))
wma = func.WMA(ohlc['c'], 10)
# print(*symbol, wma[-1])
print(timeit.default_timer() - t0)
conn.close()
WMA Melalui SQL
"""
if the period is 10
then we need 9 previous candles or 15 x 9 = 135 mins on the interval department
we also need to start counting at row number - (count in that group - 10)
For example if AAPL had 134 coins and current row number was 125
weight at that row will be weight = 125 - (134 - 10) = 1
10 period WMA calculations
Row no Weight c
125 1
126 2
127 3
128 4
129 5
130 6
131 7
132 8
133 9
134 10
"""
query2 = """
WITH
condition(sym, maxts, cnt) as (
select symbol, max(ts), count(symbol) from ohlc_900 group by symbol
),
cte as (
select symbol, ts,
case when cnt >= 10 and ts >= maxts - interval '135 mins'
then (row_number() over (partition by symbol order by ts) - (cnt - 10)) * c
else null
end as weighted_close
from ohlc_900
INNER JOIN condition
ON symbol = sym
WINDOW
w as (partition by symbol order by ts rows between 9 preceding and current row)
)
select symbol, sum(weighted_close)/55 as wma
from cte
WHERE weighted_close is NOT NULL
GROUP by symbol ORDER BY symbol
"""
with psycopg2.connect('dbname=xyz user=xyz') as conn:
with conn.cursor() as cur:
t0 = timeit.default_timer()
cur.execute(query2)
# for i in cur.fetchall():
# print(*i)
print(timeit.default_timer() - t0)
conn.close()
Percaya atau tidak, kueri berjalan lebih cepat daripada versi Pure Python dalam melakukan RATA-RATA BERGERAK BERAT !!! Saya selangkah demi selangkah menulis pertanyaan itu, jadi tunggu sebentar dan Anda akan baik-baik saja
Mempercepat
0,42141127300055814 detik Python
0,23801879299935536 detik SQL
Saya memiliki 134.000 catatan OHLC palsu di basis data saya dibagi di antara 1.000 saham sehingga itu adalah contoh di mana SQL dapat mengungguli server aplikasi Anda