-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
acc9126
commit b42a7fa
Showing
25 changed files
with
2,607 additions
and
303 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,193 +1,171 @@ | ||
# champion-trader | ||
# Champion Trader | ||
|
||
A React TypeScript trading application built with modern technologies and best practices. | ||
A React-based trading application for options trading. | ||
|
||
## Technologies | ||
## Features | ||
|
||
- React 18 | ||
- TypeScript | ||
- TailwindCSS for styling | ||
- Zustand for state management | ||
- Axios for API communication | ||
- Jest and React Testing Library for testing | ||
- Real-time market data streaming | ||
- Contract price updates | ||
- Position management | ||
- Trade execution | ||
- Responsive design | ||
- TypeScript support | ||
|
||
## Getting Started | ||
|
||
> **Prerequisites:** | ||
> The following steps require [NodeJS](https://nodejs.org/en/) to be installed on your system, so please | ||
> install it beforehand if you haven't already. | ||
### Prerequisites | ||
|
||
To get started with your project, you'll first need to install the dependencies with: | ||
- Node.js (v18 or higher) | ||
- npm or yarn | ||
|
||
### Installation | ||
|
||
```bash | ||
# Install dependencies | ||
npm install | ||
``` | ||
|
||
Then, you'll be able to run a development version of the project with: | ||
|
||
```bash | ||
# Start development server | ||
npm run dev | ||
|
||
# Build for production | ||
npm run build | ||
|
||
# Run tests | ||
npm test | ||
``` | ||
|
||
After a few seconds, your project should be accessible at the address | ||
[http://localhost:4113/](http://localhost:4113/) | ||
## Architecture | ||
|
||
## Environment Configuration | ||
### Real-time Data Streaming | ||
|
||
The application supports different environments (development, staging, production) with environment-specific configurations. Create a `.env` file in the project root with the following variables: | ||
The application uses Server-Sent Events (SSE) for real-time data streaming, providing efficient unidirectional communication for: | ||
|
||
```bash | ||
# WebSocket Configuration | ||
RSBUILD_WS_URL=ws://options-trading-api.deriv.ai # WebSocket server URL | ||
RSBUILD_WS_PUBLIC_PATH=/ws # Public WebSocket endpoint path | ||
RSBUILD_WS_PROTECTED_PATH=/ws # Protected WebSocket endpoint path | ||
- Market price updates | ||
- Contract price streaming | ||
- Position updates | ||
|
||
# REST API Configuration | ||
RSBUILD_REST_URL=http://options-trading-api.deriv.ai # REST API server URL | ||
``` | ||
#### Why SSE over WebSocket? | ||
|
||
Default configurations per environment: | ||
1. **Simpler Protocol**: SSE is built on HTTP and is simpler to implement and maintain | ||
2. **Automatic Reconnection**: Built-in reconnection handling | ||
3. **Better Load Balancing**: Works well with HTTP/2 and standard load balancers | ||
4. **Lower Overhead**: No need for ping/pong messages or connection heartbeats | ||
5. **Firewall Friendly**: Uses standard HTTP port 80/443 | ||
|
||
### Development | ||
```typescript | ||
{ | ||
ws: { | ||
baseUrl: 'ws://options-trading-api.deriv.ai', | ||
publicPath: '/ws', | ||
protectedPath: '/ws' | ||
}, | ||
rest: { | ||
baseUrl: 'http://options-trading-api.deriv.ai' | ||
} | ||
} | ||
``` | ||
### Example Usage | ||
|
||
### Staging | ||
```typescript | ||
{ | ||
ws: { | ||
baseUrl: 'wss://options-trading-api.deriv.ai', | ||
publicPath: '/ws', | ||
protectedPath: '/ws' | ||
}, | ||
rest: { | ||
baseUrl: 'https://options-trading-api.deriv.ai' | ||
} | ||
// Market Data Streaming | ||
import { useMarketSSE } from '@/hooks/sse'; | ||
|
||
function MarketPrice({ instrumentId }: { instrumentId: string }) { | ||
const { price, isConnected } = useMarketSSE(instrumentId, { | ||
onPrice: (price) => { | ||
console.log('New price:', price); | ||
} | ||
}); | ||
|
||
return ( | ||
<div> | ||
{isConnected ? ( | ||
<p>Current price: {price?.bid}</p> | ||
) : ( | ||
<p>Connecting...</p> | ||
)} | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
### Production | ||
```typescript | ||
{ | ||
ws: { | ||
baseUrl: 'wss://options-trading-api.deriv.ai', | ||
publicPath: '/ws', | ||
protectedPath: '/ws' | ||
}, | ||
rest: { | ||
baseUrl: 'https://options-trading-api.deriv.ai' | ||
} | ||
// Contract Price Streaming | ||
import { useContractSSE } from '@/hooks/sse'; | ||
|
||
function ContractPrice({ params, authToken }: { params: ContractPriceRequest; authToken: string }) { | ||
const { price, isConnected } = useContractSSE(params, authToken, { | ||
onPrice: (price) => { | ||
console.log('Contract price:', price); | ||
} | ||
}); | ||
|
||
return ( | ||
<div> | ||
{isConnected ? ( | ||
<p>Price: {price?.price}</p> | ||
) : ( | ||
<p>Connecting...</p> | ||
)} | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
## Testing | ||
### State Management | ||
|
||
Run all tests with: | ||
The application uses Zustand for state management, providing: | ||
|
||
```bash | ||
npm test | ||
``` | ||
- Centralized store for application state | ||
- Simple and predictable state updates | ||
- TypeScript support | ||
- Minimal boilerplate | ||
|
||
Run tests in watch mode during development: | ||
### Project Structure | ||
|
||
```bash | ||
npm test -- --watch | ||
``` | ||
src/ | ||
├── components/ # Reusable UI components | ||
├── hooks/ # Custom React hooks | ||
├── layouts/ # Page layouts | ||
├── screens/ # Page components | ||
├── services/ # API and service layer | ||
│ └── api/ | ||
│ ├── rest/ # REST API services | ||
│ └── sse/ # SSE services | ||
├── stores/ # Zustand stores | ||
└── types/ # TypeScript type definitions | ||
``` | ||
|
||
### Testing Guidelines | ||
|
||
- Follow Test-Driven Development (TDD) methodology | ||
- Write tests before implementing functionality | ||
- Maintain at least 90% test coverage | ||
- Mock external dependencies (Axios, Zustand stores) | ||
- Test edge cases explicitly | ||
|
||
## Development Guidelines | ||
## Development | ||
|
||
### Component Design | ||
### Code Style | ||
|
||
- Follow Atomic Component Design principles | ||
- Components should be self-contained and independent | ||
- Follow TypeScript best practices | ||
- Use functional components with hooks | ||
- Implement proper error handling | ||
- Write comprehensive tests | ||
- Use TailwindCSS for styling | ||
- Implement lazy loading for components | ||
|
||
### State Management | ||
|
||
- Use local state for component-specific logic | ||
- Use Zustand for shared/global state | ||
- Avoid prop drilling | ||
|
||
### API Integration | ||
|
||
#### REST API | ||
The application uses Axios for REST API calls. Available endpoints: | ||
|
||
##### Available Instruments | ||
Fetches available trading instruments: | ||
```typescript | ||
import { getAvailableInstruments } from '@/services/api/rest/service'; | ||
|
||
const response = await getAvailableInstruments({ | ||
context: { | ||
app_id: 1001, | ||
account_type: 'real' | ||
} | ||
}); | ||
// Returns: { instruments: [{ id: string, name: string }] } | ||
``` | ||
### Testing | ||
|
||
General guidelines: | ||
- Use Axios for HTTP requests | ||
- Wrap API calls in service layers | ||
- Handle errors gracefully | ||
- Use environment-specific configurations from `src/config/api.ts` | ||
The project uses Jest and React Testing Library for testing: | ||
|
||
### Import Paths | ||
```bash | ||
# Run all tests | ||
npm test | ||
|
||
Use path aliases for better maintainability: | ||
# Run tests with coverage | ||
npm test -- --coverage | ||
|
||
```typescript | ||
// Instead of | ||
import { TradeButton } from "../../components/TradeButton"; | ||
|
||
// Use | ||
import { TradeButton } from "@/components/TradeButton"; | ||
# Run specific test file | ||
npm test -- src/components/MyComponent.test.tsx | ||
``` | ||
|
||
### Version Control | ||
### Environment Variables | ||
|
||
Commit messages should follow the pattern: | ||
``` | ||
<type>: concise description | ||
Create a `.env` file in the root directory: | ||
|
||
- Detailed bullet points | ||
- Additional context | ||
```env | ||
RSBUILD_REST_URL=https://api.example.com | ||
RSBUILD_SSE_PUBLIC_PATH=/sse | ||
RSBUILD_SSE_PROTECTED_PATH=/sse | ||
``` | ||
|
||
Allowed types: | ||
- feat: New features | ||
- fix: Bug fixes | ||
- refactor: Code changes that neither fix bugs nor add features | ||
- docs: Documentation changes | ||
- test: Test-related changes | ||
- chore: Build process or auxiliary tool changes | ||
## Contributing | ||
|
||
## Building for Production | ||
1. Fork the repository | ||
2. Create your feature branch (`git checkout -b feature/amazing-feature`) | ||
3. Commit your changes (`git commit -m 'Add some amazing feature'`) | ||
4. Push to the branch (`git push origin feature/amazing-feature`) | ||
5. Open a Pull Request | ||
|
||
Build the project for release with: | ||
|
||
```bash | ||
npm run build | ||
``` | ||
## License | ||
|
||
This will create an optimized production build in the `dist` directory. | ||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. |
Oops, something went wrong.