Kronos: κΈμ΅ μμ₯μ μΈμ΄λ₯Ό μν νμ΄λ°μ΄μ λͺ¨λΈ
Kronosλ μ΅μ΄μ μ€νμμ€ νμ΄λ°μ΄μ λͺ¨λΈλ‘, μ μΈκ³ 45κ° μ΄μμ κ±°λμ λ°μ΄ν°λ‘ νμ΅λ κΈμ΅ μΊλ€μ€ν±(K-line) λͺ¨λΈμ λλ€.
π° μμ
- π© [2025.08.17] νμΈνλ μ€ν¬λ¦½νΈλ₯Ό 곡κ°νμ΅λλ€! Kronosλ₯Ό μ¬λ¬λΆμ μμ μ λ§κ² μ μ©ν΄ 보μΈμ.
- π© [2025.08.02] λ Όλ¬Έμ΄ arXivμ κ²μ¬λμμ΅λλ€!
π μκ°
Kronosλ λμ½λ μ μ© νμ΄λ°μ΄μ λͺ¨λΈ ν¨λ°λ¦¬λ‘, κΈμ΅ μμ₯μ "μΈμ΄"μΈ K-line μνμ€μ νΉνλμ΄ μ¬μ νμ΅λμμ΅λλ€. λ²μ© TSFMκ³Ό λ¬λ¦¬ Kronosλ κΈμ΅ λ°μ΄ν°μ κ³ μ ν κ³ μ‘μ νΉμ±μ μ²λ¦¬νλλ‘ μ€κ³λμμ΅λλ€. μλ‘μ΄ 2λ¨κ³ νλ μμν¬λ₯Ό νμ©ν©λλ€:
- νΉνλ ν ν¬λμ΄μ κ° μ°μμ μ΄κ³ λ€μ°¨μμ μΈ K-line λ°μ΄ν°(OHLCV)λ₯Ό κ³μΈ΅μ μ΄μ° ν ν°μΌλ‘ μμνν©λλ€.
- λκ·λͺ¨ μκΈ°νκ· Transformerκ° μ΄λ¬ν ν ν°μΌλ‘ μ¬μ νμ΅λμ΄ λ€μν μμ μμ μ μν ν΅ν© λͺ¨λΈλ‘ κΈ°λ₯ν μ μμ΅λλ€.
β¨ λΌμ΄λΈ λ°λͺ¨
Kronosμ μμΈ‘ κ²°κ³Όλ₯Ό μκ°ννλ λΌμ΄λΈ λ°λͺ¨λ₯Ό μ€μ νμ΅λλ€. μΉνμ΄μ§λ ν₯ν 24μκ° λμμ BTC/USDT κ±°λ μμ λν μμΈ‘μ 보μ¬μ€λλ€.
π λΌμ΄λΈ λ°λͺ¨ λ°λ‘κ°κΈ°
π¦ λͺ¨λΈ λͺ©λ‘
λ€μν μ»΄ν¨ν λ° μ ν리μΌμ΄μ μꡬμ λ§μΆ° λ€μν μ©λμ μ¬μ νλ ¨λ λͺ¨λΈ ν¨λ°λ¦¬λ₯Ό 곡κ°ν©λλ€. λͺ¨λ λͺ¨λΈμ Hugging Face Hubμμ λ°λ‘ μ΄μ©ν μ μμ΅λλ€.
λͺ¨λΈ | ν ν¬λμ΄μ | 컨ν μ€νΈ κΈΈμ΄ | λ§€κ°λ³μ | μ€νμμ€ |
---|---|---|---|---|
Kronos-mini | Kronos-Tokenizer-2k | 2048 | 4.1M | β NeoQuasar/Kronos-mini |
Kronos-small | Kronos-Tokenizer-base | 512 | 24.7M | β NeoQuasar/Kronos-small |
Kronos-base | Kronos-Tokenizer-base | 512 | 102.3M | β NeoQuasar/Kronos-base |
Kronos-large | Kronos-Tokenizer-base | 512 | 499.2M | β |
π μμνκΈ°
μ€μΉ
- Python 3.10+λ₯Ό μ€μΉν ν μ’ μμ±μ μ€μΉνμΈμ:
pip install -r requirements.txt
π μμΈ‘ μμ±νκΈ°
Kronosλ‘ μμΈ‘νλ κ²μ KronosPredictor
ν΄λμ€λ₯Ό μ¬μ©νμ¬ κ°λ¨ν©λλ€. λ°μ΄ν° μ μ²λ¦¬, μ κ·ν, μμΈ‘ λ° μμ κ·νλ₯Ό μ²λ¦¬νλ―λ‘ μμ λ°μ΄ν°μμ μμΈ‘κΉμ§ λͺ μ€μ μ½λλ‘ μ΄λν μ μμ΅λλ€.
μ€μ μ°Έκ³ : Kronos-small
λ° Kronos-base
μ max_context
λ 512μ
λλ€. μ΄λ λͺ¨λΈμ΄ μ²λ¦¬ν μ μλ μ΅λ μνμ€ κΈΈμ΄μ
λλ€. μ΅μ μ μ±λ₯μ μν΄ μ
λ ₯ λ°μ΄ν° κΈΈμ΄(μ¦, lookback
)κ° μ΄ μ νμ μ΄κ³Όνμ§ μλ κ²μ΄ μ’μ΅λλ€. KronosPredictor
λ λ κΈ΄ 컨ν
μ€νΈμ λν΄ μλμΌλ‘ μλ¦Όμ μ²λ¦¬ν©λλ€.
첫 λ²μ§Έ μμΈ‘μ μμ±νλ λ¨κ³λ³ κ°μ΄λμ λλ€.
1. ν ν¬λμ΄μ μ λͺ¨λΈ λ‘λνκΈ°
λ¨Όμ , Hugging Face Hubμμ μ¬μ νλ ¨λ Kronos λͺ¨λΈκ³Ό ν΄λΉ ν ν¬λμ΄μ λ₯Ό λ‘λν©λλ€.
from model import Kronos, KronosTokenizer, KronosPredictor # Load from Hugging Face Hub tokenizer = KronosTokenizer.from_pretrained("NeoQuasar/Kronos-Tokenizer-base") model = Kronos.from_pretrained("NeoQuasar/Kronos-small")
2. μμΈ‘κΈ° μΈμ€ν΄μ€ννκΈ°
λͺ¨λΈ, ν ν¬λμ΄μ λ° μνλ μ₯μΉλ₯Ό μ λ¬νμ¬ KronosPredictor
μ μΈμ€ν΄μ€λ₯Ό μμ±ν©λλ€.
# Initialize the predictor predictor = KronosPredictor(model, tokenizer, device="cuda:0", max_context=512)
3. μ λ ₯ λ°μ΄ν° μ€λΉνκΈ°
predict
λ©μλμλ μΈ κ°μ§ μ£Όμ μ
λ ₯μ΄ νμν©λλ€:
df
: κ³Όκ±° K-line λ°μ΄ν°λ₯Ό ν¬ν¨νλ pandas DataFrame.['open', 'high', 'low', 'close']
μ΄μ ν¬ν¨ν΄μΌ ν©λλ€.volume
κ³Όamount
λ μ ν μ¬νμ λλ€.x_timestamp
:df
μ κ³Όκ±° λ°μ΄ν°μ ν΄λΉνλ νμμ€ν¬νμ pandas Series.y_timestamp
: μμΈ‘νλ €λ λ―Έλ κΈ°κ°μ νμμ€ν¬ν pandas Series.
import pandas as pd # Load your data df = pd.read_csv("./data/XSHG_5min_600977.csv") df['timestamps'] = pd.to_datetime(df['timestamps']) # Define context window and prediction length lookback = 400 pred_len = 120 # Prepare inputs for the predictor x_df = df.loc[:lookback-1, ['open', 'high', 'low', 'close', 'volume', 'amount']] x_timestamp = df.loc[:lookback-1, 'timestamps'] y_timestamp = df.loc[lookback:lookback+pred_len-1, 'timestamps']
4. μμΈ‘ μμ±νκΈ°
predict
λ©μλλ₯Ό νΈμΆνμ¬ μμΈ‘μ μμ±ν©λλ€. νλ₯ μ μμΈ‘μ μν΄ T
, top_p
, sample_count
μ κ°μ λ§€κ°λ³μλ‘ μνλ§ κ³Όμ μ μ μ΄ν μ μμ΅λλ€.
# Generate predictions pred_df = predictor.predict( df=x_df, x_timestamp=x_timestamp, y_timestamp=y_timestamp, pred_len=pred_len, T=1.0, # Temperature for sampling top_p=0.9, # Nucleus sampling probability sample_count=1 # Number of forecast paths to generate and average ) print("Forecasted Data Head:") print(pred_df.head())
predict
λ©μλλ μ 곡ν y_timestamp
λ₯Ό μΈλ±μ€λ‘ νμ¬ open
, high
, low
, close
, volume
, amount
μ λν μμΈ‘κ°μ ν¬ν¨νλ pandas DataFrameμ λ°νν©λλ€.
μ¬λ¬ μκ³μ΄μ ν¨μ¨μ μΌλ‘ μ²λ¦¬νκΈ° μν΄ Kronosλ predict_batch
λ©μλλ₯Ό μ 곡νλ©°, μ΄λ₯Ό ν΅ν΄ μ¬λ¬ λ°μ΄ν°μ
μ λν΄ λμμ λ³λ ¬ μμΈ‘μ μνν μ μμ΅λλ€. μ΄λ μ¬λ¬ μμ°μ΄λ κΈ°κ°μ ν λ²μ μμΈ‘ν΄μΌ ν λ νΉν μ μ©ν©λλ€.
# Prepare multiple datasets for batch prediction df_list = [df1, df2, df3] # List of DataFrames x_timestamp_list = [x_ts1, x_ts2, x_ts3] # List of historical timestamps y_timestamp_list = [y_ts1, y_ts2, y_ts3] # List of future timestamps # Generate batch predictions pred_df_list = predictor.predict_batch( df_list=df_list, x_timestamp_list=x_timestamp_list, y_timestamp_list=y_timestamp_list, pred_len=pred_len, T=1.0, top_p=0.9, sample_count=1, verbose=True ) # pred_df_list contains prediction results in the same order as input for i, pred_df in enumerate(pred_df_list): print(f"Predictions for series {i}:") print(pred_df.head())
λ°°μΉ μμΈ‘μ μν μ£Όμ μꡬμ¬ν:
- λͺ¨λ μκ³μ΄μ λμΌν κ³Όκ±° κΈΈμ΄(룩백 μλμ°)λ₯Ό κ°μ ΈμΌ ν©λλ€.
- λͺ¨λ μκ³μ΄μ λμΌν μμΈ‘ κΈΈμ΄(
pred_len
)λ₯Ό κ°μ ΈμΌ ν©λλ€. - κ° DataFrameμ νμ μ΄μΈ
['open', 'high', 'low', 'close']
λ₯Ό ν¬ν¨ν΄μΌ ν©λλ€. volume
λ°amount
μ΄μ μ ν μ¬νμ΄λ©°, λλ½λ κ²½μ° 0μΌλ‘ μ±μμ§λλ€.
predict_batch
λ©μλλ ν¨μ¨μ μΈ μ²λ¦¬λ₯Ό μν΄ GPU λ³λ ¬ μ²λ¦¬λ₯Ό νμ©νλ©°, κ° μκ³μ΄μ λν΄ λ
립μ μΌλ‘ μ κ·ν λ° μμ κ·νλ₯Ό μλμΌλ‘ μ²λ¦¬ν©λλ€.
5. μμ λ° μκ°ν
λ°μ΄ν° λ‘λ©, μμΈ‘, νλ‘ν
μ ν¬ν¨νλ μμ ν μ€ν κ°λ₯ν μ€ν¬λ¦½νΈλ examples/prediction_example.py
λ₯Ό μ°Έμ‘°νμΈμ.
μ΄ μ€ν¬λ¦½νΈλ₯Ό μ€ννλ©΄ μλμ μ μ¬ν κ·Έλνκ° μμ±λμ΄ μ€μ λ°μ΄ν°μ λͺ¨λΈ μμΈ‘μΉλ₯Ό λΉκ΅ν μ μμ΅λλ€:
λν Volume λ° Amount λ°μ΄ν° μμ΄ μμΈ‘μ μννλ μ€ν¬λ¦½νΈλ μ 곡νλ©°, μ΄λ examples/prediction_wo_vol_example.py
μμ νμΈν μ μμ΅λλ€.
π§ μ¬μ©μ λ°μ΄ν°λ‘ νμΈνλ (A-Share μμ₯ μμ)
Kronosλ₯Ό μ¬μ©μ λ°μ΄ν°μ μΌλ‘ νμΈνλνκΈ° μν μμ ν νμ΄νλΌμΈμ μ 곡ν©λλ€. μμλ‘ μ€κ΅ A-Share μμ₯ λ°μ΄ν°λ₯Ό QlibμΌλ‘ μ€λΉνκ³ κ°λ¨ν λ°±ν μ€νΈλ₯Ό μννλ λ°©λ²μ 보μ¬μ€λλ€.
λ©΄μ± μ‘°ν: μ΄ νμ΄νλΌμΈμ νμΈνλ νλ‘μΈμ€λ₯Ό μ€λͺ νκΈ° μν λ°λͺ¨μ©μ λλ€. λ¨μνλ μμμ΄λ©° νλ‘λμ μ€λΉλ μμ νΈλ μ΄λ© μμ€ν μ΄ μλλλ€. μμ μ μΈ μνλ₯Ό λ¬μ±νκΈ° μν΄μλ ν¬νΈν΄λ¦¬μ€ μ΅μ ν λ° λ¦¬μ€ν¬ ν©ν° μ€μ±νμ κ°μ λ μ κ΅ν κΈ°λ²μ΄ νμν©λλ€.
νμΈνλ νλ‘μΈμ€λ λ€ κ°μ§ μ£Όμ λ¨κ³λ‘ ꡬμ±λ©λλ€:
- ꡬμ±: κ²½λ‘ λ° νμ΄νΌνλΌλ―Έν° μ€μ
- λ°μ΄ν° μ€λΉ: Qlibμ μ¬μ©νμ¬ λ°μ΄ν° μ²λ¦¬ λ° λΆν
- λͺ¨λΈ νμΈνλ: Tokenizer λ° Predictor λͺ¨λΈ νμΈνλ
- λ°±ν μ€ν : νμΈνλλ λͺ¨λΈμ μ±λ₯ νκ°
νμ 쑰건
- λ¨Όμ
requirements.txt
μ λͺ μλ λͺ¨λ μμ‘΄μ±μ μ€μΉνμΈμ. - μ΄ νμ΄νλΌμΈμ
qlib
μ μμ‘΄ν©λλ€. λ€μ λͺ λ Ήμ΄λ‘ μ€μΉνμΈμ:pip install pyqlib
- Qlib λ°μ΄ν°λ₯Ό μ€λΉν΄μΌ ν©λλ€. 곡μ Qlib κ°μ΄λλ₯Ό λ°λΌ λ°μ΄ν°λ₯Ό λ€μ΄λ‘λνκ³ λ‘컬μ μ€μ νμΈμ. μμ μ€ν¬λ¦½νΈλ μΌλ³(daily) μ£ΌκΈ° λ°μ΄ν°λ₯Ό μ¬μ©νλ€κ³ κ°μ ν©λλ€.
1λ¨κ³: μ€ν ꡬμ±νκΈ°
λ°μ΄ν°, νμ΅, λͺ¨λΈ κ²½λ‘μ λν λͺ¨λ μ€μ μ finetune/config.py
μμ μ€μ μ§μ€νλμ΄ μμ΅λλ€. μ΄λ€ μ€ν¬λ¦½νΈλ₯Ό μ€ννκΈ° μ μ, μ¬μ©μ νκ²½μ λ§κ² λ€μ κ²½λ‘λ€μ μμ νμΈμ:
qlib_data_path
: λ‘컬 Qlib λ°μ΄ν° λλ ν 리 κ²½λ‘μ λλ€.dataset_path
: μ²λ¦¬λ νλ ¨/κ²μ¦/ν μ€νΈ νΌν΄(pickle) νμΌμ΄ μ μ₯λ λλ ν 리μ λλ€.save_path
: λͺ¨λΈ 체ν¬ν¬μΈνΈλ₯Ό μ μ₯ν κΈ°λ³Έ λλ ν 리μ λλ€.backtest_result_path
: λ°±ν μ€ν κ²°κ³Όλ₯Ό μ μ₯ν λλ ν 리μ λλ€.pretrained_tokenizer_path
λ°pretrained_predictor_path
: μ¬μ νλ ¨λ λͺ¨λΈμ κ²½λ‘μ λλ€ (λ‘컬 κ²½λ‘ λλ Hugging Face λͺ¨λΈ μ΄λ¦ μ¬μ© κ°λ₯).
νΉμ μμ
μ λ§κ² instrument
, train_time_range
, epochs
, batch_size
μ κ°μ λ€λ₯Έ λ§€κ°λ³μλ€λ μ‘°μ ν μ μμ΅λλ€. Comet.mlμ μ¬μ©νμ§ μλλ€λ©΄ use_comet = False
λ‘ μ€μ νμΈμ.
2λ¨κ³: λ°μ΄ν°μ μ€λΉνκΈ°
λ°μ΄ν° μ μ²λ¦¬ μ€ν¬λ¦½νΈλ₯Ό μ€ννμΈμ. μ΄ μ€ν¬λ¦½νΈλ Qlib λλ ν 리μμ μμ μμ₯ λ°μ΄ν°λ₯Ό λ‘λνκ³ , μ²λ¦¬ν λ€ νλ ¨, κ²μ¦, ν μ€νΈ μΈνΈλ‘ λΆν νμ¬ pickle νμΌλ‘ μ μ₯ν©λλ€.
python finetune/qlib_data_preprocess.py
μ€ν νμλ μ€μ νμΌμ dataset_path
μ μ§μ λ λλ ν 리μμ train_data.pkl
, val_data.pkl
, test_data.pkl
νμΌμ μ°Ύμ μ μμ΅λλ€.
Step 3: νμΈνλ μ€ν
νμΈνλ κ³Όμ μ λ λ¨κ³λ‘ ꡬμ±λ©λλ€: ν ν¬λμ΄μ λ₯Ό λ¨Όμ νμΈνλνκ³ , κ·Έ λ€μ μμΈ‘ λͺ¨λΈμ νμΈνλν©λλ€. λ νλ ¨ μ€ν¬λ¦½νΈ λͺ¨λ torchrun
μ μ¬μ©ν λ€μ€ GPU νλ ¨μ μν΄ μ€κ³λμμ΅λλ€.
3.1 ν ν¬λμ΄μ νμΈνλ
μ΄ λ¨κ³λ ν ν¬λμ΄μ λ₯Ό νΉμ λλ©μΈμ λ°μ΄ν° λΆν¬μ λ§κ² μ‘°μ ν©λλ€.
# Replace NUM_GPUS with the number of GPUs you want to use (e.g., 2) torchrun --standalone --nproc_per_node=NUM_GPUS finetune/train_tokenizer.py
κ°μ₯ μ±λ₯μ΄ μ’μ ν ν¬λμ΄μ 체ν¬ν¬μΈνΈλ config.py
μμ ꡬμ±λ κ²½λ‘(save_path
μ tokenizer_save_folder_name
μμ νμλ¨)μ μ μ₯λ©λλ€.
3.2 μμΈ‘ λͺ¨λΈ νμΈνλ
μ΄ λ¨κ³λ μμΈ‘ μμ μ μν΄ μ£Όμ Kronos λͺ¨λΈμ νμΈνλν©λλ€.
# Replace NUM_GPUS with the number of GPUs you want to use (e.g., 2) torchrun --standalone --nproc_per_node=NUM_GPUS finetune/train_predictor.py
κ°μ₯ μ±λ₯μ΄ μ’μ μμΈ‘ λͺ¨λΈ 체ν¬ν¬μΈνΈλ config.py
μμ ꡬμ±λ κ²½λ‘μ μ μ₯λ©λλ€.
Step 4: λ°±ν μ€ν μΌλ‘ νκ°
λ§μ§λ§μΌλ‘, νμΈνλλ λͺ¨λΈμ νκ°νκΈ° μν΄ λ°±ν μ€ν μ€ν¬λ¦½νΈλ₯Ό μ€ννμΈμ. μ΄ μ€ν¬λ¦½νΈλ λͺ¨λΈμ λ‘λνκ³ , ν μ€νΈ μΈνΈμ λν΄ μΆλ‘ μ μννλ©°, μμΈ‘ μ νΈ(μ: μμΈ‘λ κ°κ²© λ³λ)λ₯Ό μμ±νκ³ , κ°λ¨ν μμ Kκ° μ λ΅ λ°±ν μ€νΈλ₯Ό μ€νν©λλ€.
# Specify the GPU for inference python finetune/qlib_test.py --device cuda:0
μ΄ μ€ν¬λ¦½νΈλ μ½μμ μμΈν μ±λ₯ λΆμμ μΆλ ₯νκ³ , μλμ μ μ¬ν λ²€μΉλ§ν¬ λλΉ μ λ΅μ λμ μμ΅λ₯ 곑μ μ 보μ¬μ£Όλ νλ‘―μ μμ±ν©λλ€:
π‘ λ°λͺ¨μμ νλ‘λμ μΌλ‘: μ€μν κ³ λ €μ¬ν
- μμ μ νΈ vs μμ μν: μ΄ λ°λͺ¨μμ λͺ¨λΈμ΄ μμ±νλ μ νΈλ μμ μμΈ‘κ°μ λλ€. μ€μ μμ ν¬μ μν¬νλ‘μμλ μΌλ°μ μΌλ‘ μ΄λ¬ν μ νΈλ₯Ό ν¬νΈν΄λ¦¬μ€ μ΅μ ν λͺ¨λΈμ μ λ ₯ν©λλ€. μ΄ λͺ¨λΈμ μΌλ°μ μΈ μν μμΈ(μ: μμ₯ λ² ν, κ·λͺ¨ λ° κ°μΉμ κ°μ μ€νμΌ ν©ν°)μ λν λ ΈμΆμ μ€μ±ννκΈ° μν μ μ½ μ‘°κ±΄μ μ μ©νμ¬ **"μμ μν"**λ₯Ό λΆλ¦¬νκ³ μ λ΅μ κ²¬κ³ μ±μ ν₯μμν΅λλ€.
- λ°μ΄ν° μ²λ¦¬: μ 곡λ
QlibDataset
μ μμμ λλ€. λ€λ₯Έ λ°μ΄ν° μμ€λ νμμ κ²½μ° λ°μ΄ν° λ‘λ© λ° μ μ²λ¦¬ λ‘μ§μ μμ ν΄μΌ ν©λλ€. - μ λ΅ λ° λ°±ν μ€νΈ 볡μ‘μ±: μ¬κΈ°μ μ¬μ©λ λ¨μ Top-K μ λ΅μ κΈ°λ³Έμ μΈ μμμ μ λλ€. νλ‘λμ μμ€μ μ λ΅μ μΌλ°μ μΌλ‘ ν¬νΈν΄λ¦¬μ€ ꡬμ±, λμ ν¬μ§μ μ¬μ΄μ§, μν κ΄λ¦¬(μ: μμ λ§€/μ΅μ κ·μΉ)λ₯Ό μν λ 볡μ‘ν λ‘μ§μ ν¬ν¨ν©λλ€. λν, λμ μ νλμ λ°±ν μ€νΈλ κ±°λ λΉμ©, μ¬λ¦¬νΌμ§, μμ₯ μν₯μ μΈμ¬νκ² λͺ¨λΈλ§νμ¬ μ€μ μ±λ₯μ λ μ ννκ² μΆμ ν΄μΌ ν©λλ€.
π AI μμ± μ£Όμ:
finetune/
λλ ν 리 λ΄μ λ§μ μ½λ μ£Όμμ μ€λͺ λͺ©μ μΌλ‘ AI μ΄μμ€ν΄νΈ(Gemini 2.5 Pro)μ μν΄ μμ±λμμ΅λλ€. λμμ΄ λλλ‘ μμ±λμμ§λ§ λΆμ νν λ΄μ©μ΄ ν¬ν¨λ μ μμ΅λλ€. μ½λ μ체λ₯Ό λ Όλ¦¬μ νμ μ μΈ μΆμ²λ‘ κ°μ£Όν κ²μ κΆμ₯ν©λλ€.
π μΈμ©
μ°κ΅¬μ Kronosλ₯Ό μ¬μ©νμλ κ²½μ°, μ ν¬ λ Όλ¬Έμ μΈμ©ν΄ μ£Όμλ©΄ κ°μ¬νκ² μ΅λλ€:
@misc{shi2025kronos, title={Kronos: A Foundation Model for the Language of Financial Markets}, author={Yu Shi and Zongliang Fu and Shuo Chen and Bohan Zhao and Wei Xu and Changshui Zhang and Jian Li}, year={2025}, eprint={2508.02739}, archivePrefix={arXiv}, primaryClass={q-fin.ST}, url={https://arxiv.org/abs/2508.02739}, }
π λΌμ΄μ μ€
μ΄ νλ‘μ νΈλ MIT λΌμ΄μ μ€μ λ°λΌ λΌμ΄μ μ€κ° λΆμ¬λ©λλ€.