# FinSTaR: Towards Financial Reasoning with Time Series Reasoning Models

arXiv License

**FinSTaR** (**Fin**ancial Time **S**eries **T**hinking **a**nd **R**easoning) is the first Time Series Reasoning Model (TSRM) designed specifically for the financial domain. It employs two structurally different chain-of-thought (CoT) strategies tailored to the properties of financial reasoning: - (1) **Compute-in-CoT** for *assessment* tasks (deterministic, computable from observable prices) - (2) **Scenario-Aware CoT** for *prediction* tasks (probabilistic, subject to unobservable factors)
--- ## Overview ### Four Capability Categories We define core capabilities of a Financial TSRM along two axes, forming a 2x2 taxonomy:


| | **Single-Stock** | **Multi-Stock** | |---|---|---| | **Assessment** | Drawdown, Volatility Regime, Trend Direction | Correlation | | **Prediction** | Event Response, Support/Resistance, Drawdown Recovery, Volatility Forecast | Relative Performance, Pair Convergence |
### Key Results | Model | Assessment Avg. | Prediction Avg. | Overall | |---|---|---|---| | Qwen2.5-7B (zero-shot) | 53.5 | 50.3 | 51.6 | | TimeOmni-1-7B (zero-shot) | 48.3 | 53.2 | 51.3 | | Qwen2.5-7B (SFT w/ CoT) | 67.7 | 51.1 | 57.8 | | **FinSTaR (Ours)** | **95.0** | **68.2** | **78.9** |
--- ## Installation ```bash git clone https://github.com/seunghan96/FinSTaR.git cd FinSTaR pip install -r requirements.txt ```
--- ## FinTSR-Bench ### Data Generation FinTSR-Bench is constructed from 250 S&P 500 stocks (2010-2025). To generate the benchmark from raw stock data: ```bash # Step 1: Generate QA pairs (10 tasks, ~3,500 samples each) python src/data_generation/generate_qa_10tasks.py \ --data_dir raw_stock_data/ \ --output_dir data/raw/ \ --samples_per_task 3500 # Step 2: Generate CoT annotations and prepare final data python src/data_generation/prepare_final_data.py \ --input_dir data/raw/ \ --output_dir data/ ``` ### Data Structure ``` data/ ├── train_cot.json # 35K samples with CoT annotations ├── train_ao.json # 35K samples (answer-only) ├── test_sft.json # Test A: ID stocks, OOD period (10K) ├── test_b_ood_stock.json # Test B: OOD stocks, ID period (10K) └── test_c_ood_stock_period.json # Test C: OOD stocks + period (10K) ``` ### Data Format Each sample follows the chat format: ```json { "task": "F1_drawdown", "answer": "C", "conversations": [ {"role": "user", "content": "You are analyzing the stock AAPL. Below are the daily closing prices (120 days): [...]"}, {"role": "assistant", "content": "\nStep 1 — Find the peak price: ...\n\n(C)"} ], "metadata": {"peak": 182.63, "current": 161.42, "drawdown": 0.116} } ```
--- ## Training ### Quick Start ```bash # Train FinSTaR (TimeOmni-1-7B backbone, LoRA, 4 epochs) accelerate launch --num_processes 2 --mixed_precision bf16 \ src/training/train.py \ --model_dir anton-hugging/TimeOmni-1-7B \ --train_file data/train_cot.json \ --output_dir checkpoints/finstar \ --lora_r 32 --lora_alpha 64 \ --batch_size 1 --grad_accum 16 \ --max_length 4096 --num_epochs 4 --lr 5e-5 ``` ### Training Configurations | Config | Backbone | CoT | Description | |---|---|---|---| | `02_cot_train_timeomni.sh` | TimeOmni-1-7B | Compute + Scenario | **FinSTaR** (main) | | `03_cot_train_qwen.sh` | Qwen2.5-7B | Compute + Scenario | SFT baseline (w/ CoT) | | `04_ao_train_timeomni.sh` | TimeOmni-1-7B | None (answer-only) | Ablation (w/o CoT) | | `05_ao_train_qwen.sh` | Qwen2.5-7B | None (answer-only) | SFT baseline (w/o CoT) |
--- ## Evaluation ### Zero-Shot Evaluation ```bash # Evaluate any model zero-shot on FinTSR-Bench python src/evaluation/inference.py \ --model_dir anton-hugging/TimeOmni-1-7B \ --test_file data/test_sft.json \ --output_dir results/timeomni_zs_test_a ``` ### FinSTaR Evaluation ```bash # Evaluate FinSTaR (LoRA adapter) python src/evaluation/inference.py \ --model_dir anton-hugging/TimeOmni-1-7B \ --lora_dir checkpoints/finstar/lora \ --test_file data/test_sft.json \ --output_dir results/finstar_test_a ``` ### Forecasting Baselines ```bash # Statistical baselines (Last Value, MA, ETS, Drift, Momentum) bash scripts/12_statistical_baselines.sh # Deep learning baselines (PatchTST, DLinear, Chronos, etc.) bash scripts/13_dl_baselines.sh ```
--- ## Project Structure ``` FinSTaR/ ├── README.md ├── requirements.txt ├── configs/ │ └── accelerate_config.yaml # Multi-GPU training config ├── src/ │ ├── data_generation/ # FinTSR-Bench construction │ │ ├── generate_qa_10tasks.py # QA pair generation (10 tasks) │ │ ├── generate_cot.py # Compute-in-CoT annotation │ │ ├── generate_compute_cot.py # Extended CoT with computation │ │ ├── prepare_final_data.py # Final data preparation │ │ ├── prepare_fair_data.py # Fair evaluation data │ │ └── utils.py # Financial indicators & utilities │ ├── training/ │ │ ├── train.py # LoRA SFT training │ │ ├── data_utils.py # Dataset & prompt utilities │ │ └── train_utils.py # Model loading & LoRA config │ └── evaluation/ │ ├── inference.py # Batch inference (vLLM) │ ├── get_score.py # Metric computation │ └── utils.py # Evaluation helpers ├── scripts/ # Experiment shell scripts │ ├── 01_zs.sh # Zero-shot baselines │ ├── 02_cot_train_timeomni.sh # FinSTaR training │ ├── 06_cot_eval_timeomni.sh # FinSTaR evaluation │ └── ... └── data/ # FinTSR-Bench (generate via src/data_generation/) ```
--- ## Citation If you find this work useful, please cite: ```bibtex @article{lee2026finstar, title={FinSTaR: Towards Financial Reasoning with Time Series Reasoning Models}, author={Lee, Seunghan and Seo, Jun and Lee, Jaehoon and Yoo, Sungdong and Kim, Minjae and Lim, Tae Yoon and Kang, Dongwan and Choi, Hwanil and Lee, Soonyoung and Ahn, Wonbin}, journal={arXiv preprint arXiv:2605.03460}, year={2026} } ``` ## Acknowledgements FinSTaR builds upon [TimeOmni-1](https://arxiv.org/abs/2509.24803) as its backbone. We thank the TimeOmni team for releasing model weights. Stock price data is sourced from publicly available S&P 500 historical data. ## Contact Seunghan Lee — seunghan.lee@lgresearch.ai