ถ้าสามารถพยากรณ์ราคาหุ้นด้วยโมเดล AI ขนาดเล็กที่รันแบบโลคอล ให้ผลลัพธ์ในระดับมิลลิวินาที และไม่ต้องฝึกสอนเพิ่มเติม จะเป็นอย่างไร
การพยากรณ์อนุกรมเวลาโดยทั่วไปมักหมายถึงวิธีเชิงสถิติอย่าง ARIMA สายการประมวลผลด้วยแมชชีนเลิร์นนิง หรือโมเดลที่ฝึกบนชุดข้อมูลเฉพาะ Timestral ตระกูลโมเดลพยากรณ์แบบ open-weight ที่ปล่อยโดย Mistral AI เมื่อวันที่ 15 ตุลาคม 2026 ใช้วิธีที่ต่างออกไป มันทำนายค่าล่วงหน้าจากข้อมูลในอดีตโดยไม่ต้องปรับแต่ง และตามที่ Mistral ระบุ โมเดลขนาดใหญ่สุดของตระกูลนี้อยู่ในอันดับหนึ่งในบรรดาโมเดลแบบ pretrained zero-shot บนเบนช์มาร์กสาธารณะสามชุด
แม้จะมีขนาดเล็ก แต่โมเดลเหล่านี้ให้ความแม่นยำที่แข่งขันได้ในหลายเบนช์มาร์กการพยากรณ์ และสามารถประยุกต์ใช้กับทุกอย่างตั้งแต่ตลาดการเงินไปจนถึงการใช้พลังงานและอุปสงค์ค้าปลีก
ในบทเรียนนี้ จะอธิบายว่า Timestral คืออะไรและทำงานอย่างไร ตั้งค่าการใช้งานแบบโลคอลด้วย Python และ uv และทดสอบกับข้อมูลหุ้น Apple (AAPL) จริง จะสร้างการพยากรณ์แบบเลื่อนหน้าต่างรายวัน เปรียบเทียบกับราคาปิดจริงและเบสไลน์แบบง่าย และแปลงผลทำนายเป็นสัญญาณ ซื้อ ขาย หรือ ถือ นอกจากนี้ยังดูบทเรียนของเราที่ การพยากรณ์อนุกรมเวลาด้วย TimeGPT และ ARIMA สำหรับการพยากรณ์อนุกรมเวลา ได้ด้วย
Mistral Timestral คืออะไร
Timestral เป็นตระกูลโมเดลฐานสำหรับอนุกรมเวลาของ Mistral AI ที่เปิดน้ำหนักโมเดล ออกแบบมาเพื่อการพยากรณ์ทั่วไปที่รวดเร็ว โมเดลฐานสำหรับอนุกรมเวลาจะได้รับการพรีเทรนครั้งเดียวบนชุดอนุกรมเวลาขนาดใหญ่และหลากหลาย จึงสามารถพยากรณ์ข้อมูลที่ไม่เคยเห็นมาก่อนได้
ต่างจากโมเดลพยากรณ์แบบดั้งเดิมที่ต้องฝึกสอนบนชุดข้อมูลเฉพาะ Timestral รองรับ zero-shot forecasting โดยทำนายค่าล่วงหน้าได้โดยตรงจากข้อมูลอดีต โดยไม่ต้องฝึกสอนหรือปรับแต่งเพิ่มเติม
Timestral เป็นทรานส์ฟอร์เมอร์เชิงเหตุและผลแบบแบ่งแพตช์ (patch-based) ที่ฝึกเป็นส่วนใหญ่บนข้อมูลสังเคราะห์ ตามด้วยระยะที่สองบนข้อมูลจริงผสมสังเคราะห์ รองรับข้อมูลราคาหุ้น ความต้องการพลังงาน ยอดขาย และข้อมูลจากเซนเซอร์ Mistral อธิบายสถาปัตยกรรมและการฝึกสอนใน รายงานทางเทคนิค
Mistral ปล่อยโมเดลสี่ขนาด โดยแต่ละขนาดแลกเปลี่ยนกันระหว่างขนาด ความเร็ว และความแม่นยำ:
โมเดล พารามิเตอร์ ขนาดน้ำหนัก (FP32) Timestral-5M 5 ล้าน 21 MB Timestral-28M 28 ล้าน 111 MB Timestral-123M 123 ล้าน 490 MB Timestral-209M 209 ล้าน 837 MB
ตามเบนช์มาร์กที่ Mistral เผยแพร่ Timestral-209M อยู่ในอันดับหนึ่งของโมเดล pretrained และ zero-shot บน GIFT-Eval , TIME และ fev-bench ซึ่งเอาชนะโมเดลขนาดใหญ่กว่าอย่าง TimesFM-3 และ Falcon-2.0 ในการเปรียบเทียบที่รายงานไว้ ทั้งนี้เป็นผลลัพธ์จาก Mistral เองที่ส่งเข้ากระดานผู้นำของ GIFT-Eval และ TIME ควรตรวจสอบกระดานผู้นำเพื่อยืนยันจากแหล่งอิสระ
ความเร็วเป็นข้อได้เปรียบอีกอย่าง บน CPU เซิร์ฟเวอร์มาตรฐานที่มี 8 เธรด Mistral รายงานว่า Timestral-209M พยากรณ์หนึ่งวันล่วงหน้าจากประวัติข้อมูลทุก 15 นาทีเป็นเวลา 3 สัปดาห์ได้ใน 113 มิลลิวินาที และโมเดล 5M ใช้เวลา 17 มิลลิวินาที โดยไม่ต้องใช้ GPU
Timestral รองรับคุณสมบัติการพยากรณ์เหล่านี้:
บริบทประวัติยาว: รับอินพุตประวัติได้สูงสุด 32,768 ขั้นเวลา
การพยากรณ์แบบหลายตัวแปร: พยากรณ์อนุกรมเวลาที่เกี่ยวข้องหลายชุดร่วมกันเพื่อปรับปรุงการทำนาย
การทำนายเชิงความน่าจะเป็น: ส่งคืนควอนไทล์ 21 ค่าเพื่อประมาณความไม่แน่นอนของการพยากรณ์ แทนที่จะให้ค่าเดียว
ตัวแปรประกอบ (covariates): รับตัวแปรที่มีเฉพาะอดีตและที่ทราบล่วงหน้า ทั้งเชิงตัวเลขหรือเชิงกลุ่ม ที่อาจมีอิทธิพลต่อการพยากรณ์
รันแบบโลคอล: ทำงานบน CPU และ GPU โดยไม่ต้องใช้ API แบบเสียเงิน โค้ดเปิดภายใต้ Apache 2.0 และน้ำหนักโมเดลภายใต้ไลเซนส์ MIT ที่ปรับแก้
ในบทเรียนนี้ จะใช้ Timestral-209M ซึ่งตามเบนช์มาร์กของ Mistral เป็นโมเดลที่ใหญ่และแม่นยำที่สุดในตระกูล จะรันแบบโลคอลบน NVIDIA RTX 4070 GPU เพื่อพยากรณ์ราคาหุ้นและประเมินประสิทธิภาพกับข้อมูลตลาดจริง
ตั้งค่า Timestral บน Linux
Timestral ต้องใช้ Python 3.10 ขึ้นไป และ PyTorch 2.4 ขึ้นไป ที่นี่จะใช้ Python 3.12, PyTorch 2.7.0 และ uv เพื่อสร้างสภาพแวดล้อมพัฒนาแบบเบา ๆ บนเครื่อง Linux Timestral รองรับการรันบน CPU ด้วย ดังนั้น GPU เป็นตัวเลือก
ก่อนอื่น ตรวจสอบว่า NVIDIA GPU ถูกตรวจพบและไดรเวอร์ทำงานปกติ:
nvidia-smiขับเคลื่อนโดย
ต่อไป ติดตั้ง uv ตัวจัดการแพ็กเกจและสภาพแวดล้อม Python ที่รวดเร็ว:
curl -LsSf https://astral.sh/uv/install.sh | sh ขับเคลื่อนโดย
เริ่มต้นเทอร์มินัลใหม่หลังติดตั้ง uv เพื่อให้คำสั่งพร้อมใช้งานในเชลล์
ตอนนี้สร้างไดเรกทอรีโปรเจกต์และสภาพแวดล้อมเสมือน Python 3.12:
mkdir timestral-project
cd timestral-project
uv venv --python 3.12
source .venv/bin/activateขับเคลื่อนโดย
ถัดไป ติดตั้ง PyTorch 2.7.0 ที่รองรับ CUDA 12.6:
uv pip install torch == 2.7 .0 \
--index-url https://download.pytorch.org/whl/cu126ขับเคลื่อนโดย
ระหว่างการทดสอบ บิลด์ CUDA 12.8 เกิดข้อผิดพลาดความเข้ากันได้ของไดรเวอร์บน RTX 4070 ของเรา การสลับเป็น PyTorch 2.7.0 พร้อม CUDA 12.6 ช่วยแก้ปัญหาได้โดยไม่ต้องอัปเดตไดรเวอร์ ทั้งนี้ขึ้นกับ GPU และไดรเวอร์ NVIDIA อาจต้องใช้บิลด์ CUDA อื่น
หากไม่มี GPU ให้ติดตั้งบิลด์สำหรับ CPU โดยเปลี่ยน index URL เป็น https://download.pytorch.org/whl/cpu โค้ดถัดไปในบทเรียนนี้จะย้อนกลับไปใช้ CPU โดยอัตโนมัติ
ตอนนี้ติดตั้ง Timestral โดยตรงจาก GitHub อย่างเป็นทางการ :
uv pip install git+https://github.com/mistralai/timestral.gitขับเคลื่อนโดย
ติดตั้งไลบรารีที่เหลือสำหรับดาวน์โหลดข้อมูลตลาดหุ้น ประมวลผลผลทำนาย สร้างภาพ และรันโน้ตบุ๊ก:
uv pip install numpy "pandas>=2.2,<3.1" matplotlib \
yfinance jupyterlab ipykernel tqdmขับเคลื่อนโดย
ใช้ yfinance เพื่อดึงราคาหุ้นย้อนหลัง pandas และ NumPy สำหรับประมวลผลข้อมูล และ Matplotlib สำหรับพล็อตราคา จริงเทียบกับที่ทำนาย อีกทั้งจำกัดเวอร์ชัน pandas ให้อยู่ในช่วงที่ทดสอบเพื่อหลีกเลี่ยงคำเตือนด้านความเข้ากันได้
ก่อนดำเนินการต่อ ตรวจสอบว่า PyTorch เข้าถึง GPU ได้:
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'No CUDA GPU available')" ขับเคลื่อนโดย
เอาต์พุตของเรา:
2.7.0+cu126
True
NVIDIA GeForce RTX 4070ขับเคลื่อนโดย
ค่า True ยืนยันว่า PyTorch ใช้ CUDA ได้ และบรรทัดสุดท้ายระบุชื่อ GPU พร้อมสำหรับเริ่มทดลองใช้ Timestral แล้ว
แทนการใช้สคริปต์ Python แยก จะใช้ JupyterLab เพื่อรันโค้ดทีละส่วน ตรวจสอบค่าพยากรณ์ และเปรียบเทียบผลกับข้อมูลตลาดจริง เปิด JupyterLab จากไดเรกทอรีโปรเจกต์:
python -m jupyter labขับเคลื่อนโดย
เปิด URL ที่ปรากฏในเทอร์มินัล โดยทั่วไปคือ http://localhost:8888/lab และสร้างโน้ตบุ๊ก Python ใหม่โดยใช้สภาพแวดล้อมที่เพิ่งตั้งค่า จะใช้โน้ตบุ๊กนี้ในการโหลด Timestral สร้างการพยากรณ์ และประเมินประสิทธิภาพของโมเดล
พยากรณ์ราคาหุ้น Apple ด้วย Timestral
แทนที่จะสร้างข้อมูลสังเคราะห์ จะใช้ราคาหุ้น Apple ย้อนหลังจริง และวัดความแม่นยำของ Timestral ในการทำนายราคาปิดของวันทำการถัดไป
เพื่อให้การทดลองสมจริงขึ้น จะใช้ การพยากรณ์แบบเลื่อนหน้าต่างหนึ่งวัน สำหรับทุกวันทำการในช่วงทดสอบ Timestral จะได้รับราคาปิด 500 ค่าในอดีตก่อนหน้า และทำนายเฉพาะราคาปิดของวันถัดไป
จะเปรียบเทียบสองวิธี:
พยากรณ์ราคาดิบ: ทำนายราคาปิดถัดไปโดยตรง
พยากรณ์อัตราผลตอบแทนแบบลอการิทึม: ทำนายการเปลี่ยนแปลงของลอการิทึมของราคาในวันถัดไป แล้วแปลงกลับเป็นราคาปิด
1. ดาวน์โหลดราคาหุ้นย้อนหลัง
เริ่มโน้ตบุ๊กและนำเข้าไลบรารีที่ต้องใช้ กำหนดสัญลักษณ์ หุ้น จำนวนวันทดสอบ หน้าต่างบริบท และชื่อโมเดล
import numpy as np
import pandas as pd
import torch
import yfinance as yf
import matplotlib. pyplot as plt
from tqdm. auto import tqdm
from IPython. display import display
from timestral import TimestralForecaster
TICKER = "AAPL"
DAYS = 60
WINDOW = 500
MODEL = "mistralai/Timestral-209M" ขับเคลื่อนโดย
ตอนนี้ดาวน์โหลดข้อมูลรายวันของหุ้น Apple ระยะเวลา 5 ปี การตั้งค่า auto_adjust=True จะคืนค่าราคาปิดที่ปรับด้วยการแตกพาร์และปันผลแล้ว
data = yf. download(
TICKER,
period= "5y" ,
interval= "1d" ,
auto_adjust= True ,
multi_level_index= False ,
progress= False ,
)
close = data[ "Close" ] . dropna( ) . astype( float )
assert len ( close) >= WINDOW + DAYS
assert ( close > 0 ) . all ( )
display( data. tail( ) ) ขับเคลื่อนโดย
ใช้ช่วง 60 วันทำการสุดท้ายเป็นการทดสอบ และใช้ข้อมูลสังเกตการณ์ 500 ค่าก่อนหน้าเป็นบริบทสำหรับแต่ละการทำนาย
2. โหลด Timestral ลงบน GPU
โหลดโมเดล 209M ลงบน GPU พร้อมทางเลือกสำรองเป็น CPU หากไม่มี CUDA น้ำหนักขนาด 837 MB จะดาวน์โหลดจาก Hugging Face เมื่อรันเซลล์นี้ครั้งแรก
device = "cuda" if torch. cuda. is_available( ) else "cpu"
model = TimestralForecaster. from_pretrained(
MODEL,
device= device,
)
print ( f"Loaded { MODEL} on { device} " ) ขับเคลื่อนโดย
โมเดลของเราถูกโหลดสำเร็จบน RTX 4070:
Loaded mistralai/Timestral-209M on cudaขับเคลื่อนโดย
3. สร้างการพยากรณ์แบบเลื่อนหน้าต่างหนึ่งวัน
ต่อไปจะสร้างการทำนายสองชุดสำหรับแต่ละวันทำการ: ชุดหนึ่งจากราคาปิดในอดีต และอีกชุดจากอัตราผลตอบแทนแบบลอการิทึม อัตราผลตอบแทนแบบลอการิทึมคือการเปลี่ยนแปลงรายวันของลอการิทึมของราคา และจะแปลงผลทำนายกลับเป็นราคาด้วยการใช้ราคาปิดก่อนหน้า
actual = [ ]
price_predictions = [ ]
return_predictions = [ ]
previous_prices = [ ]
lower_bounds = [ ]
upper_bounds = [ ]
dates = [ ]
for i in tqdm( range ( DAYS) , desc= "Forecasting" ) :
pos = len ( close) - DAYS + i
history = close. iloc[ pos - WINDOW: pos] . to_numpy( dtype= np. float32)
previous = float ( history[ - 1 ] )
with torch. inference_mode( ) :
price_fc = model. forecast(
history,
prediction_length= 1 ,
)
price_pred = float ( price_fc. median. squeeze( ) )
returns = np. diff( np. log( history) )
return_fc = model. forecast(
returns. astype( np. float32) ,
prediction_length= 1 ,
)
return_pred = previous * np. exp(
float ( return_fc. median. squeeze( ) )
)
actual. append( float ( close. iloc[ pos] ) )
previous_prices. append( previous)
price_predictions. append( price_pred)
return_predictions. append( return_pred)
lower_bounds. append( float ( price_fc. quantile( 0.1 ) . squeeze( ) ) )
upper_bounds. append( float ( price_fc. quantile( 0.9 ) . squeeze( ) ) )
dates. append( close. index[ pos] )
actual = np. array( actual)
previous_prices = np. array( previous_prices)
price_predictions = np. array( price_predictions)
return_predictions = np. array( return_predictions)
lower_bounds = np. array( lower_bounds)
upper_bounds = np. array( upper_bounds)
results = pd. DataFrame( {
"Previous Close" : previous_prices,
"Actual" : actual,
"Raw Prediction" : price_predictions,
"Return Prediction" : return_predictions,
"Lower 10%" : lower_bounds,
"Upper 90%" : upper_bounds,
} , index= pd. DatetimeIndex( dates, name= "Date" ) )
display( results. tail( ) ) ขับเคลื่อนโดย
โมเดลจะสร้างการพยากรณ์รายวันแบบเลื่อนหน้าต่าง 60 ครั้ง โดยใช้ราคาปิด 500 ค่าก่อนหน้าสำหรับแต่ละครั้ง แต่ละการพยากรณ์ใช้เฉพาะข้อมูลที่มีอยู่ก่อนวันเป้าหมาย จึงไม่เกิดการรั่วไหลของข้อมูลอนาคตเข้าสู่อินพุตของโมเดล
4. ประเมินความแม่นยำของการพยากรณ์
จะวัดค่า mean absolute error (MAE), root mean squared error (RMSE), mean absolute percentage error (MAPE) และความแม่นยำของทิศทาง นอกจากนี้จะเปรียบเทียบ Timestral กับเบสไลน์แบบง่ายที่สมมติว่าราคาปิดของวันพรุ่งนี้เท่ากับของวันนี้
actual = results[ "Actual" ] . to_numpy( )
previous = results[ "Previous Close" ] . to_numpy( )
raw = results[ "Raw Prediction" ] . to_numpy( )
ret = results[ "Return Prediction" ] . to_numpy( )
def evaluate ( prediction, baseline= False ) :
metrics = {
"MAE ($)" : np. mean( np. abs ( actual - prediction) ) ,
"RMSE ($)" : np. sqrt( np. mean( ( actual - prediction) ** 2 ) ) ,
"MAPE (%)" : np. mean( np. abs ( ( actual - prediction) / actual) ) * 100 ,
}
metrics[ "Direction (%)" ] = (
np. nan if baseline
else np. mean( np. sign( actual - previous) == np. sign( prediction - previous) ) * 100
)
return metrics
metrics = pd. DataFrame( {
"Baseline" : evaluate( previous, baseline= True ) ,
"Raw Prices" : evaluate( raw) ,
"Log Returns" : evaluate( ret) ,
} ) . T
coverage = (
( actual >= results[ "Lower 10%" ] . to_numpy( ) )
& ( actual <= results[ "Upper 90%" ] . to_numpy( ) )
) . mean( ) * 100
display( metrics. round ( 2 ) )
print ( f"Raw-price 10-90% interval coverage: { coverage: .1f } %" ) ขับเคลื่อนโดย
ผลลัพธ์ของเราชี้ว่า Timestral ทำได้ดีกว่าเล็กน้อยเมื่อพยากรณ์อัตราผลตอบแทนลอการิทึมแทนที่จะเป็นราคาหุ้นดิบ
วิธีแบบลอกรับผลตอบแทนได้ค่า MAE ($3.05), RMSE ($3.84) และ MAPE (0.93%) ต่ำที่สุด เหนือกว่าเบสไลน์ของเราเล็กน้อย
ที่สำคัญยิ่งกว่า ความแม่นยำด้านทิศทางเพิ่มจาก 41.67% สำหรับราคาดิบ เป็น 55% สำหรับอัตราผลตอบแทนลอการิทึม บ่งชี้ว่าทำนายได้ดีกว่าในแง่ราคาจะขึ้นหรือลง
โมเดลราคาดิบยังให้ความครอบคลุมของช่วงคาดการณ์ 10-90% ที่ 81.7% ใกล้เคียงกับที่คาดไว้ 80% สะท้อนว่าประมาณค่าความไม่แน่นอนค่อนข้างเที่ยงตรง โดยรวม Timestral ให้การพยากรณ์ราคาที่ค่อนข้างแม่นยำ แต่ความเหนือกว่าเบสไลน์อย่างง่ายมีน้อย และยังต้องทดสอบต่อไปเพื่อดูว่าผลทำนายสามารถสนับสนุนการตัดสินใจซื้อขายได้อย่างน่าเชื่อถือหรือไม่
5. แสดงภาพการทำนายของ Timestral
มาพล็อตราคาปิดจริงเทียบกับทั้งสองวิธีการพยากรณ์ด้วย Matplotlib
fig, axes = plt. subplots(
2 , 1 ,
figsize= ( 14 , 9 ) ,
gridspec_kw= { "height_ratios" : [ 2 , 1 ] } ,
sharex= True ,
)
axes[ 0 ] . plot(
dates, actual,
label= "Actual Price" ,
color= "green" ,
linewidth= 2.5 ,
)
axes[ 0 ] . plot(
dates, price_predictions,
label= "Timestral Raw Price" ,
color= "orange" ,
linestyle= "--" ,
)
axes[ 0 ] . plot(
dates, return_predictions,
label= "Timestral Log Returns" ,
color= "royalblue" ,
linestyle= "--" ,
)
axes[ 0 ] . fill_between(
dates,
lower_bounds,
upper_bounds,
color= "orange" ,
alpha= 0.12 ,
label= "10-90% Forecast Range" ,
)
axes[ 0 ] . set_title( f"Timestral-209M | { TICKER} Rolling One-Day Forecast" )
axes[ 0 ] . set_ylabel( "Adjusted Close (USD)" )
axes[ 0 ] . legend( )
axes[ 0 ] . grid( alpha= 0.2 )
axes[ 1 ] . plot(
dates,
price_predictions - actual,
label= "Raw Price Error" ,
color= "orange" ,
)
axes[ 1 ] . plot(
dates,
return_predictions - actual,
label= "Log Return Error" ,
color= "royalblue" ,
)
axes[ 1 ] . axhline( 0 , color= "black" , linestyle= ":" )
axes[ 1 ] . set_ylabel( "Error ($)" )
axes[ 1 ] . set_xlabel( "Date" )
axes[ 1 ] . legend( )
axes[ 1 ] . grid( alpha= 0.2 )
fig. autofmt_xdate( )
plt. tight_layout( )
fig. savefig( "aapl_improved.png" , dpi= 180 , bbox_inches= "tight" )
plt. show( ) ขับเคลื่อนโดย
กราฟแสดงว่า Timestral ติดตามราคาจริงของ Apple ได้ใกล้เคียงในช่วง 60 วันทำการ ทั้งสองวิธีจับแนวโน้มขาขึ้นได้ ส่วนพื้นที่สีส้มเงาคือช่วงคาดการณ์ 10-90% ของโมเดลราคาดิบ แผงล่างพล็อตข้อผิดพลาดของการทำนายรายวัน
ข้อผิดพลาดส่วนใหญ่อยู่ในช่วงประมาณ $5 โดยมีพลาดมากกว่าบางวันในช่วง $9 ถึง $11 ระหว่างที่ราคาขยับแรง ทั้งสองวิธีให้ผลเกือบเหมือนกัน โดยอัตราผลตอบแทนลอการิทึมนำเล็กน้อย เส้นพยากรณ์ทั้งสองยังตามหลังราคาจริงอยู่ราวหนึ่งวัน ซึ่งสอดคล้องกับช่องว่างที่เล็กมากเมื่อเทียบกับเบสไลน์แบบง่าย
6. สร้างสัญญาณ ซื้อ ถือ และ ขาย
ตอนนี้จะแปลงการทำนายราคาดิบเป็นสัญญาณ ซื้อ ถือ และ ขาย เพื่อการทดลอง ใช้เกณฑ์ 1% ของการเปลี่ยนแปลงราคาที่ทำนายได้:
BUY: คาดว่าราคาเพิ่มขึ้นมากกว่า 1%
SELL: คาดว่าราคาลดลงมากกว่า 1%
HOLD: คาดว่าการเคลื่อนไหวราคาอยู่ระหว่าง -1% ถึง +1%
สามารถเขียนกฎเหล่านี้ด้วย NumPy ได้ดังนี้:
THRESHOLD = 1.0
change_pct = (
price_predictions / previous_prices - 1
) * 100
signals = np. where(
change_pct > THRESHOLD,
"BUY" ,
np. where( change_pct < - THRESHOLD, "SELL" , "HOLD" ) ,
)
results[ "Expected Change (%)" ] = change_pct
results[ "Signal" ] = signals
display( results. tail( 10 ) . round ( 2 ) )
display( results[ "Signal" ] . value_counts( ) )
results. to_csv( "aapl_signals.csv" ) ขับเคลื่อนโดย
ทั้ง 60 วันทำการให้สัญญาณ HOLD โดยไม่มีคำแนะนำ BUY หรือ SELL ใน 10 แถวสุดท้ายที่แสดง การเปลี่ยนแปลงที่คาดไว้ไม่เคยเกิน 0.15% ไปในทิศทางใดทิศทางหนึ่ง ซึ่งต่ำกว่าเกณฑ์ 1% ของเรามาก
สัญญาณเหล่านี้มาจากการทำนายราคาดิบ ซึ่งมีความแม่นยำด้านทิศทางที่อ่อนกว่า (41.67%) หากต้องการดูสัญญาณจากการพยากรณ์อัตราผลตอบแทนลอการิทึม ให้สลับ price_predictions เป็น return_predictions ในการคำนวณ change_pct การลดเกณฑ์จะให้สัญญาณ BUY และ SELL มากขึ้น แต่ก็ไวต่อความผิดพลาดของการพยากรณ์และสัญญาณรบกวนของตลาดมากขึ้นด้วย
สัญญาณเหล่านี้มีไว้เพื่อการทดลอง ไม่ใช่เพื่อการเทรดจริง และไม่มีส่วนใดในบทเรียนนี้เป็นคำแนะนำด้านการเงิน การทดสอบย้อนหลังเพิ่มเติม การปรับเกณฑ์ และการวิเคราะห์ต้นทุนธุรกรรมเป็นสิ่งจำเป็นเพื่อตรวจสอบว่าสามารถสนับสนุนกลยุทธ์ที่ทำกำไรได้หรือไม่
ข้อคิดส่งท้าย
โดยรวมแล้ว ประทับใจกับ Timestral มาก
การตั้งค่าทั้งหมดทำได้ไม่ยุ่งยาก อินเฟอเรนซ์รวดเร็ว และสามารถรันทุกอย่างแบบโลคอลบน RTX 4070 โดยไม่ต้องพึ่งพา API ภายนอก
ที่ทำให้น่าสนใจยิ่งขึ้นคือโมเดลขนาดเบาเหล่านี้ยังรันบน CPU ได้ ทำให้เข้าถึงได้โดยไม่ต้องใช้ฮาร์ดแวร์ราคาแพง
ในแง่ความแม่นยำในการพยากรณ์ ผลลัพธ์ของเราออกมาก้ำกึ่ง
Timestral ติดตามราคาหุ้นได้สมเหตุสมผล แต่แทบไม่เหนือกว่าเบสไลน์อย่างง่าย
ไม่ใช่ผู้เชี่ยวชาญด้านการพยากรณ์ทางการเงินหรือการเทรด ดังนั้นอาจยังทำได้มากกว่านี้ในเรื่องการเตรียมข้อมูล กลยุทธ์การพยากรณ์ และการจูนพารามิเตอร์เพื่อให้ได้ผลลัพธ์ที่ดีกว่า
ก่อนหน้านี้เคยใช้บริการพยากรณ์แบบโฮสต์อย่าง TimeGPT แต่ Timestral ทำให้การพยากรณ์แบบโลคอลน่าสนใจยิ่งขึ้น ตั้งแต่มีการปล่อยโมเดลนี้ ได้เริ่มย้ายงานพยากรณ์จำนวนมากขึ้นไปใช้โมเดลแบบโลคอล เพราะรวดเร็ว ขนาดเล็ก และไม่ต้องมี API หรือค่าบริการตามการใช้งาน
สำหรับเราแล้ว จุดแข็งที่ใหญ่ที่สุดของ Timestral ไม่ใช่แค่ความแม่นยำ แต่คือความง่ายและต้นทุนที่ต่ำในการทำพยากรณ์
สามารถรันโมเดลอนุกรมเวลาที่มีศักยภาพบนฮาร์ดแวร์ของตัวเอง ทดลองได้อย่างอิสระ และฝังเข้าในแอปพลิเคชันได้โดยไม่ต้องพึ่งพาบริการภายนอก แม้ว่าการทำนายหุ้นของเราจะไม่โดดเด่น คิดว่า Timestral เป็นตัวเลือกที่ยอดเยี่ยมสำหรับผู้ที่กำลังสร้างแอปพยากรณ์แบบโลคอล
หากสนใจเรียนรู้เรื่องการพยากรณ์เพิ่มเติม แนะนำคอร์ส Time Series Analysis in Python สำหรับโมเดลเฉพาะด้านการเงิน ลองดู Machine Learning for Finance in Python
ถ้าสามารถพยากรณ์ราคาหุ้นด้วยโมเดล AI ขนาดเล็กที่รันแบบโลคอล ให้ผลลัพธ์ในระดับมิลลิวินาที และไม่ต้องฝึกสอนเพิ่มเติม จะเป็นอย่างไร
การพยากรณ์อนุกรมเวลาโดยทั่วไปมักหมายถึงวิธีเชิงสถิติอย่าง ARIMA สายการประมวลผลด้วยแมชชีนเลิร์นนิง หรือโมเดลที่ฝึกบนชุดข้อมูลเฉพาะ Timestral ตระกูลโมเดลพยากรณ์แบบ open-weight ที่ปล่อยโดย Mistral AI เมื่อวันที่ 15 ตุลาคม 2026 ใช้วิธีที่ต่างออกไป มันทำนายค่าล่วงหน้าจากข้อมูลในอดีตโดยไม่ต้องปรับแต่ง และตามที่ Mistral ระบุ โมเดลขนาดใหญ่สุดของตระกูลนี้อยู่ในอันดับหนึ่งในบรรดาโมเดลแบบ pretrained zero-shot บนเบนช์มาร์กสาธารณะสามชุด
แม้จะมีขนาดเล็ก แต่โมเดลเหล่านี้ให้ความแม่นยำที่แข่งขันได้ในหลายเบนช์มาร์กการพยากรณ์ และสามารถประยุกต์ใช้กับทุกอย่างตั้งแต่ตลาดการเงินไปจนถึงการใช้พลังงานและอุปสงค์ค้าปลีก
ในบทเรียนนี้ จะอธิบายว่า Timestral คืออะไรและทำงานอย่างไร ตั้งค่าการใช้งานแบบโลคอลด้วย Python และ uv และทดสอบกับข้อมูลหุ้น Apple (AAPL) จริง จะสร้างการพยากรณ์แบบเลื่อนหน้าต่างรายวัน เปรียบเทียบกับราคาปิดจริงและเบสไลน์แบบง่าย และแปลงผลทำนายเป็นสัญญาณ ซื้อ ขาย หรือ ถือ นอกจากนี้ยังดูบทเรียนของเราที่ การพยากรณ์อนุกรมเวลาด้วย TimeGPT และ ARIMA สำหรับการพยากรณ์อนุกรมเวลา ได้ด้วย
Mistral Timestral คืออะไร
Timestral เป็นตระกูลโมเดลฐานสำหรับอนุกรมเวลาของ Mistral AI ที่เปิดน้ำหนักโมเดล ออกแบบมาเพื่อการพยากรณ์ทั่วไปที่รวดเร็ว โมเดลฐานสำหรับอนุกรมเวลาจะได้รับการพรีเทรนครั้งเดียวบนชุดอนุกรมเวลาขนาดใหญ่และหลากหลาย จึงสามารถพยากรณ์ข้อมูลที่ไม่เคยเห็นมาก่อนได้
ต่างจากโมเดลพยากรณ์แบบดั้งเดิมที่ต้องฝึกสอนบนชุดข้อมูลเฉพาะ Timestral รองรับ zero-shot forecasting โดยทำนายค่าล่วงหน้าได้โดยตรงจากข้อมูลอดีต โดยไม่ต้องฝึกสอนหรือปรับแต่งเพิ่มเติม
Timestral เป็นทรานส์ฟอร์เมอร์เชิงเหตุและผลแบบแบ่งแพตช์ (patch-based) ที่ฝึกเป็นส่วนใหญ่บนข้อมูลสังเคราะห์ ตามด้วยระยะที่สองบนข้อมูลจริงผสมสังเคราะห์ รองรับข้อมูลราคาหุ้น ความต้องการพลังงาน ยอดขาย และข้อมูลจากเซนเซอร์ Mistral อธิบายสถาปัตยกรรมและการฝึกสอนใน รายงานทางเทคนิค
Mistral ปล่อยโมเดลสี่ขนาด โดยแต่ละขนาดแลกเปลี่ยนกันระหว่างขนาด ความเร็ว และความแม่นยำ:
ตามเบนช์มาร์กที่ Mistral เผยแพร่ Timestral-209M อยู่ในอันดับหนึ่งของโมเดล pretrained และ zero-shot บน GIFT-Eval, TIME และ fev-bench ซึ่งเอาชนะโมเดลขนาดใหญ่กว่าอย่าง TimesFM-3 และ Falcon-2.0 ในการเปรียบเทียบที่รายงานไว้ ทั้งนี้เป็นผลลัพธ์จาก Mistral เองที่ส่งเข้ากระดานผู้นำของ GIFT-Eval และ TIME ควรตรวจสอบกระดานผู้นำเพื่อยืนยันจากแหล่งอิสระ
ความเร็วเป็นข้อได้เปรียบอีกอย่าง บน CPU เซิร์ฟเวอร์มาตรฐานที่มี 8 เธรด Mistral รายงานว่า Timestral-209M พยากรณ์หนึ่งวันล่วงหน้าจากประวัติข้อมูลทุก 15 นาทีเป็นเวลา 3 สัปดาห์ได้ใน 113 มิลลิวินาที และโมเดล 5M ใช้เวลา 17 มิลลิวินาที โดยไม่ต้องใช้ GPU
Timestral รองรับคุณสมบัติการพยากรณ์เหล่านี้:
ในบทเรียนนี้ จะใช้ Timestral-209M ซึ่งตามเบนช์มาร์กของ Mistral เป็นโมเดลที่ใหญ่และแม่นยำที่สุดในตระกูล จะรันแบบโลคอลบน NVIDIA RTX 4070 GPU เพื่อพยากรณ์ราคาหุ้นและประเมินประสิทธิภาพกับข้อมูลตลาดจริง
ตั้งค่า Timestral บน Linux
Timestral ต้องใช้ Python 3.10 ขึ้นไป และ PyTorch 2.4 ขึ้นไป ที่นี่จะใช้ Python 3.12, PyTorch 2.7.0 และ uv เพื่อสร้างสภาพแวดล้อมพัฒนาแบบเบา ๆ บนเครื่อง Linux Timestral รองรับการรันบน CPU ด้วย ดังนั้น GPU เป็นตัวเลือก
ก่อนอื่น ตรวจสอบว่า NVIDIA GPU ถูกตรวจพบและไดรเวอร์ทำงานปกติ:
ต่อไป ติดตั้ง uv ตัวจัดการแพ็กเกจและสภาพแวดล้อม Python ที่รวดเร็ว:
เริ่มต้นเทอร์มินัลใหม่หลังติดตั้ง uv เพื่อให้คำสั่งพร้อมใช้งานในเชลล์
ตอนนี้สร้างไดเรกทอรีโปรเจกต์และสภาพแวดล้อมเสมือน Python 3.12:
ถัดไป ติดตั้ง PyTorch 2.7.0 ที่รองรับ CUDA 12.6:
ระหว่างการทดสอบ บิลด์ CUDA 12.8 เกิดข้อผิดพลาดความเข้ากันได้ของไดรเวอร์บน RTX 4070 ของเรา การสลับเป็น PyTorch 2.7.0 พร้อม CUDA 12.6 ช่วยแก้ปัญหาได้โดยไม่ต้องอัปเดตไดรเวอร์ ทั้งนี้ขึ้นกับ GPU และไดรเวอร์ NVIDIA อาจต้องใช้บิลด์ CUDA อื่น
หากไม่มี GPU ให้ติดตั้งบิลด์สำหรับ CPU โดยเปลี่ยน index URL เป็น
https://download.pytorch.org/whl/cpuโค้ดถัดไปในบทเรียนนี้จะย้อนกลับไปใช้ CPU โดยอัตโนมัติตอนนี้ติดตั้ง Timestral โดยตรงจาก GitHub อย่างเป็นทางการ:
ติดตั้งไลบรารีที่เหลือสำหรับดาวน์โหลดข้อมูลตลาดหุ้น ประมวลผลผลทำนาย สร้างภาพ และรันโน้ตบุ๊ก:
ใช้ yfinance เพื่อดึงราคาหุ้นย้อนหลัง pandas และ NumPy สำหรับประมวลผลข้อมูล และ Matplotlib สำหรับพล็อตราคา จริงเทียบกับที่ทำนาย อีกทั้งจำกัดเวอร์ชัน pandas ให้อยู่ในช่วงที่ทดสอบเพื่อหลีกเลี่ยงคำเตือนด้านความเข้ากันได้
ก่อนดำเนินการต่อ ตรวจสอบว่า PyTorch เข้าถึง GPU ได้:
เอาต์พุตของเรา:
ค่า
Trueยืนยันว่า PyTorch ใช้ CUDA ได้ และบรรทัดสุดท้ายระบุชื่อ GPU พร้อมสำหรับเริ่มทดลองใช้ Timestral แล้วแทนการใช้สคริปต์ Python แยก จะใช้ JupyterLab เพื่อรันโค้ดทีละส่วน ตรวจสอบค่าพยากรณ์ และเปรียบเทียบผลกับข้อมูลตลาดจริง เปิด JupyterLab จากไดเรกทอรีโปรเจกต์:
เปิด URL ที่ปรากฏในเทอร์มินัล โดยทั่วไปคือ
http://localhost:8888/labและสร้างโน้ตบุ๊ก Python ใหม่โดยใช้สภาพแวดล้อมที่เพิ่งตั้งค่า จะใช้โน้ตบุ๊กนี้ในการโหลด Timestral สร้างการพยากรณ์ และประเมินประสิทธิภาพของโมเดลพยากรณ์ราคาหุ้น Apple ด้วย Timestral
แทนที่จะสร้างข้อมูลสังเคราะห์ จะใช้ราคาหุ้น Apple ย้อนหลังจริง และวัดความแม่นยำของ Timestral ในการทำนายราคาปิดของวันทำการถัดไป
เพื่อให้การทดลองสมจริงขึ้น จะใช้ การพยากรณ์แบบเลื่อนหน้าต่างหนึ่งวัน สำหรับทุกวันทำการในช่วงทดสอบ Timestral จะได้รับราคาปิด 500 ค่าในอดีตก่อนหน้า และทำนายเฉพาะราคาปิดของวันถัดไป
จะเปรียบเทียบสองวิธี:
1. ดาวน์โหลดราคาหุ้นย้อนหลัง
เริ่มโน้ตบุ๊กและนำเข้าไลบรารีที่ต้องใช้ กำหนดสัญลักษณ์ หุ้น จำนวนวันทดสอบ หน้าต่างบริบท และชื่อโมเดล
ตอนนี้ดาวน์โหลดข้อมูลรายวันของหุ้น Apple ระยะเวลา 5 ปี การตั้งค่า
auto_adjust=Trueจะคืนค่าราคาปิดที่ปรับด้วยการแตกพาร์และปันผลแล้วใช้ช่วง 60 วันทำการสุดท้ายเป็นการทดสอบ และใช้ข้อมูลสังเกตการณ์ 500 ค่าก่อนหน้าเป็นบริบทสำหรับแต่ละการทำนาย
2. โหลด Timestral ลงบน GPU
โหลดโมเดล 209M ลงบน GPU พร้อมทางเลือกสำรองเป็น CPU หากไม่มี CUDA น้ำหนักขนาด 837 MB จะดาวน์โหลดจาก Hugging Face เมื่อรันเซลล์นี้ครั้งแรก
โมเดลของเราถูกโหลดสำเร็จบน RTX 4070:
3. สร้างการพยากรณ์แบบเลื่อนหน้าต่างหนึ่งวัน
ต่อไปจะสร้างการทำนายสองชุดสำหรับแต่ละวันทำการ: ชุดหนึ่งจากราคาปิดในอดีต และอีกชุดจากอัตราผลตอบแทนแบบลอการิทึม อัตราผลตอบแทนแบบลอการิทึมคือการเปลี่ยนแปลงรายวันของลอการิทึมของราคา และจะแปลงผลทำนายกลับเป็นราคาด้วยการใช้ราคาปิดก่อนหน้า
โมเดลจะสร้างการพยากรณ์รายวันแบบเลื่อนหน้าต่าง 60 ครั้ง โดยใช้ราคาปิด 500 ค่าก่อนหน้าสำหรับแต่ละครั้ง แต่ละการพยากรณ์ใช้เฉพาะข้อมูลที่มีอยู่ก่อนวันเป้าหมาย จึงไม่เกิดการรั่วไหลของข้อมูลอนาคตเข้าสู่อินพุตของโมเดล
4. ประเมินความแม่นยำของการพยากรณ์
จะวัดค่า mean absolute error (MAE), root mean squared error (RMSE), mean absolute percentage error (MAPE) และความแม่นยำของทิศทาง นอกจากนี้จะเปรียบเทียบ Timestral กับเบสไลน์แบบง่ายที่สมมติว่าราคาปิดของวันพรุ่งนี้เท่ากับของวันนี้
ผลลัพธ์ของเราชี้ว่า Timestral ทำได้ดีกว่าเล็กน้อยเมื่อพยากรณ์อัตราผลตอบแทนลอการิทึมแทนที่จะเป็นราคาหุ้นดิบ
วิธีแบบลอกรับผลตอบแทนได้ค่า MAE ($3.05), RMSE ($3.84) และ MAPE (0.93%) ต่ำที่สุด เหนือกว่าเบสไลน์ของเราเล็กน้อย
ที่สำคัญยิ่งกว่า ความแม่นยำด้านทิศทางเพิ่มจาก 41.67% สำหรับราคาดิบ เป็น 55% สำหรับอัตราผลตอบแทนลอการิทึม บ่งชี้ว่าทำนายได้ดีกว่าในแง่ราคาจะขึ้นหรือลง
โมเดลราคาดิบยังให้ความครอบคลุมของช่วงคาดการณ์ 10-90% ที่ 81.7% ใกล้เคียงกับที่คาดไว้ 80% สะท้อนว่าประมาณค่าความไม่แน่นอนค่อนข้างเที่ยงตรง โดยรวม Timestral ให้การพยากรณ์ราคาที่ค่อนข้างแม่นยำ แต่ความเหนือกว่าเบสไลน์อย่างง่ายมีน้อย และยังต้องทดสอบต่อไปเพื่อดูว่าผลทำนายสามารถสนับสนุนการตัดสินใจซื้อขายได้อย่างน่าเชื่อถือหรือไม่
5. แสดงภาพการทำนายของ Timestral
มาพล็อตราคาปิดจริงเทียบกับทั้งสองวิธีการพยากรณ์ด้วย Matplotlib
กราฟแสดงว่า Timestral ติดตามราคาจริงของ Apple ได้ใกล้เคียงในช่วง 60 วันทำการ ทั้งสองวิธีจับแนวโน้มขาขึ้นได้ ส่วนพื้นที่สีส้มเงาคือช่วงคาดการณ์ 10-90% ของโมเดลราคาดิบ แผงล่างพล็อตข้อผิดพลาดของการทำนายรายวัน
ข้อผิดพลาดส่วนใหญ่อยู่ในช่วงประมาณ $5 โดยมีพลาดมากกว่าบางวันในช่วง $9 ถึง $11 ระหว่างที่ราคาขยับแรง ทั้งสองวิธีให้ผลเกือบเหมือนกัน โดยอัตราผลตอบแทนลอการิทึมนำเล็กน้อย เส้นพยากรณ์ทั้งสองยังตามหลังราคาจริงอยู่ราวหนึ่งวัน ซึ่งสอดคล้องกับช่องว่างที่เล็กมากเมื่อเทียบกับเบสไลน์แบบง่าย
6. สร้างสัญญาณ ซื้อ ถือ และ ขาย
ตอนนี้จะแปลงการทำนายราคาดิบเป็นสัญญาณ ซื้อ ถือ และ ขาย เพื่อการทดลอง ใช้เกณฑ์ 1% ของการเปลี่ยนแปลงราคาที่ทำนายได้:
สามารถเขียนกฎเหล่านี้ด้วย NumPy ได้ดังนี้:
ทั้ง 60 วันทำการให้สัญญาณ HOLD โดยไม่มีคำแนะนำ BUY หรือ SELL ใน 10 แถวสุดท้ายที่แสดง การเปลี่ยนแปลงที่คาดไว้ไม่เคยเกิน 0.15% ไปในทิศทางใดทิศทางหนึ่ง ซึ่งต่ำกว่าเกณฑ์ 1% ของเรามาก
สัญญาณเหล่านี้มาจากการทำนายราคาดิบ ซึ่งมีความแม่นยำด้านทิศทางที่อ่อนกว่า (41.67%) หากต้องการดูสัญญาณจากการพยากรณ์อัตราผลตอบแทนลอการิทึม ให้สลับ
price_predictionsเป็นreturn_predictionsในการคำนวณchange_pctการลดเกณฑ์จะให้สัญญาณ BUY และ SELL มากขึ้น แต่ก็ไวต่อความผิดพลาดของการพยากรณ์และสัญญาณรบกวนของตลาดมากขึ้นด้วยสัญญาณเหล่านี้มีไว้เพื่อการทดลอง ไม่ใช่เพื่อการเทรดจริง และไม่มีส่วนใดในบทเรียนนี้เป็นคำแนะนำด้านการเงิน การทดสอบย้อนหลังเพิ่มเติม การปรับเกณฑ์ และการวิเคราะห์ต้นทุนธุรกรรมเป็นสิ่งจำเป็นเพื่อตรวจสอบว่าสามารถสนับสนุนกลยุทธ์ที่ทำกำไรได้หรือไม่
ข้อคิดส่งท้าย
โดยรวมแล้ว ประทับใจกับ Timestral มาก
การตั้งค่าทั้งหมดทำได้ไม่ยุ่งยาก อินเฟอเรนซ์รวดเร็ว และสามารถรันทุกอย่างแบบโลคอลบน RTX 4070 โดยไม่ต้องพึ่งพา API ภายนอก
ที่ทำให้น่าสนใจยิ่งขึ้นคือโมเดลขนาดเบาเหล่านี้ยังรันบน CPU ได้ ทำให้เข้าถึงได้โดยไม่ต้องใช้ฮาร์ดแวร์ราคาแพง
ในแง่ความแม่นยำในการพยากรณ์ ผลลัพธ์ของเราออกมาก้ำกึ่ง
Timestral ติดตามราคาหุ้นได้สมเหตุสมผล แต่แทบไม่เหนือกว่าเบสไลน์อย่างง่าย
ไม่ใช่ผู้เชี่ยวชาญด้านการพยากรณ์ทางการเงินหรือการเทรด ดังนั้นอาจยังทำได้มากกว่านี้ในเรื่องการเตรียมข้อมูล กลยุทธ์การพยากรณ์ และการจูนพารามิเตอร์เพื่อให้ได้ผลลัพธ์ที่ดีกว่า
ก่อนหน้านี้เคยใช้บริการพยากรณ์แบบโฮสต์อย่าง TimeGPT แต่ Timestral ทำให้การพยากรณ์แบบโลคอลน่าสนใจยิ่งขึ้น ตั้งแต่มีการปล่อยโมเดลนี้ ได้เริ่มย้ายงานพยากรณ์จำนวนมากขึ้นไปใช้โมเดลแบบโลคอล เพราะรวดเร็ว ขนาดเล็ก และไม่ต้องมี API หรือค่าบริการตามการใช้งาน
สำหรับเราแล้ว จุดแข็งที่ใหญ่ที่สุดของ Timestral ไม่ใช่แค่ความแม่นยำ แต่คือความง่ายและต้นทุนที่ต่ำในการทำพยากรณ์
สามารถรันโมเดลอนุกรมเวลาที่มีศักยภาพบนฮาร์ดแวร์ของตัวเอง ทดลองได้อย่างอิสระ และฝังเข้าในแอปพลิเคชันได้โดยไม่ต้องพึ่งพาบริการภายนอก แม้ว่าการทำนายหุ้นของเราจะไม่โดดเด่น คิดว่า Timestral เป็นตัวเลือกที่ยอดเยี่ยมสำหรับผู้ที่กำลังสร้างแอปพยากรณ์แบบโลคอล
หากสนใจเรียนรู้เรื่องการพยากรณ์เพิ่มเติม แนะนำคอร์ส Time Series Analysis in Python สำหรับโมเดลเฉพาะด้านการเงิน ลองดู Machine Learning for Finance in Python