Skip to content

ozalpd/OzzTradeDiary

Repository files navigation

Ozz Trade Diary

A Windows desktop trade journaling application for tracking trades across multiple markets — crypto, stocks, forex, futures, options, commodities, and more.

Status: Pre-release development (no public release yet)

Internal tracking versions: OzzTradeDiary 0.0.63, OzzTradeDiary.AppInfra 0.0.63, OzzTradeDiary.RepositoryContracts 0.0.63, OzzTradeDiary.WPF 0.0.63, OzzTradeDiary.SQLite 0.0.63, OzzTradeDiary.i18n 0.0.63

Changelog

See CHANGELOG.md for release history.

Third-Party Assets

  • This project uses icon paths derived from Bootstrap Icons.
  • Source: https://icons.getbootstrap.com
  • Project repository: https://github.com/twbs/icons
  • Version: v1.13.1
  • License: MIT
  • SPDX License Identifier: MIT

Features

Trade Journal

  • Track trades across multiple markets: Crypto, Stock, Forex, Futures, Options, Commodities, and more
  • Long and short trade directions
  • Separate order type enums for entries (EntryOrderType: Market, Limit, StopMarket, StopLimit) and exits (ExitOrderType: Market, Limit, TrailingStop, Stop, StopLimit)
  • Entry/exit orders, stop-loss, and take-profit levels per trade
  • Trade images: attach chart screenshots or web URLs with notes
  • Trade filtering and paging with TradeQueryParameters — supports date ranges, position values, P/L, and risk range filters

Multi-Account & Multi-Exchange

  • Manage multiple exchanges with optional default currency per exchange
  • Manage multiple trading accounts linked to exchanges
  • Manage symbols with market type, base/price currency, and exchange association

Maintenance UI

  • Maintenance window for Currency, Exchange, TradingAccount, and Symbol CRUD
  • Add, Edit, Save, Refresh, and Delete operations with localized icon-based buttons
  • Symbols tab supports text search and exchange-based filtering
  • Safe exchange deletion — disabled when exchange is referenced by symbols or trading accounts
  • Unsaved-changes confirmation on dialog close for edit dialogs

Localization

  • Full English and Turkish UI support
  • Localized DataAnnotations on model classes for display names and validation messages
  • All UI strings sourced from generated resource classes (ActionStrings, CommonStrings, ErrorStrings, LocalizedStrings, MessageStrings)

Data Layer

  • Raw SQLite data access via Microsoft.Data.Sqlite — no ORM
  • Repository implementations in TD.SQLite, contracts in TD.RepositoryContracts
  • Repositories implemented: Currency, Exchange, TradingAccount, Symbol, Trade, TradeImage, EntryOrder, StopLossOrder, TakeProfitOrder
  • Navigation collections auto-loaded for Exchange (Symbols, TradingAccounts) and Trade (orders, images)
  • Type-safe decimal SQLite persistence — scaled integers for values, TEXT for precision-sensitive price/quantity fields

Database Backup

  • Automatic and manual SQLite backup via SQLite BACKUP API
  • Backups archived as timestamped ZIP files
  • Configurable retention policy with automatic cleanup of old backups

Developer Experience

  • TD.Tools.SeedDemoData console tool for seeding realistic demo crypto trade data
  • Scripts/SeedDemoData.bat convenience launcher — resets and reseeds the debug database
  • Debug builds use repo-root SampleData/ path to avoid touching user app-data folders
  • SQLite DDL scripts, localization resources, model classes, and repository generation settings managed by OzzCodeGen

Application Infrastructure

  • DPI-aware multi-monitor window positioning
  • App version displayed in title bar; Bootstrap Icons for window title bar icons
  • UI culture configurable via AppSettings.UiCulture (BCP-47); falls back to OS culture when empty
  • Shared platform-agnostic MVVM base classes (AbstractViewModel, AbstractCommand, AbstractDataErrorInfoVM, AbstractCreateEditVM, AbstractDiaryVM) and AppDataSources dependency container in TD.AppInfra for reuse by WPF and future MAUI frontends
  • App.OnStartup is the single composition root: all repositories are created as named variables, wrapped in AppDataSources (TD.AppInfra.Models), and passed as a single object into MainWindowMainWindowVM; ShowMaintenanceCommand forwards the same AppDataSources to MaintenanceWindowMaintenanceWindowVM
  • Lookup services (ExchangeLookupService, CurrencyLookupService, etc.) are instantiated inside ViewModel constructors from injected repositories — keeping App.OnStartup clean and ViewModels free of repository construction logic
  • Design-time mock implementations for all repositories and lookup services live in TD.AppInfra/DesignTime/ for use by parameterless XAML designer constructors

Planned

  • Introduce TD.AppContracts to host shared application-service/lookup contracts (for example IExchangeLookupService, ISymbolLookupService) used by both WPF and future MAUI frontends
  • Add a MAUI frontend project (OzzTradeDiary.MAUI) that reuses platform-agnostic core (TD), localization (TD.i18n), app infra (TD.AppInfra), and contract layers
  • Keep lookup/app-service contracts in TD.AppContracts (separate from WPF-only assemblies) so both WPF and MAUI can share the same service abstractions
  • Remaining model repository classes in OzzTradeDiary.SQLite
  • Functional data layer repositories and query logic
  • Multi-market support: Stock, Forex, Crypto, Futures, Options, Commodities, and more
  • Trade tracking with entry/exit orders, stop-loss, and take-profit levels
  • Long and short trade directions
  • Separate order type enums for entries and exits (EntryOrderType, ExitOrderType)
  • Trade images with chart attachments and notes
  • Multi-account and multi-exchange support
  • Automatic SQLite database backup with ZIP archiving

Prerequisites

Getting Started

# Clone the repository
git clone https://github.com/your-username/OzzTradeDiary.git
cd OzzTradeDiary

# Build
dotnet build OzzTradeDiary.slnx

# Run
dotnet run --project OzzTradeDiary.NET/OzzTradeDiary.WPF/OzzTradeDiary.WPF.csproj

Project Structure

View and ViewModel files use entity-first, verb-last naming (e.g., TradingAccountCreate.xaml, TradingAccountCreateVM.cs) so that files for the same entity sort together in Solution Explorer. Method names remain verb-first (e.g., CreateTradingAccount(), DeleteExchange()).

OzzTradeDiary.slnx
├── OzzTradeDiary.NET/
│   ├── OzzTradeDiary/            # Core models, shared helpers, validation (TD / TD.Extensions / TD.Helpers / TD.Validation) — platform-independent
│   │   ├── Models/               # Trade, TradeImage, Symbol, Exchange, Currency, Orders, etc.
│   │   ├── Extensions/           # Shared enum/text helpers reusable outside WPF
│   │   ├── Helpers/              # Shared query parameter contracts and other platform-agnostic helpers
│   │   └── Validation/           # Shared DataAnnotations-based validation (TD.Validation.ModelValidator)
│   ├── OzzTradeDiary.AppInfra/   # Shared MVVM infrastructure (TD.AppInfra namespace) — platform-independent base classes
│   │   ├── Commands/             # AbstractCommand and other shared command infrastructure
│   │   ├── DesignTime/           # Mock repositories and lookup services for XAML designer support (e.g. TradeMockRepository, CurrencyMockRepository)
│   │   ├── Services/             # Shared lookup services (generated, platform-agnostic — e.g. ExchangeLookupService, SymbolLookupService)
│   │   └── ViewModels/           # AbstractViewModel, AbstractDataErrorInfoVM, AbstractCreateEditVM, AbstractCollectionVM, AbstractDiaryVM, etc.
│   ├── OzzTradeDiary.i18n/       # Localization resources (TD.i18n namespace) — platform-independent, generated by OzzCodeGen/OzzGen
│   │   ├── *Strings.resx         # Base resources (Action/Common/Error/Localized/Message)
│   │   └── *Strings.tr.resx      # Turkish resources
│   ├── TD.RepositoryContracts/   # Shared repository contracts (TD.RepositoryContracts namespace) — platform-independent
│   ├── OzzTradeDiary.SQLite/     # Data access (TD.SQLite namespace) — platform-independent
│   │   ├── DbScripts/            # Generated SQL DDL scripts (one per model in OzzTradeDiary/Models)
│   │   ├── Extensions/           # SQLite-specific extension methods
│   │   ├── AbstractDatabaseRepository.cs
│   │   ├── MetadataRepository.cs
│   │   ├── CurrencyRepository.cs
│   │   ├── ExchangeRepository.cs
│   │   ├── TradingAccountRepository.cs
│   │   ├── SymbolRepository.cs
│   │   ├── TradeRepository.cs
│   │   └── ...                   # Repository classes live at the project root
│   ├── TD.Tools.SeedDemoData/    # Demo-data seeding console tool
│   └── OzzTradeDiary.WPF/        # Desktop UI (TD.WPF namespace) — Windows only
│       ├── Commands/             # WPF-specific command implementations
│       ├── Extensions/           # WPF-specific helpers
│       ├── Models/               # App settings, versioning, window positioning
│       ├── Resources/            # XAML styles, Bootstrap Icons
│       ├── Services/             # WPF-specific services (database backup, auto-backup); lookup services moved to TD.AppInfra
│       ├── ViewModels/           # WPF view models (inherit from TD.AppInfra base classes)
│       │   └── Maintenance/      # ViewModels for maintenance screens (TD.WPF.ViewModels.Maintenance)
│       └── Views/                # XAML views
│           └── Maintenance/      # Maintenance window and related views (TD.WPF.Views.Maintenance)
└── OzzCodeGen/                   # Code generation settings
    ├── SqliteScriptsGen.settings # SQLite DDL generation config
    ├── ResourceGen.settings      # Localization resource generation config
    └── Vocabulary/               # English/Turkish translation files

Architecture

Six-project MVVM architecture layered for platform portability:

Project Target Role
OzzTradeDiary net10.0 Core data models, shared helpers such as TD.Extensions.EnumExtension, shared query helpers in TD.Helpers, and shared validation utilities (for example TD.Validation.ModelValidator) with no platform dependencies
OzzTradeDiary.AppInfra net10.0 Shared ViewModel, Command, MVVM infrastructure base classes, and generated lookup services (*LookupService) for reuse by WPF and future frontends (MAUI, web, etc.)
OzzTradeDiary.i18n net10.0 Shared localization resources (*.resx/designer classes) generated from OzzCodeGen/OzzGen inputs
OzzTradeDiary.RepositoryContracts net10.0 Shared repository contracts (interfaces) for data access abstractions
OzzTradeDiary.SQLite net10.0 Data access layer — raw SQLite via Microsoft.Data.Sqlite, repository pattern
OzzTradeDiary.WPF net10.0-windows10.0.19041.0 WPF desktop frontend — views, view models, commands, services

Core models, localization resources, data access, and shared MVVM infrastructure are platform-independent, enabling future frontends (MAUI, web, etc.) to reuse them. Model classes localize display metadata and validation messages through DataAnnotations that reference TD.i18n resource types. Shared enum and text helper logic lives in TD.Extensions so UI projects such as WPF and future MAUI frontends can reuse the same behavior. Shared ViewModel/Command base classes live in TD.AppInfra so both WPF and future platforms can inherit from a common, platform-agnostic foundation. Exchange now includes navigation collections (Symbols, TradingAccounts) and Trade includes quantity fields (OrderQuantity, FilledQuantity) reflected across model, repository, and schema generation. Trade also persists PlannedPositionValue, ExecutedPositionValue, PlannedEntryPrice, ExecutedEntryPrice, PlannedProfitLoss, RealizedProfitLoss, PlannedRiskAmount, and IsFullyClosed across model, repository mapping, and generated schema/indexes.

SQLite Repository and Script Conventions

  • Model names are singular; related table names are plural.
  • Each model has a generated DDL file in OzzTradeDiary.SQLite/DbScripts with the same model name and .sql suffix.
  • Some models have generated seed files named <PluralTableName>-Data.sql in OzzTradeDiary.SQLite/DbScripts.
  • DDL and seed files are generated by OzzCodeGen; do not edit manually.
  • Each repository CUD operation updates metadata timestamp via SaveLastUpdateUtcAsync in SqliteDatabaseMetadataRepository.
  • MetadataRepository is shared via a singleton GetInstance() method; repositories use it internally and WPF ViewModels/services do not instantiate it directly.
  • When adding a generated seed file <PluralTableName>-Data.sql, the corresponding repository InitializeDatabase() should call SqliteDbScriptInitializer.SeedIfEmpty(connection, "<PluralTableName>", "<PluralTableName>-Data.sql").
  • Generated repositories can expose OnLoaded partial hooks for post-load behavior, especially when navigation properties are configured with AutoLoad=true.
  • TradeRepository may use injected related repositories to populate Trade navigation collections during OnLoaded.
  • Immutable repository keys:
    • Currency.CurrencyTicker
    • Exchange.ExchangeCode
    • Symbol.TickerFull
  • Nullable text fields such as Exchange.DefaultCurrency should be stored as SQL NULL, not the literal string "null".
  • Prefer TD.SQLite.Extensions.SqliteExtensions.AddNullableParameter(...) for nullable SQLite parameters; avoid AddNullableTextParameter.
  • Use scaled INTEGER storage for value columns such as OrderValue and FilledValue, and use TEXT storage for precision-sensitive price/quantity decimals.

Database Initialization and Seed Data

At repository startup, initialization executes generated DDL scripts and applies baseline seed scripts only when target tables are empty.

  • Seeding is idempotent and uses the inherited SeedIfEmpty(...) helper from AbstractDatabaseRepository.
  • Demo data for local debugging can be seeded with TD.Tools.SeedDemoData or the convenience launcher Scripts/SeedDemoData.bat.
  • SeedDemoData generates demo symbols/trades/images for multiple crypto tickers with a crypto base-price dictionary for more realistic price generation.
  • Demo seeding creates two exchanges and two trading accounts, then distributes generated trades over a wider date range.
  • SeedTrades supports flexible account/exchange/day-range/suffix targeting for reusable seeding scenarios.
  • Scripts/SeedDemoData.bat is intended to reset the debug database before seeding so local demo runs are deterministic and clean.
  • Current generated seed scripts include:
    • OzzTradeDiary.SQLite/DbScripts/Currencies-Data.sql
    • OzzTradeDiary.SQLite/DbScripts/Exchanges-Data.sql
    • OzzTradeDiary.SQLite/DbScripts/Symbols-Data.sql

Dependencies

Package Version Project
Microsoft.Data.Sqlite 10.0.5 OzzTradeDiary.SQLite, OzzTradeDiary.WPF

Code Generation

SQLite DDL scripts and localization resources are generated by OzzCodeGen — a separate code generation tool. Configuration lives in OzzCodeGen/:

  • SqliteScriptsGen.settings — maps C# models to SQLite CREATE TABLE scripts in DbScripts/
  • SqliteRepositoryGen.settings — generates SQLite repository classes and interfaces
  • WpfMvVmCodeEngine.settings — generates WPF View, ViewModel, Command, and related MVVM base outputs
  • CsModelClassCodeEngine.settings — uses CSharpModelClassCodeEngine as the root element for generated C# model class settings
  • ResourceGen.settings — generates localization resources from vocabulary XML files
  • Vocabulary/ — bilingual term definitions (English/Turkish)
  • LocalizedStrings.resx is sourced from OzzTradeDiary.OzzGen
  • Model classes and database schema generation are sourced from OzzTradeDiary.OzzGen (generator name: CS_Model_Class_Generator)
  • QueryParameters class generation is enabled for shared pagination/search contracts in TD.Helpers
  • Entity-specific query parameter generation (for example TradeQueryParameters) is supported through CsModelClassCodeEngine.settings
  • Searchable properties can be explicitly marked in generator settings so generated query contracts stay typed and aligned
  • Generated model/validator code uses standardized header text for clearer generated-file context
  • Generated repository interfaces are co-located inside repository class files (I<Entity>Repository)
  • Generated repository hooks and auto-loading behavior depend on generator settings and execution order in OzzTradeDiary.OzzGen
  • Generator execution order in OzzTradeDiary.OzzGen should be kept aligned with repository/schema dependencies and generated hook availability
  • Custom repository behavior should be added in companion partial files (for example SymbolRepository.part.cs or TradeRepository.part.cs)
  • Shared application/tool behavior may also be extracted into partial files and linked into multiple projects (for example AppSettings.part.cs for debug SampleData path resolution)

Do not edit generated files manually (DbScripts/*.sql, generated .resx, generated .Designer.cs, and generated repository/model/schema outputs) — they are overwritten on regeneration.

License

MIT License

About

A trading journal application which will keep trade details and produce some statistics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages