FX Journal is a Flask trading journal for logging trades, reviewing performance, and organizing activity by trade account. It supports both CFD/FX workflows and futures workflows, including MT5 XLSX imports for CFD accounts and Tradovate CSV imports for futures accounts.
- Secure account system with registration, email verification, login, logout, and password reset
- Account management with email-change confirmation flow and account deletion
- Multi-account journaling with per-user trade accounts and active-account switching
- Manual trade entry and editing for CFD and futures trades
- Trade profile / strategy management with version history
- Dashboard and analytics views driven from stored trade history
- AI-generated weekly dashboard review support
- Import pipelines for:
- MT5 Positions XLSX
- Tradovate Performance CSV
- Deduplication safeguards for imported trades
- Contact form with persistence fallback when email delivery is unavailable
- Rate-limited destructive and sensitive actions
The app no longer keeps all route logic in one file.
app.pySlim app bootstrap: Flask config, extension initialization, middleware, error handlers, blueprint registrationauth_account.pyPublic/auth routes and admin access-control routesroutes/Domain blueprints for dashboard, trades, trade accounts, trade profiles, account, and contacthelpers.pyShared route helpers for timezone handling, trade account resolution, pubkey lookups, trade profile helpers, dedupe keys, and account cleanuputils.pyShared low-level utilities such as environment parsing,utcnow_naive(), and@login_requiredtrading.pyTrading math, symbol metadata, analytics, and import parsersmodels.pySQLAlchemy modelstests/Pytest coverage for trading math, import parsing, and auth token flows
//login/register/verify-email/pending/verify-email/<token>/password/forgot/password/reset/<token>/logout/privacy/terms
/dashboard/dashboard/analytics
/dashboard/trades/dashboard/trades/manage/dashboard/trades/new/dashboard/trades/<trade_pubkey>/dashboard/trades/<trade_pubkey>/edit/dashboard/trades/<trade_pubkey>/delete/dashboard/trades/bulk-delete/dashboard/trades/batch-profile/dashboard/import/dashboard/imports/delete
/dashboard/trade-accounts/dashboard/trade-accounts/switch/dashboard/trade-accounts/<trade_account_pubkey>/default/dashboard/trade-accounts/<trade_account_pubkey>/update/dashboard/trade-accounts/<trade_account_pubkey>/delete/dashboard/trade-accounts/delete-all
/dashboard/trade-profiles/dashboard/strategies/dashboard/trade-profiles/<profile_pubkey>/edit/dashboard/trade-profiles/<profile_pubkey>/archive
/account/account/email-change/cancel/account/email-change/<token>/account/password-reset-email/account/delete/contact
- Python
- Flask
- SQLAlchemy
- Flask-Migrate / Alembic
- Flask-WTF
- Flask-Limiter
- Jinja templates
- PostgreSQL in deployed environments
- SQLite fallback for local development
The app stores more than just users and trades. Core entities include:
UserTradeTradeAccountTradeProfileTradeProfileVersionCFDSymbolFuturesSymbolContactSubmission- AI review history models
Trades are tied to a user and a trade account. Futures trades can also carry a contract code. Imported trades store import signatures and dedupe keys to prevent accidental re-imports.
FX Journal includes custom parsing and math logic for trade journaling:
- PnL calculation for FX, metals, and futures
- Pip calculation for standard and JPY pairs
- Tick calculation for futures contracts
- Exit-price derivation from desired PnL
- Import profile detection before parsing
- Trade deduplication across repeated imports
The test suite includes fixed-value examples for these calculations so the expected math is visible and easy to verify.
- Create and activate a virtual environment.
- Install dependencies:
pip install -r requirements.txt- Configure environment variables.
The app reads from .env. Important variables include:
SECRET_KEYTOKEN_SALTDATABASE_URLENCRYPTION_KEYMT5_SYNC_SECRETFLASK_API_URLRATELIMIT_STORAGE_URI(optional; defaults toREDIS_URL, thenmemory://)MAX_UPLOAD_MBAPP_ENVFEEDBACK_TO_EMAIL
- Run migrations:
flask --app app db upgrade- Start the app:
flask --app app runIf DATABASE_URL is not set, the app falls back to local SQLite for development.
Pytest is configured for the project.
Run the test suite with:
pytest -vCurrent automated coverage focuses on:
- trading math
- import parsing
- auth token generation and verification
The MT5 sync/setup worker is Windows-only.
celery_app.pynow loads environment fromFXJ_ENV_FILEwhen set, then falls back to.env,FXJournal Main.env, andfxjournal.env.- If a Windows worker starts without
REDIS_URL, Celery falls back to an in-memory broker, which will not consume tasks from your shared production queue. - For a VM-hosted MT5 worker, prefer running it under a supervisor instead of a one-off terminal session.
- The MT5 Python API keeps session state at the process level, so the MT5 sync worker should run with
--pool=solo --concurrency=1. Running threaded sync workers can mix account sessions and import one MT5 account's trades into the wrong trade account.
Example restart-loop launchers:
powershell -ExecutionPolicy Bypass -File .\scripts\windows\run_mt5_setup_worker.ps1powershell -ExecutionPolicy Bypass -File .\scripts\windows\run_mt5_sync_worker.ps1These start dedicated MT5 Celery workers and restart them if the process exits.
FX Journal is built to stay practical rather than overloaded:
- clean journaling workflow
- account-aware organization
- understandable analytics
- import support for common retail platforms
- maintainable Flask structure with shared helpers and blueprints
- Flash messages are used for one-time UI feedback after redirects.
- Sensitive POST endpoints are rate limited.
- Public and authenticated flows share the same app but are organized by domain.
Note: Portions of this README were refined with assistance from AI tools (ChatGPT/OpenAI Codex).