Turn plain-language trading strategies into executable rules, then backtest them on BIST 100 and commodity data — end to end.
Overview · Features · Tech Stack · Architecture · Installation · Usage
Prompt-to-Code lets you write a trading idea the way you would say it — in English or Turkish — and turns it into a structured, testable rule. A natural-language sentence such as "Buy THYAO when RSI drops below 35" is parsed by an AI model into a JSON rule, historical price data and technical indicators are fetched, a commission-aware backtest is run, and the results are returned as metrics and chart-ready data.
"Buy THYAO when RSI drops below 35" → AI parses the rule → data is fetched → strategy is backtested → metrics and charts are returned.
| Natural language to rules | Gemini + Pydantic convert a sentence into a structured JSON rule |
| Bilingual input | Understands both English and Turkish phrasing |
| Local fallback parser | A regex engine handles common patterns when the API is unavailable |
| Persistent cache | Parsed rules are stored on disk, so repeated strategies cost no quota |
| 20+ indicators | RSI, Stochastic, SMA/EMA (four periods), MACD, ADX, Bollinger Bands, volume |
| Realistic backtest | 0.1% commission, 10,000 ₺ start, next-bar-open fills (no look-ahead) |
| Risk management | Optional stop-loss and take-profit, triggered intrabar at the price level |
| Multi-symbol compare | Run one strategy across several tickers and rank them by return |
| Rich metrics | Buy & hold benchmark, alpha, Sharpe, profit factor, exit-reason breakdown |
| Modern UI | TradingView candlesticks, BUY/SELL markers, equity-curve tab |
| Smart symbols | BIST tickers get .IS automatically; commodities map to yfinance symbols |
flowchart LR
U([User: plain-language strategy]) --> NLP
subgraph BE["FastAPI Backend"]
direction TB
NLP[nlp_parser<br/>Gemini + Pydantic<br/>+ local fallback] --> DATA[data_engine<br/>yfinance + indicators]
DATA --> BT[backtest_engine<br/>simulation + metrics]
end
BT --> API[/api/run-strategy<br/>JSON: chart + metrics]
API --> FE([Frontend<br/>candles, BUY/SELL, equity])
CACHE[(rule_cache.json)] -.-> NLP
NLP -.-> CACHE
Flow: text → rule (NLP) → data + indicators → commission-aware backtest → JSON → charts.
prompt-to-code/
├── data_engine.py # yfinance data + 20+ technical indicators (cached)
├── nlp_parser.py # Gemini/regex: text -> TradingRule + persistent cache
├── backtest_engine.py # backtest sim: fills, stop/target, metrics
├── compare_engine.py # run one strategy across many symbols, ranked
├── app.py # FastAPI service + CORS + static frontend
├── frontend/
│ └── index.html # modern UI (Lightweight Charts)
├── tests/ # network-free pytest suite
├── assets/ # README images (SVG)
├── requirements.txt # pinned runtime dependencies
├── requirements-dev.txt # test dependencies (pytest, httpx)
└── .env.example # environment variable template
git clone https://github.com/noutrexx/prompt-to-code.git
cd prompt-to-code
pip install -r requirements.txtCreate a .env file (see .env.example):
GEMINI_API_KEY=your_api_key
CORS_ORIGINS=http://127.0.0.1:8000,http://localhost:8000
RATE_LIMIT_PER_MINUTE=10
MAX_CONCURRENT_STRATEGIES=2
MAX_REQUEST_BODY_BYTES=4096Get a free key from Google AI Studio. The app also runs without a key — in that case the local regex parser is used.
python app.py # or: uvicorn app:app --reloadOpen http://127.0.0.1:8000/ in your browser.
pip install -r requirements-dev.txt
pytestThe suite is network-free (synthetic OHLC data) and covers the backtest engine and the API guards.
This expensive endpoint is protected by:
- an allowlisted CORS origin list;
- a maximum 500-character strategy and 4 KB request body;
- a per-client request limit, defaulting to 10 requests per minute;
- a concurrent strategy execution limit, defaulting to 2.
Tune these values through environment variables before deployment. Requests over the rate
limit return 429; requests above current execution capacity return 503.
The built-in limiter is process-local. Multi-instance production deployments should also enforce a shared rate limit and abuse protection at the API gateway or reverse proxy.
Request:
{ "strateji_metni": "Buy THYAO when RSI drops below 35" }Response (excerpt):
{
"asset": "THYAO.IS",
"rule": { "conditions": [ { "indicator": "RSI", "operator": "less_than", "value": 35 } ], "action": "BUY" },
"metrics": { "toplam_kar_zarar_pct": 39.34, "win_rate_pct": 80.0, "max_drawdown_pct": -21.07, "toplam_islem_sayisi": 5 },
"signals": [ { "date": "2024-08-09", "side": "BUY", "price": 294.77 } ],
"candles": [ ... ], "sma50": [ ... ], "sma200": [ ... ], "equity": [ ... ]
}Runs one strategy across multiple symbols (max 5) and returns them ranked by total return.
Request:
{ "strateji_metni": "Buy when RSI drops below 35", "semboller": ["THYAO.IS", "ASELS.IS", "GARAN.IS"] }Response (excerpt):
{
"rule": { "conditions": [ ... ], "action": "BUY" },
"results": [
{ "symbol": "ASELS.IS", "ok": true, "rank": 1, "metrics": { "toplam_kar_zarar_pct": 41.2 } },
{ "symbol": "THYAO.IS", "ok": true, "rank": 2, "metrics": { "toplam_kar_zarar_pct": 18.7 } },
{ "symbol": "BADSYM", "ok": false, "error": "veri bulunamadi" }
]
}Failing symbols are isolated (ok: false) and sorted last, so one bad ticker never aborts the comparison.
Returns service status and NLP mode (Gemini or local fallback).
| Metric | Description |
|---|---|
| Total P/L (%) | 10,000 ₺ start, 0.1% commission per trade |
| Buy & Hold (%) | Passive return over the same period (benchmark) |
| Alpha (%) | Strategy return minus buy & hold — does it actually add value? |
| Sharpe | Annualized risk-adjusted return from the equity curve |
| Win Rate (%) | Share of profitable trades |
| Profit Factor | Gross profit ÷ gross loss (null when there are no losing trades) |
| Avg Win / Loss (%) | Mean return of winning and losing trades |
| Max Drawdown (%) | Deepest peak-to-trough decline |
| Exit reasons | Breakdown of exits: signal / stop_loss / take_profit / end_of_data |
| Trades | Number of completed buy/sell round trips |
Trades execute at the next bar's open after a signal (no look-ahead bias). Optional stop-loss / take-profit levels are checked intrabar against the bar's high/low.
- Separate user-defined entry and exit rules
- Next-bar-open entry (look-ahead correction)
- Stop-loss / take-profit risk management
- Multi-symbol / multi-strategy comparison
- Richer metrics (buy & hold, alpha, Sharpe, profit factor)
- Unit tests (pytest)
This project is for educational and research purposes only. Past performance does not guarantee future results, and nothing produced here constitutes financial advice.
Natural-language algorithmic trading · BIST 100 + Commodities