trading-journal 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,395 @@
1
+ Metadata-Version: 2.4
2
+ Name: trading-journal
3
+ Version: 0.1.0
4
+ Summary: CLI trading journal with performance metrics, prop-firm benchmarking, and Monte Carlo / Markov chain simulation of strategy returns
5
+ Keywords: trading,journal,cli,finance,backtesting,risk-management
6
+ Author: Amjad Saidam
7
+ Author-email: Amjad Saidam <amjadsaidama@gmail.com>
8
+ License-Expression: MIT
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Financial and Insurance Industry
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Office/Business :: Financial :: Investment
18
+ Requires-Dist: typer
19
+ Requires-Dist: rich
20
+ Requires-Dist: numpy
21
+ Requires-Dist: pandas
22
+ Requires-Dist: matplotlib
23
+ Requires-Dist: plotly
24
+ Requires-Dist: seaborn
25
+ Requires-Dist: scipy
26
+ Requires-Python: >=3.10
27
+ Description-Content-Type: text/markdown
28
+
29
+ # CLI Trading Journal
30
+
31
+ 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.
32
+
33
+ ![header](/images/readme_header.png)
34
+
35
+ ## Content Page
36
+
37
+ - [Repository Tree](#repository-tree)
38
+ - [Features](#features)
39
+ - [Installation](#installation)
40
+ - [Using uv](#using-uv)
41
+ - [From Source](#from-source)
42
+ - [Quickstart](#quickstart)
43
+ - [Creating a Trading Journal Table and Adding a New Trade](#creating-a-trading-journal-table-and-adding-a-new-trade)
44
+ - [Usage](#usage)
45
+ - [TABLE Functions](#table-functions)
46
+ - [FX REPLAY Function](#fx-replay-function)
47
+ - [JOURNAL VIEW Functions](#journal-view-functions)
48
+ - [JOURNAL MOD Functions](#journal-mod-functions)
49
+ - [EXPORT Functions](#export-functions)
50
+ - [METRIC Functions](#metric-functions)
51
+ - [SUMMARY Functions](#summary-functions)
52
+ - [PLOT Functions](#plot-functions)
53
+ - [SIMULATION Functions](#simulation-functions)
54
+ - [Future Updates](#future-updates)
55
+
56
+ ## Repository Tree
57
+
58
+ ```
59
+ Trading-Journal/
60
+ ├── src/
61
+ │ └── trading_journal/
62
+ │ ├── __init__.py # package version
63
+ │ ├── main.py # Typer CLI entrypoint; defines all `trading-journal` commands
64
+ │ ├── database.py # SQLite connection, table creation, trade CRUD operations
65
+ │ ├── model.py # TableInputs class; validates/structures trade entry data
66
+ │ ├── metrics.py # performance metric calculations
67
+ │ ├── simulation.py # permutation tests, binomial win/loss tree matrix, and Monte Carlo/Markov equity simulation
68
+ │ └── fx_replay.py # imports and standardises fx-replay .csv exports into the journal db
69
+ ├── tests/
70
+ │ ├── test_database.py # isolated SQLite tests for journal building and error handling
71
+ │ └── test_metrics.py # tests for performance metric functions
72
+ ├── images/ # screenshots used in documentation
73
+ ├── pyproject.toml # package metadata, dependencies, CLI entry point
74
+ ├── uv.lock # locked dependency versions (uv)
75
+ ├── LICENSE # MIT license
76
+ └── README.md # this file
77
+ ```
78
+
79
+ ## Features
80
+
81
+ 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](#usage) chapter below*.
82
+
83
+ | Command | Command Class | Description |
84
+ | ------- | ------------- | ----------- |
85
+ | `tables` | TABLE | list of available tables in the `trading_journal.db` database |
86
+ | `show-fx-replay` | FX REPLAY | prints standardised fx-replay database if imported |
87
+ | `load-fx-replay` | FX REPLAY | imports trading journal downloaded as type `.csv` from fx-replay, and appends to `trading_journal.db` |
88
+ | `show` | JOURNAL VIEW | prints trading journal table if it exists in `trading_journal.db` |
89
+ | `get-trade` | JOURNAL VIEW | gets trade from trading journal table indexed by trade-id |
90
+ | `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. |
91
+ | `update` | JOURNAL MOD | modifies an existing trade using trade-id in specified trading journal table and aligns all subsequent entries if any exist |
92
+ | `trade-delete` | JOURNAL MOD | deletes an existing trade in trading journal table using trade-id |
93
+ | `delete-all` | JOURNAL MOD | permanently drops the specified trading journal table from `trading_journal.db`, after confirmation |
94
+ | `save` | EXPORT | exports specified trading-journal table locally as `.csv` |
95
+ | `nw` | METRIC | strategy or strategy portfolio number of winning trades in specified trading journal table |
96
+ | `nl` | METRIC | strategy or strategy portfolio number of losing trades in specified trading journal table |
97
+ | `gf` | METRIC | strategy or strategy portfolio growth-factor |
98
+ | `ror` | METRIC | strategy or strategy portfolio rate-of-return |
99
+ | `pnl` | METRIC | strategy or strategy portfolio profit and loss in account currency |
100
+ | `summary` | SUMMARY | table containing essential summary statistics calculated using specified trading journal table at strategy or strategy portfolio level |
101
+ | `prop-firm-check` | SUMMARY | assesses if strategy or strategy portfolio pass defined prop-firm evaluation requirements |
102
+ | `equity` | PLOT | plots strategy or strategy portfolio equity curve using specified trading journal table |
103
+ | `drawdown` | PLOT | plots strategy or strategy portfolio drawdown curve using specified trading journal table |
104
+ | `win-matrix` | PLOT | plots a simulated strategy or strategy portfolio binomial win/loss tree matrix |
105
+ | `rolling-sharpe` | PLOT | plots rolling strategy or strategy portfolio annualised Sharpe ratio using specified trading journal table |
106
+ | `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 |
107
+ | `trade-agg` | PLOT | plots strategy or strategy portfolio returns aggregated at day or month frequency from specified trading journal table |
108
+ | `permutation-test` | SIMULATION | runs an empirical Monte Carlo permutation hypothesis test using permutations of strategy or strategy portfolio signals from specified trading journal table |
109
+ | `pnl-density` | SIMULATION | approximates the joint expectation of strategy or strategy portfolio returns from a specified trading journal table using a kernel density estimator |
110
+ | `trade-independence` | SIMULATION | tests whether a strategy or strategy portfolio's trade state transition matrix implies trade dependence using a chi-square test |
111
+ | `markov-sim` | SIMULATION | simulates strategy or strategy portfolio equity if trades display dependence using specified trading journal table |
112
+
113
+ ## Installation
114
+
115
+ Below we list different ways to download and use the trading-journal package.
116
+
117
+ ### Using uv
118
+
119
+ To download the latest version of the CLI tool directly from PyPI (Python Package Index), run the following command in your terminal/command-shell.
120
+
121
+ ```
122
+ >>> uv tool install trading-journal
123
+ ```
124
+
125
+ 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`.
126
+
127
+ ### From Source
128
+
129
+ 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.
130
+
131
+ ```
132
+ >>> repo='https://github.com/AmjadSaidam/Trading-Journal.git'
133
+ >>> git clone $repo && cd $repo
134
+ >>> uv tool install .
135
+ ```
136
+
137
+ ## Quickstart
138
+
139
+ 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.
140
+
141
+ ```
142
+ >>> trading-journal --help
143
+ ```
144
+
145
+ ![cli all commands](images/cli_all_example.png)
146
+
147
+ 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
148
+
149
+ ### Creating a Trading Journal Table and Adding a New Trade
150
+
151
+ ![cli add help](images/cli_add_help.png)
152
+
153
+ So we must specify `account_balance`, `percentage_risked`, `entry`, `stop_loss` and `take_profit` (Required Parameters). Optional Parameters include
154
+
155
+ - `--table-name` = the name of the trading journal table, default `journal_1`
156
+ - `--number-strategies` = the number of strategies we trade under the same account (usually called once on initialisation), with default 1
157
+ - `--strategy-number` = the strategy number associated with the trade metadata, default 1
158
+ - `--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
159
+ - `--print-table` = if the trading journal table should be printed after we append a new trade, default `True`
160
+
161
+ ```
162
+ >>> trading-journal add 1000.0 0.01 100.0 90.0 110.0
163
+ ```
164
+
165
+ ![cli add example](images/cli_add_example.png)
166
+
167
+ To close the trade we must define the exit price
168
+
169
+ ```
170
+ >>> trading-journal update '1' '{"exit": 110.0}'
171
+ ```
172
+
173
+ ![cli update example](images/cli_update_example.png)
174
+
175
+ After defining the exit price, `returns`, `final_equity`, `risk_reward_mult` and `result` are auto-populated.
176
+
177
+ ## Usage
178
+
179
+ 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.
180
+
181
+ ### TABLE Functions
182
+
183
+ `tables`: Lists all trading journal tables currently stored in `trading_journal.db`. Following the example above we have.
184
+
185
+ ```
186
+ >>> trading-journal tables
187
+ ['journal_1']
188
+ ```
189
+
190
+ `journal_1` is the default trading journal table name, created automatically on the first `add` command.
191
+
192
+ ### FX REPLAY Function
193
+
194
+ The fx-replay class of commands is intended specifically to import fx-replay exported data.
195
+
196
+ `load-fx-replay`: imports, standardises and stores fx-replay exported data as a new fx-replay journal table in `trading_journal.db`.
197
+
198
+ ```
199
+ >>> trading-journal load-fx-replay 'PATH_TO_DOWNLOADED_FX_REPLAY_DATA'
200
+ ```
201
+
202
+ `show-fx-replay`: Prints the fx-replay trading journal table.
203
+
204
+ ### JOURNAL VIEW Functions
205
+
206
+ `show`: Prints any non-fx-replay based trading journal table to console (called by default on all JOURNAL MOD functions)
207
+
208
+ ```
209
+ >>> trading-journal show
210
+ ...
211
+ ```
212
+
213
+ `get-trade`: Prints a specific trade, indexed by `trade_id`
214
+
215
+ ```
216
+ >>> trading-journal get-trade '1'
217
+ ...
218
+ ```
219
+
220
+ ### JOURNAL MOD Functions
221
+
222
+ These are the core functions that let you create, configure, edit and delete trading journal tables
223
+
224
+ `add`: As illustrated in the [Quickstart](#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.
225
+
226
+ ```
227
+ >>> trading-journal add 1000.0 0.01 100.0 90.0 110.0 --number-strategies 3 --strategy-number 3
228
+ ```
229
+
230
+ 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*.
231
+
232
+ `update`: This function is used to edit existing trades in the trading journal table, indexed by trade id. The following keys are editable.
233
+
234
+ - `date_added`, `date_completed`, `account_balance`, `percentage_risked_initial`, `entry`, `stop_loss`, `take_profit` and `exit`
235
+
236
+ ```
237
+ >>> trading-journal update '1' '{"entry": 101.0}'
238
+ ```
239
+
240
+ Note that the update dict must be of the form `'{"key": type(key),...}'`
241
+
242
+
243
+ `trade-delete`: Deletes the trade corresponding to the listed trade id from the specified strategy journal table.
244
+
245
+ ```
246
+ >>> trading-journal trade-delete '1'
247
+ ```
248
+
249
+ `delete-all`: Permanently drops the specified trading journal table from the database. *Prompts user to confirm deletion by answering* `[y/N]`.
250
+
251
+ ```
252
+ >>> trading-journal delete-all
253
+ ```
254
+
255
+ ### EXPORT Functions
256
+
257
+ `save`: Exports the specified trading journal table as a `.csv` file to the specified local folder path
258
+
259
+ ```
260
+ >>> trading-journal save 'FOLDER_SAVE_PATH'
261
+ ```
262
+
263
+ ### METRIC Functions
264
+
265
+ `nw`: Number of winning trades
266
+
267
+ `nl`: Number of losing trades
268
+
269
+ `gf`: Equity growth factor. This is the multiple of the initial account balance that equals the current account equity
270
+
271
+ `ror`: Rate-of-return — profit in percentage terms, i.e. the growth factor less $1$.
272
+
273
+ `pnl`: The profit/loss in account currency
274
+
275
+ ```
276
+ >>> trading-journal nw
277
+ >>> trading-journal nl
278
+ >>> trading-journal gf 1000.0
279
+ >>> trading-journal ror 1000.0
280
+ >>> trading-journal pnl 1000.0
281
+ ```
282
+
283
+ ### SUMMARY Functions
284
+
285
+ `summary`: Prints a table of basic summary statistics from the trading journal table
286
+
287
+ ```
288
+ >>> trading-journal summary 1000.0
289
+ ```
290
+
291
+ ![cli summary summary](images/cli_summary_summary.png)
292
+
293
+ `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.
294
+
295
+ ```
296
+ >>> trading-journal prop-firm-check
297
+ ```
298
+
299
+ ![cli prop firm check](images/cli_prop_firm_check_summary.png)
300
+
301
+ ### PLOT Functions
302
+
303
+ `equity`: Plots the equity curve given a starting account balance.
304
+
305
+ ```
306
+ >>> trading-journal equity 1000.0
307
+ ```
308
+
309
+ ![cli equity plot](images/cli_equity_plot.png)
310
+
311
+ `drawdown`: Plots the drawdown (equity underwater plot)
312
+
313
+ ```
314
+ >>> trading-journal drawdown
315
+ ```
316
+
317
+ ![cli drawdown](images/cli_drawdown_plot.png)
318
+
319
+ `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$.
320
+
321
+ ```
322
+ >>> trading-journal win-matrix 5 4
323
+ ```
324
+
325
+ ![cli win matrix](images/cli_win_matrix_plot.png)
326
+
327
+ `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.
328
+
329
+ ```
330
+ >>> trading-journal rolling-sharpe
331
+ ```
332
+
333
+ ![cli rolling sharpe](images/cli_rolling_sharpe_plot.png)
334
+
335
+ `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.
336
+
337
+ ```
338
+ >>> trading-journal trade-freq --aggregation 'day_of_week'
339
+ ```
340
+
341
+ ![cli trade freq](images/cli_trade_freq_plot.png)
342
+
343
+ `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.
344
+
345
+ ```
346
+ >>> trading-journal trade-agg
347
+ ```
348
+
349
+ ![cli trade agg](images/cli_trade_agg_plot.png)
350
+
351
+ ### SIMULATION Functions
352
+
353
+ `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.
354
+
355
+ ```
356
+ >>> trading-journal permutation-test 'sharpe' 1000.0
357
+ ```
358
+
359
+ ![cli permutation test](images/cli_permutation_test_plots.png)
360
+
361
+ ![cli permutation test table](images/cli_permutation_test_table.png)
362
+
363
+ `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.
364
+
365
+ ```
366
+ >>> trading-journal trade-independence
367
+ ```
368
+
369
+ ![cli trade independence](images/cli_trade_independence_sim.png)
370
+
371
+ `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.
372
+
373
+ ```
374
+ >>> trading-journal pnl-density
375
+ ```
376
+
377
+ ![cli pnl density](images/cli_pnl_density_sim.png)
378
+
379
+
380
+ `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.
381
+
382
+
383
+ ```
384
+ >>> trading-journal markov-sim
385
+ ```
386
+
387
+ ![cli markov sim](images/cli_markov_dependence_test.png)
388
+
389
+ ## Future Updates
390
+
391
+ - Integration of uploaded time-indexed returns
392
+
393
+ ## License
394
+
395
+ MIT - see [LICENSE](/LICENSE) # Trading-Journal