CLI Trading Journal
The trading-journal is a lightweight offline trading journal accessible via your machine's command line (macOS: Terminal, Windows: PowerShell) intended for discretionary traders to track and analyse their trading strategy, or trading strategy portfolio, through a quantitative lens.
Content Page
Repository Tree
Trading-Journal/
├── src/
│ └── trading_journal/
│ ├── __init__.py # package version
│ ├── main.py # Typer CLI entrypoint; defines all `trading-journal` commands
│ ├── database.py # SQLite connection, table creation, trade CRUD operations
│ ├── model.py # TableInputs class; validates/structures trade entry data
│ ├── metrics.py # performance metric calculations
│ ├── simulation.py # permutation tests, binomial win/loss tree matrix, and Monte Carlo/Markov equity simulation
│ └── fx_replay.py # imports and standardises fx-replay .csv exports into the journal db
├── tests/
│ ├── test_database.py # isolated SQLite tests for journal building and error handling
│ └── test_metrics.py # tests for performance metric functions
├── images/ # screenshots used in documentation
├── pyproject.toml # package metadata, dependencies, CLI entry point
├── uv.lock # locked dependency versions (uv)
├── LICENSE # MIT license
└── README.md # this file
Features
The table below lists the complete set of available command line functions, their command class, and their use case. Examples of function implementation and methodology can be found in the Usage chapter below.
| Command | Command Class | Description |
|---|---|---|
tables |
TABLE | list of available tables in the trading_journal.db database |
show-fx-replay |
FX REPLAY | prints standardised fx-replay database if imported |
load-fx-replay |
FX REPLAY | imports trading journal downloaded as type .csv from fx-replay, and appends to trading_journal.db |
show |
JOURNAL VIEW | prints trading journal table if it exists in trading_journal.db |
get-trade |
JOURNAL VIEW | gets trade from trading journal table indexed by trade-id |
add |
JOURNAL MOD | appends a new trade to strategy or strategy portfolio with trade metadata to specified trading journal table in trading_journal.db. Also used as the initialisation function for a new trading journal table in trading_journal.db with single or multiple concurrent strategies. |
update |
JOURNAL MOD | modifies an existing trade using trade-id in specified trading journal table and aligns all subsequent entries if any exist |
trade-delete |
JOURNAL MOD | deletes an existing trade in trading journal table using trade-id |
delete-all |
JOURNAL MOD | permanently drops the specified trading journal table from trading_journal.db, after confirmation |
save |
EXPORT | exports specified trading-journal table locally as .csv |
nw |
METRIC | strategy or strategy portfolio number of winning trades in specified trading journal table |
nl |
METRIC | strategy or strategy portfolio number of losing trades in specified trading journal table |
gf |
METRIC | strategy or strategy portfolio growth-factor |
ror |
METRIC | strategy or strategy portfolio rate-of-return |
pnl |
METRIC | strategy or strategy portfolio profit and loss in account currency |
summary |
SUMMARY | table containing essential summary statistics calculated using specified trading journal table at strategy or strategy portfolio level |
prop-firm-check |
SUMMARY | assesses if strategy or strategy portfolio pass defined prop-firm evaluation requirements |
equity |
PLOT | plots strategy or strategy portfolio equity curve using specified trading journal table |
drawdown |
PLOT | plots strategy or strategy portfolio drawdown curve using specified trading journal table |
win-matrix |
PLOT | plots a simulated strategy or strategy portfolio binomial win/loss tree matrix |
rolling-sharpe |
PLOT | plots rolling strategy or strategy portfolio annualised Sharpe ratio using specified trading journal table |
trade-freq |
PLOT | plots strategy or strategy portfolio aggregated trade counts across unique days, days of week, or days of month from specified trading journal table |
trade-agg |
PLOT | plots strategy or strategy portfolio returns aggregated at day or month frequency from specified trading journal table |
permutation-test |
SIMULATION | runs an empirical Monte Carlo permutation hypothesis test using permutations of strategy or strategy portfolio signals from specified trading journal table |
pnl-density |
SIMULATION | approximates the joint expectation of strategy or strategy portfolio returns from a specified trading journal table using a kernel density estimator |
trade-independence |
SIMULATION | tests whether a strategy or strategy portfolio's trade state transition matrix implies trade dependence using a chi-square test |
markov-sim |
SIMULATION | simulates strategy or strategy portfolio equity if trades display dependence using specified trading journal table |
Installation
Below we list different ways to download and use the trading-journal package.
Using uv
To download the latest version of the CLI tool directly from PyPI (Python Package Index), run the following command in your terminal/command-shell.
>>> uv tool install trading-journal
Using uv for package installation is recommended for speed. To check if you have uv in your active environment, run pip show uv. If you get WARNING: Package(s) not found: uv printed in console, install uv using pip install uv.
From Source
If you would like to use the most up-to-date version of trading-journal, which may not necessarily have been pushed as a version update to PyPI, run the following commands to clone the repository locally.
>>> repo='https://github.com/AmjadSaidam/Trading-Journal.git'
>>> git clone $repo && cd $repo
>>> uv tool install .
Quickstart
After confirming the CLI is downloaded and accessible by running pip show trading-journal, run the following command to get a list of all available commands.
>>> trading-journal --help
Initialise the database and first trading journal by calling the add command with all required fields. To see which fields a command requires, use the --help flag. Calling trading-journal add --help we get
Creating a Trading Journal Table and Adding a New Trade
So we must specify account_balance, percentage_risked, entry, stop_loss and take_profit (Required Parameters). Optional Parameters include
--table-name= the name of the trading journal table, defaultjournal_1--number-strategies= the number of strategies we trade under the same account (usually called once on initialisation), with default 1--strategy-number= the strategy number associated with the trade metadata, default 1--weight-set= the weighted allocation of initial account balance per strategy (usually called once on initialisation) with default 1 if--number-strategies=1, otherwise equal allocation--print-table= if the trading journal table should be printed after we append a new trade, defaultTrue
>>> trading-journal add 1000.0 0.01 100.0 90.0 110.0
To close the trade we must define the exit price
>>> trading-journal update '1' '{"exit": 110.0}'
After defining the exit price, returns, final_equity, risk_reward_mult and result are auto-populated.
Usage
The following chapter presents default case examples on how to use each available function. Note the --help method can be called on any command, e.g. trading-journal command --help, to list the full set of required and optional inputs the command takes.
TABLE Functions
tables: Lists all trading journal tables currently stored in trading_journal.db. Following the example above we have.
>>> trading-journal tables
['journal_1']
journal_1 is the default trading journal table name, created automatically on the first add command.
FX REPLAY Function
The fx-replay class of commands is intended specifically to import fx-replay exported data.
load-fx-replay: imports, standardises and stores fx-replay exported data as a new fx-replay journal table in trading_journal.db.
>>> trading-journal load-fx-replay 'PATH_TO_DOWNLOADED_FX_REPLAY_DATA'
show-fx-replay: Prints the fx-replay trading journal table.
JOURNAL VIEW Functions
show: Prints any non-fx-replay based trading journal table to console (called by default on all JOURNAL MOD functions)
>>> trading-journal show
...
get-trade: Prints a specific trade, indexed by trade_id
>>> trading-journal get-trade '1'
...
JOURNAL MOD Functions
These are the core functions that let you create, configure, edit and delete trading journal tables
add: As illustrated in the Quickstart example, add can be used to create a new trading-journal table with a custom specification, otherwise the function is simply used to append new trades to the listed trading journal table.
>>> trading-journal add 1000.0 0.01 100.0 90.0 110.0 --number-strategies 3 --strategy-number 3
The function above will create a trading journal table journal_1 that bookkeeps 3 strategies, with each strategy having an initial capital allocation of $1/3 \times 1000.0$. Each strategy will risk a weighted fraction of $1%$ proportional to the current strategy allocation as a fraction of account balance. In our example above, we open a trade on strategy 3, with entry price $100.0$, stop-loss price $90.0$ and take-profit $110.0$; we risk $0.01 \times 1/3$. As we append more trades to each strategy, the fraction risked per strategy will scale linearly with strategy account balance — for example, if strategy 3 were to have an allocation of $1000.0$ and the total account balance is $1500$, the fraction risked would be $0.01 \times 1/1.5$, so winning is rewarded. This method ensures that, no matter how allocation is distributed, the maximum fraction risked is capped at percentage_risked, $1%$. Currently there is no other way to change this multi strategy risk logic.
update: This function is used to edit existing trades in the trading journal table, indexed by trade id. The following keys are editable.
date_added,date_completed,account_balance,percentage_risked_initial,entry,stop_loss,take_profitandexit
>>> trading-journal update '1' '{"entry": 101.0}'
Note that the update dict must be of the form '{"key": type(key),...}'
trade-delete: Deletes the trade corresponding to the listed trade id from the specified strategy journal table.
>>> trading-journal trade-delete '1'
delete-all: Permanently drops the specified trading journal table from the database. Prompts user to confirm deletion by answering [y/N].
>>> trading-journal delete-all
EXPORT Functions
save: Exports the specified trading journal table as a .csv file to the specified local folder path
>>> trading-journal save 'FOLDER_SAVE_PATH'
METRIC Functions
nw: Number of winning trades
nl: Number of losing trades
gf: Equity growth factor. This is the multiple of the initial account balance that equals the current account equity
ror: Rate-of-return — profit in percentage terms, i.e. the growth factor less $1$.
pnl: The profit/loss in account currency
>>> trading-journal nw
>>> trading-journal nl
>>> trading-journal gf 1000.0
>>> trading-journal ror 1000.0
>>> trading-journal pnl 1000.0
SUMMARY Functions
summary: Prints a table of basic summary statistics from the trading journal table
>>> trading-journal summary 1000.0
prop-firm-check: Prints a table comparing current trading journal table prop firm statistics against their benchmark values, printing True if the realised value passes the benchmark statistic, False otherwise.
>>> trading-journal prop-firm-check
PLOT Functions
equity: Plots the equity curve given a starting account balance.
>>> trading-journal equity 1000.0
drawdown: Plots the drawdown (equity underwater plot)
>>> trading-journal drawdown
win-matrix: Plots the probability of observing $j$ winning trades out of $i$ total future trades in any order, for all $j$ and $i$. This is effectively a full binomial tree in matrix form, and helps us understand how many trades we can expect to lose in the next couple of trades. The example below requires the number of total future trades, $5$, and the maximum number of wins to plot, $4$.
>>> trading-journal win-matrix 5 4
rolling-sharpe: This is the annualised historical Sharpe ratio, calculated on a fixed 14-day rolling window by default (configurable via --window). Returns are up sampled to a daily frequency, and days with no trading are assigned a $0$ return. The function has no required fields.
>>> trading-journal rolling-sharpe
trade-freq: Plots the trade frequency given unique entries of some aggregation frequency, default is --aggregation day, where the function plots the trade frequency on each unique day in the year. To better illustrate, we aggregate by --aggregation day_of_week, which plots trade frequency on each unique day of the week.
>>> trading-journal trade-freq --aggregation 'day_of_week'
trade-agg: Similar to trade-freq, although it plots the returns aggregated by --aggregation day (default) or --aggregation month. Instead of unique entries per aggregation, it plots the sum of returns in the aggregation window, e.g. sum of daily returns or sum of monthly returns.
>>> trading-journal trade-agg
SIMULATION Functions
permutation-test: A Monte Carlo Permutation Test (MCPT) is a non-parametric type of hypothesis test that tests if the observed test statistic is significant at the $\alpha$ significance level. The test is empirical and makes no distribution assumption on the observed data; rather, we assume the current signal is independent of past returns, therefore the signal and returns are exchangeable (the joint density of signals and returns is identical for any permutation of the signal). This means any realised path of signal and returns could have been observed. To test if the observed path is not realised by random chance, we require the probability of observing a test-statistic, e.g. the Sharpe ratio, at least as extreme as the test-statistic derived from the observed data to be less than that associated with some critical value. Simulating all $n!$ exchangeable paths is not feasible, however the law of large numbers guarantees for sufficiently large $n$, as $n \rightarrow \infty$, the empirical p value approaches its population value with probabilistic certainty.
>>> trading-journal permutation-test 'sharpe' 1000.0
trade-independence: Table that prints the outcome of a chi-squared statistic and p-value for the hypothesis test of independence of the observed trade frequencies in the trade contingency table. Rejection of the null hypothesis implies a future trade outcome is dependent on the current trade outcome, with probability given by the Markov transition matrix.
>>> trading-journal trade-independence
pnl-density: Plots a 3D surface approximation of the joint conditional expectation of returns given the Sharpe ratio (annualised) and volatility. Both the Sharpe ratio and volatility are calculated on a rolling basis, and we use the kernel-density estimator to approximate the expectation.
>>> trading-journal pnl-density
markov-sim: If trade-independence rejects the null hypothesis, given an initial state, simulates future equity paths using the long run state transition matrix probabilities from the current state. Each trade's returns are sampled from a Student's t-distribution with estimators (mean and variance) equal to the current trade state's empirical in-sample estimates. To model real-world market dynamics, volatility clustering, return auto-correlation and transaction costs are also factored into current return estimates. A table of simulation statistics is also printed in the console. If we fail to reject the null hypothesis defined by trade-independence, the hypothesis test result is printed to the console.
>>> trading-journal markov-sim
Future Updates
- Integration of uploaded time-indexed returns
License
MIT - see LICENSE # Trading-Journal
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file trading_journal-0.1.0.tar.gz.
File metadata
- Download URL: trading_journal-0.1.0.tar.gz
- Upload date:
- Size: 28.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a10d5c245d76e2ba5b93b6f12cb93d45ed95b80194aa37d6cf84b02e542cc4b0
|
|
| MD5 |
b85e79792c391fab70ccc45713f19872
|
|
| BLAKE2b-256 |
4b07fd843285fef9879241bf8a27cc6365e6b4ca21811b8e69ceb312f840a6bb
|
File details
Details for the file trading_journal-0.1.0-py3-none-any.whl.
File metadata
- Download URL: trading_journal-0.1.0-py3-none-any.whl
- Upload date:
- Size: 31.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5af7847edf43443856ebd64dc976c94bab835ab57175d870696d9b325508862
|
|
| MD5 |
f000be8352f6d0392fea000ef0e7aba3
|
|
| BLAKE2b-256 |
a4ec50e78af58e5a7f6128f4cbd24e885c4d3f3b06287f644b4dcafd7fa2482f
|