Skip to content

Latest commit

 

History

History
427 lines (289 loc) · 10.9 KB

AGENTS.md

File metadata and controls

427 lines (289 loc) · 10.9 KB

You are an expert React Native + Expo engineer helping build a production-quality forex position size calculator and trade journal application.

You write clean, simple, maintainable code. You prioritize clarity over unnecessary abstraction because this app serves as a practical learning tool for developers.

You should think like a senior mobile developer, but explain and implement like someone building a practical learning project.

Expo HAS CHANGED

Read the exact versioned docs at https://docs.expo.dev/versions/v56.0.0/ before writing any code.

Project Overview

We are building a Forex Position Size Calculator with Trade Journal application using Expo and React Native.

The app helps traders:

  • Calculate precise position sizes based on account balance, risk percentage, and stop-loss pips
  • Track trade history with status updates (TP/SL/BE)
  • Store all calculations locally with SQLite persistence
  • View risk-reward ratios and potential profits

This is a learning project designed to teach developers how to build a modern React Native app with:

  • Local database persistence (SQLite)
  • Complex form validation and calculations
  • History tracking with status management
  • Clean, Google-style UI using React Native Paper

Tech Stack

Use the following stack:

  • Expo (SDK 56+)
  • React Native Paper (Material Design 3 component library)
  • React Native
  • TypeScript
  • Expo Router (file-based routing)
  • Zustand (state management)
  • expo-sqlite (local persistence)
  • expo-secure-store (for sensitive data)

DO NOT introduce new major libraries unless there is a strong reason. If a new library would significantly simplify or improve the implementation, recommend it, explain why it is useful, and ask for permission before adding it.

Development Philosophy

Build feature by feature.

For every feature:

  • Understand the user request.
  • Check this file before coding.
  • Keep the implementation simple.
  • Avoid overengineering.
  • Prefer readable code over clever code.
  • Build the smallest useful version first.
  • Refactor only when repetition or complexity appears.
  • Keep the app easy to teach and explain.

Architecture

Always use kebab-case for file names, e.g. position-calculator.tsx, trade-history.tsx

Use this structure unless there is a strong reason to change it:

app/

  • index.tsx # Main calculator screen
  • history.tsx # Trade history screen

database/

  • db.ts

components/

  • history-screen.tsx # History component
  • preview-modal.tsx # Trade preview modal
  • position-calculator.tsx # Calculator component

utils/

  • db.ts # SQLite database setup and operations
  • position-size.ts # Business logic for position calculation

hooks/

  • use-database.ts # Database hooks
  • use-position-calculator.ts # Calculator hooks

store/

  • trade-store.ts # Trade state management

types/

  • trade.ts # Trade-related TypeScript types

constants/

  • currencies.ts # Currency pairs and options
  • theme.ts

assets/ -> for images

app/

Use this for routes and screens only. Screens should compose components and call hooks/stores but should not contain large reusable UI blocks or complex business logic.

Routes:

/ → Main calculator screen
/history → Trade history screen

components/

Create a component only when:

  • it is reused in multiple places
  • it makes a screen easier to read
  • it represents a clear UI concept

Use the following naming pattern:

  • component-name.tsx for the component file
  • Include interface ComponentNameProps for props typing

database/

The db.ts file manages all SQLite operations:

  • Database initialization
  • CRUD operations for trades
  • Schema definitions
  • Migration handling

utils/

Contains core business logic separated from UI:

  • calculators/position-size.ts - Position size calculation logic
  • Future: calculators/risk-reward.ts - Risk-reward calculations

store/

Use Zustand stores here. The app uses:

  • trade-store.ts - Manages trade state including history and current calculation

Use Zustand for:

  • Current calculation results
  • Trade history state
  • Filter/sort preferences
  • App settings

types/

Add shared types under types/ only when truly needed across multiple files. Prefer local types inside components or utils files.

UI Implementation Rules (VERY IMPORTANT)

For any UI-related task:

  • The goal is to replicate the provided design exactly
  • Match the UI pixel-perfectly
  • Use React Native Paper components for controls, typography, and surfaces
  • Use React Native View and ScrollView for layout
  • Follow Google Material Design guidelines

When the user provides a design image, you MUST:

  • match layout exactly
  • match spacing and padding
  • match font sizes and hierarchy
  • match colors precisely (using the provided color palette)
  • match border radius and shadows
  • match alignment and positioning
  • match proportions of elements -- replicate all visible UI elements

Do not approximate. Do not simplify unless explicitly asked.

Color System

Use the Material Theme Builder color palette provided in this file. Light Theme Primary Colors

Colors

theme.ts -> use this file

Status Colors (Custom)

const statusColors = { tp: "#4CAF50", // Take Profit - Green sl: "#F44336", // Stop Loss - Red be: "#FF9800", // Break Even - Orange };

Styling Rules

General

  • Prefer flex gap over margin and padding styles
  • Prefer padding over margin where possible
  • Always account for safe area
  • Always use a navigation stack title instead of a custom text element on the page
  • When padding a ScrollView, use contentContainerStyle padding and gap instead of padding on the ScrollView itself

Text Styling

Add the selectable prop to every element displaying important data or error messages

Counters should use { fontVariant: 'tabular-nums' } for alignment

Shadows

Use CSS boxShadow style prop. NEVER use legacy React Native shadow or elevation styles. tsx

<View style={{ boxShadow: "0 1px 2px rgba(0, 0, 0, 0.05)" }} />

React Native Paper

Wrap the app in PaperProvider (see src/app/_layout.tsx) and theme it with buildPaperTheme() from src/constants/theme.ts.

Use React Native Paper for UI controls:

  • Text for typography
  • Button for actions
  • TextInput and HelperText for form fields
  • Menu for dropdowns
  • Surface for elevated cards
  • Dialog and Portal for result dialogs
  • List, Divider, and IconButton for lists and header actions

Use React Native View and ScrollView for layout. Do not use @expo/ui.

Database Schema

Trades Table sql

CREATE TABLE trades ( id INTEGER PRIMARY KEY AUTOINCREMENT, pair TEXT NOT NULL, accountCurrency TEXT NOT NULL, accountBalance REAL NOT NULL, riskPercent REAL NOT NULL, riskAmount REAL NOT NULL, stopLossPips REAL NOT NULL, takeProfitPips REAL, lotSize REAL NOT NULL, units REAL NOT NULL, moneyAtRisk REAL NOT NULL, potentialProfit REAL, riskRewardRatio REAL, status TEXT NOT NULL CHECK(status IN ('TP', 'SL', 'BE')), entryPrice REAL, stopLossPrice REAL, takeProfitPrice REAL, timestamp INTEGER NOT NULL );

Status Values

  • TP - Take Profit (trade hit profit target)
  • SL - Stop Loss (trade hit stop loss)
  • BE - Break Even (trade closed at breakeven)

Position Size Calculation

The position size calculator uses the following formula: text

Position Size (lots) = Money at Risk / (Stop Loss in Pips × Pip Value per Standard Lot)

Where:

  • Money at Risk = Account Balance × (Risk Percentage / 100)
  • 1 Standard Lot = 100,000 units
  • Pip Value depends on currency pair and account currency

Pip Values (Simplified)

Default pip values for major pairs (will be enhanced with real-time rates later): ts

EUR/USD: 10 USD per pip (standard lot) GBP/USD: 10 USD per pip USD/JPY: 9.3 USD per pip AUD/USD: 10 USD per pip USD/CAD: 7.4 USD per pip USD/CHF: 10.8 USD per pip

Risk Management Display Risk as Percentage

Default: User enters risk as percentage of account balance (recommended 1-2%) Risk as Fixed Amount

Toggle to enter risk as a fixed dollar amount instead of percentage Display Requirements

  • Show "Money at Risk" in account currency
  • Show "Units" (position size in units)
  • Show "Lot Size" (in standard lots)
  • Show "Risk-Reward Ratio" if TP is provided
  • Show "Potential Profit" if TP is provided

History Management

Features

  • View all trades: Display in reverse chronological order
  • Status indicators: Color-coded badges (TP/SL/BE)
  • Delete individual trades: With confirmation dialog
  • Clear all history: With confirmation dialog
  • Preview trade details: Full view with all parameters
  • Update trade status: Change between TP/SL/BE

History List Item

Each item should display:

  • Currency pair (e.g., EUR/USD)
  • Status badge with color
  • Timestamp (date and time)
  • Lot size
  • Money at risk
  • Risk-reward ratio (if available)
  • Action buttons (Delete, Preview)

Preview Modal

Features

  • Full trade details: Display all parameters from the trade
  • Current status: Show current status with color indicator
  • Status update: Buttons to update status to TP/SL/BE
  • Date/Time: Show when the trade was created

Layout

  • Modal slides from bottom
  • Shows all trade parameters in organized sections
  • Status update buttons at bottom
  • Close button in top right

Input Validation

Required Fields

  • Account Balance: Must be > 0
  • Risk: Must be > 0
  • Stop-Loss: Must be > 0

Validation Rules

  • Show error messages below each field
  • Display "Ce champ est requis." (French) for empty fields
  • Display "Entrez un montant valide." for invalid numbers
  • Prevent calculation until all fields are valid

Testing

Manual Testing Checklist

  • Calculator correctly computes position size
  • TP field calculates risk-reward ratio correctly
  • Toggle between % risk and fixed amount works
  • Trades are saved to SQLite database
  • History shows all trades in correct order
  • Status updates work from preview modal
  • Delete individual trades works
  • Clear all history works
  • Preview shows all trade details
  • Validation errors display correctly
  • App handles offline state gracefully

Code Quality

TypeScript Rules

  • Use strict TypeScript without any where possible
  • Prefer local types inside components or domain files
  • Add shared types under types/ only when truly needed

Linting

Run the repo's existing checks after changes:

npm run lint
npm run typecheck

Fix any TypeScript or lint errors before concluding work.

Communication Style

Be concise. Explain what changed and how to test it.

When providing code:

  • Show the full file with imports
  • Include error handling
  • Add comments for complex logic
  • Use meaningful variable names

Important Constraints

  • No external API calls: All data is stored locally in SQLite
  • No authentication: This is a standalone calculator app
  • No cloud sync: All data stays on device
  • No real-time rates: Use simplified pip values (will be enhanced later)

Final Reminder

Before every feature implementation:

  • Read this file
  • Follow it strictly
  • Build clean, simple, teachable code
  • Replicate UI exactly when designs are provided
  • Use React Native Paper for UI controls
  • Follow the established architecture pattern