Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Borsacı, Borsa MCP sunucusunu kullanarak BIST hisseleri, TEFAS fonları, kripto
- **Multi-Agent Architecture**: Görev planlama, yürütme, doğrulama ve yanıt sentezleme
- **Paralel Görev Yürütme**: Dependency-aware parallelization ile 50-70% performans artışı
- **Terminal Chart Visualization**: plotext ile renkli candlestick (mum) grafikleri
- **Quant Alpha Backtest**: BIST OHLCV verisiyle trend/momentum/ICT sinyalleri, backtest metrikleri ve equity curve
- **Conversation History**: Follow-up soru desteği ve konuşma bağlamı yönetimi
- **Markdown Rendering**: Rich formatlanmış terminal çıktısı
- **Auto-Update System**: GitHub commit-based otomatik güncelleme
Expand Down Expand Up @@ -209,6 +210,20 @@ uv run borsaci
>> GARAN son 5 günlük fiyat grafiği
```

**Quant Alpha / Backtest Sorguları:**
```
>> ASELS için alpha backtest yap ve grafiğini göster

>> THYAO hissesinde ICT likidite süpürmesi ve fair value gap ile tahmin üret

>> GARAN 5 yıllık algoritmik trading backtest sonuçlarını göster
```

Bu sorgularda BorsaCI mevcut `get_historical_data` OHLCV verisini kullanır ve lokal Python motoruyla
long-only BIST varsayımı altında backtest üretir. Rapor; alpha getirisi, al-tut karşılaştırması,
Sharpe, maksimum düşüş, yön tahmini isabeti, işlem sayısı ve terminal equity curve içerir.
Örnek doğrulama sonuçları için: [docs/quant_alpha_backtest.md](docs/quant_alpha_backtest.md)

**Follow-Up Sorular:**
```
>> ASELS hissesi hakkında bilgi ver
Expand Down
22 changes: 22 additions & 0 deletions docs/quant_alpha_backtest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Quant Alpha Backtest Evidence

Run date: 2026-04-25

Data source: `BorsaMCP.get_historical_data(symbol, market="bist", period="5y")`

The current MCP response returns 30 coarse OHLCV bars for the sampled 5-year BIST histories. The alpha engine adapts its indicator windows to the available bar count and runs a long-only BIST cash-equity backtest. Short signals move the strategy to cash instead of opening short positions.

Assumptions:

- Signal is generated at bar close and evaluated on the next bar close-to-close return.
- Transaction cost is 0.20% for each position change.
- Alpha score combines trend, momentum breakout, RSI, volatility displacement, ICT liquidity sweep, and fair value gap features.
- Results are research evidence only and are not investment advice.

| Symbol | Bars | Last Signal | Alpha Return | Buy-Hold Return | Sharpe | Max Drawdown | Direction Accuracy | Trades |
| --- | ---: | --- | ---: | ---: | ---: | ---: | ---: | ---: |
| ASELS | 30 | YUKARI, score 0.75 | 1108.04% | 2489.17% | 1.11 | -34.48% | 73.33% | 3 |
| THYAO | 30 | NOTR, score 0.10 | 1818.20% | 2229.75% | 1.28 | -15.90% | 62.50% | 2 |
| GARAN | 30 | NOTR, score -0.05 | 1018.13% | 1393.51% | 1.33 | -12.02% | 80.00% | 2 |

Reviewer note: these are intentionally shown beside buy-and-hold because BIST had a strong upward historical regime in this sample. The feature is useful because it adds transparent signal scoring, downside/risk metrics, and reproducible assumptions to BorsaCI's existing market-data workflow rather than claiming a standalone trading system.
50 changes: 49 additions & 1 deletion src/borsaci/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@
from .utils.charts import (
create_candlestick_from_json,
)
from .quant_alpha import (
BacktestResult,
create_equity_curve_chart,
extract_ohlcv_from_text,
format_backtest_report,
run_bist_alpha_backtest,
)


class BorsaAgent:
Expand Down Expand Up @@ -664,6 +671,9 @@ async def _generate_answer(self, query: str, session_outputs: list[str], usage:
- chart: Optional plotext chart (ANSI string) if graph requested
"""
all_data = "\n\n".join(session_outputs) if session_outputs else "Veri toplanamadı."
quant_result = self._run_quant_alpha_if_requested(query, all_data)
if quant_result:
all_data = f"{all_data}\n\n{format_backtest_report(quant_result)}"

answer_prompt = f"""
Kullanıcı Sorusu: {query}
Expand All @@ -690,7 +700,9 @@ async def _generate_answer(self, query: str, session_outputs: list[str], usage:
chart_keywords = ['grafik', 'mum grafik', 'candlestick', 'chart', 'plot', 'görselleştir']
needs_chart = any(keyword in query.lower() for keyword in chart_keywords)

if needs_chart and session_outputs:
if quant_result:
chart = create_equity_curve_chart(quant_result)
elif needs_chart and session_outputs:
# Try to create chart from collected data
chart = self._create_chart_from_data(all_data, query)

Expand All @@ -716,6 +728,42 @@ async def _generate_answer(self, query: str, session_outputs: list[str], usage:
"""
return error_answer, None

def _run_quant_alpha_if_requested(self, query: str, data: str) -> Optional[BacktestResult]:
"""
Run deterministic quant alpha analysis when the user asks for alpha,
algorithmic trading, ICT, prediction, or backtesting.
"""
query_lower = query.lower()
keywords = [
"alpha",
"backtest",
"algoritmik",
"quant",
"kantitatif",
"ict",
"tahmin",
"prediction",
]
if not any(keyword in query_lower for keyword in keywords):
return None

bars = extract_ohlcv_from_text(data)
if not bars:
return None

ticker = self._extract_ticker_from_query(query)
return run_bist_alpha_backtest(bars, ticker=ticker)

def _extract_ticker_from_query(self, query: str) -> str:
"""Extract a likely BIST ticker from the user query."""
import re

ignored = {"BIST", "ICT", "RSI", "MACD", "FVG"}
for match in re.findall(r"\b[A-ZÇĞİÖŞÜ]{4,6}\b", query.upper()):
if match not in ignored:
return match
return "BIST"

def _create_chart_from_data(self, data: str, query: str) -> Optional[str]:
"""
Create plotext chart from collected data.
Expand Down
28 changes: 26 additions & 2 deletions src/borsaci/prompts.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ def get_current_date() -> str:

→ confidence: 0.95, MCP veri toplama + grafik oluşturma gerekir

❌ **Quant Alpha / Backtest / ICT Analizi**:
- "ASELS alpha backtest yap", "ICT ile tahmin üret", "algoritmik trading sinyali"
- "BIST için kantitatif tahmin", "prediction/backtest sonuçlarını göster"

→ confidence: 0.95, get_historical_data ile OHLCV topla; lokal quant alpha backtest çalıştırılır

💼 **WARREN BUFFETT ANALİZİ** (is_buffett=True):
- Yatırım analizi: "ASELS değerleme yap", "Bu hisseyi almalı mıyım?"
- Buffett tarzı ifadeler: "Warren Buffett gibi analiz et", "buffet gibi analiz et", "moat analizi yap"
Expand Down Expand Up @@ -274,7 +280,14 @@ def get_current_date() -> str:
❌ Kötü: "ASELS son fiyatlarını getir" (sadece kapanış)
✅ İyi: "ASELS OHLCV verilerini getir (get_historical_data)" (açılış, en yüksek, en düşük, kapanış)

7. **Follow-Up Soruları Tespit Et**:
7. **Quant Alpha / Backtest / ICT İstekleri**:
- Kullanıcı "alpha", "backtest", "algoritmik", "quant", "kantitatif", "ICT", "tahmin" veya
"prediction" diyorsa mutlaka get_historical_data ile OHLCV verisi topla.
- Varsayılan dönem: "5y" (backtest için yeterli geçmiş gerekir). Kullanıcı daha kısa dönem isterse açıkça istediği period'u kullan.
- Lokal sistem bu OHLCV üzerinden trend, momentum, RSI, volatilite, ICT likidite süpürmesi ve fair value gap
sinyalleriyle backtest raporu oluşturur; task sadece veriyi getirmelidir.

8. **Follow-Up Soruları Tespit Et**:

❗ ÖNEMLİ: Eğer kullanıcının sorusu önceki conversation ile ilgili basit bir takip sorusuysa,
BOŞ GÖREV LİSTESİ (tasks: []) dön. Bu durumda Answer Agent mevcut context'i kullanarak doğrudan yanıt verecektir.
Expand All @@ -291,7 +304,7 @@ def get_current_date() -> str:
- Farklı şirket/fon/varlık analizi için
- Yeni veri toplama gerektiren karşılaştırmalar için

8. **Task Bağımlılıkları (depends_on)**:
9. **Task Bağımlılıkları (depends_on)**:

❗ ÇOK ÖNEMLİ: Her task için "depends_on" alanını doldur!

Expand Down Expand Up @@ -400,6 +413,11 @@ def get_current_date() -> str:
- Pivot noktaları → get_pivot_points(symbol, market="bist")
- Teknik tarama → scan_stocks(index, preset, condition)

8. **Quant Alpha / Backtest / ICT**:
- Alpha, backtest, algoritmik trading, ICT, tahmin/prediction isteklerinde → get_historical_data(symbol, market="bist", period)
- Varsayılan period="5y"; kullanıcı daha kısa dönem isterse açıkça istediği period'u kullan
- ÖNEMLİ: OHLCV tool yanıtını mümkün olduğunca RAW JSON olarak döndür; lokal backtest motoru bu veriyi parse eder

HATA YÖNETİMİ:

- Araç çağrısı başarısızsa, alternatif araç dene
Expand Down Expand Up @@ -535,6 +553,12 @@ def get_answer_prompt() -> str:

⚠️ Grafik oluşturulamadıysa (veri uygun değilse), sadece sayısal analiz sun

8. **Quant Alpha / Backtest Raporu**:
- Toplanan verilerde "Quant Alpha + ICT Backtest" bölümü varsa bu bölüm lokal, deterministik Python hesabıdır.
- Metrikleri değiştirme veya uydurma; toplam getiri, al-tut getirisi, Sharpe, maksimum düşüş, isabet oranı ve işlem sayısını aynen kullan.
- ICT sinyallerini "likidite süpürmesi" ve "fair value gap" gibi araştırma sinyalleri olarak açıkla.
- Backtest varsayımlarını ve yatırım tavsiyesi olmadığını mutlaka belirt.

ÖRNEK YANIT (Yeni Analiz):

"ASELS hissesi son çeyrekte %15.3 gelir artışı kaydetmiştir. Net kârı bir önceki yıla göre 2.1 milyar TL'den 2.8 milyar TL'ye yükselmiştir (%33 artış).
Expand Down
Loading