Share Agent is an end-to-end stock
analysis and automated trading platform for BIST Katılım Endeksi (XKTUM), the
Islamic-compliance index of Borsa Istanbul. Three trading agents (short, medium,
and long horizon), each capitalized at 100,000 TRY, compute a weighted signal
score (-100 to +100) from 12 technical indicators (RSI, MACD, SMA/EMA, Bollinger
Bands, Stochastic, VWAP, OBV, ADX, CCI, MFI, ROC, Volume) and fundamental
ratios, then execute against the Algolab (Deniz Yatirim) API. The backend is
Python 3.12 / FastAPI following a hexagonal ports-and-adapters layout.
Agent state is persisted to PostgreSQL (agent_portfolios, agent_positions,
agent_trades) so agents survive container restarts. The platform is live at
share-agent.rollingcatsoftware.com
on a Hetzner CX43 server. The mobile client is Kotlin Multiplatform with Compose
(Android ships; iOS is a five-line stub).
The domain core is kept free of framework and IO concerns. The three primary
ports are Python ABCs: PriceProvider (OHLCV history and current price),
FinancialProvider (fundamentals and balance-sheet items), and ShareRepository
(persistence). Adapters that implement those ports include IsYatirimAdapter
(primary price data, end-of-day bars), YahooFinanceAdapter (fallback for
history plus intraday refresh every five minutes during market hours),
KapAdapter (fundamental data from the KAP regulatory platform), AlgolabAdapter
(order execution, disarmed by default and requiring two flags to arm for live
trading), PostgresShareRepository backed by a TimescaleDB hypertable for price
history, and RedisCacheAdapter for symbol-list and computation caches.
FallbackPriceProvider implements PriceProvider itself, takes a prioritized
list of providers, and tries them in order with bounded timeout and retries per
provider. The circuit breaker is a separate pre-trade gate on the live-order
path, not part of FallbackPriceProvider. When the primary İs Yatirim feed
returned malformed data for two days, I changed one line in the wiring and
YahooFinanceAdapter took over; the 12 indicators and signal scorer saw no
difference.
XKTUM compliance filtering runs before any signal is acted on. A company must
pass: debt ratio below 33%, interest-bearing income below 5% of total revenue,
and a buffer-rule flag for companies near those limits. These thresholds come
from KAP via KapAdapter. The signal scorer returns a numeric score and a reason
vector; classification (BUY/SELL/HOLD and thresholds) is left to each downstream
consumer so the domain does not lock in one interpretation.
The scheduler is APScheduler running inside the FastAPI process, with 10 scheduled jobs covering morning signal refresh (10:05), morning trade window (10:15), afternoon refresh (14:15), afternoon trade window (14:30), pre-close snapshot (17:30), evening price ingestion (18:30), evening batch signals (18:45), continuous intraday price refresh every five minutes during market hours, stop-loss monitoring every ten minutes, and a nightly data-quality check. All jobs run weekdays only on Europe/Istanbul time. CI runs ruff (E, F, I, N, W) and pytest on the backend, Gradle for the Android build, and a Docker build-push-deploy workflow on merge.
Repository: github.com/gultekinahmetabdullah/Share-Agent. Live deploy: share-agent.rollingcatsoftware.com.
- architecture
- hexagonal
- trading
- fastapi