pycharting 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.
Files changed (32) hide show
  1. pycharting-0.1.0/PKG-INFO +676 -0
  2. pycharting-0.1.0/README.md +649 -0
  3. pycharting-0.1.0/pyproject.toml +39 -0
  4. pycharting-0.1.0/src/charting/__init__.py +80 -0
  5. pycharting-0.1.0/src/charting/api/__init__.py +1 -0
  6. pycharting-0.1.0/src/charting/api/exceptions.py +41 -0
  7. pycharting-0.1.0/src/charting/api/main.py +134 -0
  8. pycharting-0.1.0/src/charting/api/models.py +156 -0
  9. pycharting-0.1.0/src/charting/api/processor.py +415 -0
  10. pycharting-0.1.0/src/charting/api/routes.py +166 -0
  11. pycharting-0.1.0/src/charting/browser.py +145 -0
  12. pycharting-0.1.0/src/charting/charting.py +420 -0
  13. pycharting-0.1.0/src/charting/detector.py +576 -0
  14. pycharting-0.1.0/src/charting/frontend/app.js +431 -0
  15. pycharting-0.1.0/src/charting/frontend/chart.js +597 -0
  16. pycharting-0.1.0/src/charting/frontend/data-client.js +224 -0
  17. pycharting-0.1.0/src/charting/frontend/divider.css +83 -0
  18. pycharting-0.1.0/src/charting/frontend/divider.js +455 -0
  19. pycharting-0.1.0/src/charting/frontend/index.html +215 -0
  20. pycharting-0.1.0/src/charting/frontend/layout-manager.js +683 -0
  21. pycharting-0.1.0/src/charting/frontend/multi-chart.js +1779 -0
  22. pycharting-0.1.0/src/charting/ingestion/__init__.py +2 -0
  23. pycharting-0.1.0/src/charting/ingestion/loader.py +314 -0
  24. pycharting-0.1.0/src/charting/ingestion/schema.py +67 -0
  25. pycharting-0.1.0/src/charting/launcher.py +212 -0
  26. pycharting-0.1.0/src/charting/mapper.py +316 -0
  27. pycharting-0.1.0/src/charting/processing/__init__.py +2 -0
  28. pycharting-0.1.0/src/charting/processing/indicators.py +248 -0
  29. pycharting-0.1.0/src/charting/processing/pivot.py +218 -0
  30. pycharting-0.1.0/src/charting/processing/resampler.py +422 -0
  31. pycharting-0.1.0/src/charting/server.py +198 -0
  32. pycharting-0.1.0/src/charting/transformer.py +222 -0
@@ -0,0 +1,676 @@
1
+ Metadata-Version: 2.1
2
+ Name: pycharting
3
+ Version: 0.1.0
4
+ Summary: High-performance financial charting library for OHLC data visualization with technical indicators
5
+ Home-page: https://github.com/alihaskar/pycharting
6
+ License: MIT
7
+ Keywords: charting,finance,ohlc,technical-indicators,trading,visualization
8
+ Author: ali askar
9
+ Author-email: 26202651+alihaskar@users.noreply.github.com
10
+ Requires-Python: >=3.12,<4.0
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Financial and Insurance Industry
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Office/Business :: Financial
18
+ Classifier: Topic :: Scientific/Engineering :: Visualization
19
+ Requires-Dist: fastapi (>=0.123.4,<0.124.0)
20
+ Requires-Dist: numpy (>=2.3.5,<3.0.0)
21
+ Requires-Dist: pandas (>=2.3.3,<3.0.0)
22
+ Requires-Dist: pydantic (>=2.12.5,<3.0.0)
23
+ Requires-Dist: pytz (>=2025.2,<2026.0)
24
+ Requires-Dist: uvicorn (>=0.38.0,<0.39.0)
25
+ Project-URL: Repository, https://github.com/alihaskar/pycharting
26
+ Description-Content-Type: text/markdown
27
+
28
+ # Financial Charting Library
29
+
30
+ A high-performance Python charting library for visualizing OHLC (Open, High, Low, Close) financial data with technical indicators. Built with FastAPI, uPlot, and modern web technologies.
31
+
32
+ ## Quick Start
33
+
34
+ ### Installation
35
+
36
+ ```bash
37
+ # Install dependencies
38
+ poetry install
39
+ ```
40
+
41
+ ### Basic Usage
42
+
43
+ #### Python API (Recommended)
44
+
45
+ ```python
46
+ import pandas as pd
47
+ import charting
48
+
49
+ # Load from CSV file
50
+ charting.plot("data/sample.csv")
51
+
52
+ # Or use a DataFrame directly
53
+ df = pd.read_csv("data/sample.csv")
54
+ df['timestamp'] = pd.to_datetime(df['timestamp'])
55
+ df.set_index('timestamp', inplace=True)
56
+
57
+ # Add indicators as columns (optional)
58
+ df['sma_20'] = df['close'].rolling(20).mean()
59
+ df['rsi_14'] = calculate_rsi(df['close'], 14)
60
+
61
+ # Plot with overlays and subplots
62
+ charting.plot(
63
+ df,
64
+ overlays=['sma_20'], # Indicators on main chart
65
+ subplots=['rsi_14'] # Indicators in separate panels
66
+ )
67
+ ```
68
+
69
+ #### Command Line
70
+
71
+ ```bash
72
+ # Start the server
73
+ poetry run python run.py
74
+
75
+ # Or load data immediately
76
+ poetry run python run.py data/sample.csv
77
+ ```
78
+
79
+ The browser will open automatically at `http://localhost:8000`.
80
+
81
+ ### Example Script
82
+
83
+ See `examples/simple_plot.py` for a complete example with multiple indicators:
84
+
85
+ ```bash
86
+ poetry run python examples/simple_plot.py
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Library Architecture
92
+
93
+ ### Overview
94
+
95
+ ```
96
+ ┌─────────────────────────────────────────────────────────────┐
97
+ │ User Interface │
98
+ │ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ │
99
+ │ │ Python API │ │ Web Browser │ │ Command Line │ │
100
+ │ │charting.plot│ │ (index.html) │ │ (run.py) │ │
101
+ │ └──────┬──────┘ └───────┬───────┘ └────────┬─────────┘ │
102
+ └─────────┼──────────────────┼───────────────────┼────────────┘
103
+ │ │ │
104
+ └──────────────────┼───────────────────┘
105
+
106
+ ┌────────▼─────────┐
107
+ │ FastAPI Server │
108
+ │ (src/api/) │
109
+ │ - main.py │
110
+ │ - routes.py │
111
+ │ - processor.py │
112
+ └────────┬──────────┘
113
+
114
+ ┌──────────────────┼──────────────────┐
115
+ │ │ │
116
+ ┌─────▼──────┐ ┌─────▼──────┐ ┌─────▼──────┐
117
+ │ Ingestion │ │ Processing │ │ Frontend │
118
+ │ (loader) │ │(indicators)│ │ (uPlot) │
119
+ │ - CSV │ │ - RSI │ │ - charts │
120
+ │ - Schema │ │ - SMA/EMA │ │ - dividers│
121
+ │ - Detect │ │ - MACD │ │ - sync │
122
+ └────────────┘ └────────────┘ └────────────┘
123
+ ```
124
+
125
+ ### Component Wiring
126
+
127
+ #### 1. **Data Ingestion Layer** (`src/charting/ingestion/`)
128
+
129
+ **Purpose**: Load and validate CSV data
130
+
131
+ - **`loader.py`**: CSV file reading with automatic column detection
132
+ - **`schema.py`**: Data validation and schema enforcement
133
+ - **`detector.py`**: Auto-detect column names (open/high/low/close/volume)
134
+ - **`mapper.py`**: Map non-standard column names to expected format
135
+
136
+ **Flow**:
137
+ ```
138
+ CSV File → loader.py → detector.py → mapper.py → Validated DataFrame
139
+ ```
140
+
141
+ #### 2. **Processing Layer** (`src/charting/processing/`)
142
+
143
+ **Purpose**: Calculate technical indicators and resample data
144
+
145
+ - **`indicators.py`**: Technical indicators (RSI, SMA, EMA, Bollinger Bands, MACD, Stochastic)
146
+ - **`resampler.py`**: Timeframe conversion (1min → 5min, 15min, 1h, etc.)
147
+ - **`pivot.py`**: Data transformation for efficient rendering
148
+
149
+ **Flow**:
150
+ ```
151
+ DataFrame → indicators.py → Indicator Columns
152
+ DataFrame → resampler.py → Resampled OHLC
153
+ ```
154
+
155
+ #### 3. **API Layer** (`src/charting/api/`)
156
+
157
+ **Purpose**: HTTP server and request handling
158
+
159
+ - **`main.py`**: FastAPI application, CORS, static file serving
160
+ - **`routes.py`**: API endpoints (`/chart-data`, `/health`)
161
+ - **`processor.py`**: Request processing, data loading, indicator calculation
162
+ - **`models.py`**: Pydantic models for request/response validation
163
+
164
+ **Endpoints**:
165
+ ```
166
+ GET /chart-data?filename=X&overlays=Y&subplots=Z
167
+ GET /health
168
+ GET / (serves frontend)
169
+ ```
170
+
171
+ **Flow**:
172
+ ```
173
+ HTTP Request → routes.py → processor.py → ingestion + processing → JSON Response
174
+ ```
175
+
176
+ #### 4. **Python API** (`src/charting/`)
177
+
178
+ **Purpose**: High-level Python interface
179
+
180
+ - **`charting.py`**: Main `Charting` class for loading and displaying data
181
+ - **`server.py`**: Server lifecycle management (start/stop)
182
+ - **`browser.py`**: Automatic browser launching
183
+ - **`launcher.py`**: Process management for server
184
+ - **`transformer.py`**: DataFrame to API format conversion
185
+ - **`__init__.py`**: Public API exports (`plot()` function)
186
+
187
+ **Flow**:
188
+ ```python
189
+ charting.plot(df)
190
+ → Charting.load()
191
+ → server.start()
192
+ → transformer.to_csv()
193
+ → browser.open(url)
194
+ ```
195
+
196
+ #### 5. **Frontend** (`src/charting/frontend/`)
197
+
198
+ **Purpose**: Interactive web-based visualization
199
+
200
+ - **`index.html`**: Main HTML structure, controls, layout
201
+ - **`app.js`**: Application state, event handlers, indicator controls
202
+ - **`multi-chart.js`**: Multiple synchronized uPlot charts (main + subplots)
203
+ - **`chart.js`**: Single chart wrapper (legacy)
204
+ - **`divider.js`**: Draggable dividers for resizing panels
205
+ - **`data-client.js`**: API communication layer
206
+
207
+ **Flow**:
208
+ ```
209
+ index.html loads
210
+ → app.js initializes
211
+ → multi-chart.js creates charts
212
+ → data-client.js fetches data
213
+ → uPlot renders charts
214
+ → divider.js enables resizing
215
+ ```
216
+
217
+ ---
218
+
219
+ ## Data Flow Examples
220
+
221
+ ### Example 1: Loading CSV via Python API
222
+
223
+ ```python
224
+ charting.plot("data/sample.csv", overlays=['sma_20'], subplots=['rsi_14'])
225
+ ```
226
+
227
+ **Step-by-step**:
228
+ 1. `charting.plot()` → calls `Charting().load()`
229
+ 2. `Charting.load()` validates DataFrame or reads CSV
230
+ 3. `server.start()` launches FastAPI on available port
231
+ 4. `transformer.to_csv()` saves DataFrame to temp file
232
+ 5. `browser.open()` opens URL with query params: `?filename=X&overlays=sma_20&subplots=rsi_14`
233
+ 6. Browser loads `index.html` from FastAPI static files
234
+ 7. `app.js` parses URL params and calls `chartManager.loadAndRender()`
235
+ 8. `multi-chart.js` fetches data via `/chart-data` endpoint
236
+ 9. `routes.py` → `processor.py` loads CSV, calculates indicators
237
+ 10. JSON data returned to frontend
238
+ 11. `multi-chart.js` creates uPlot instances (main chart + subplots)
239
+ 12. `divider.js` creates draggable dividers between charts
240
+ 13. Charts synchronized for zoom/pan
241
+
242
+ ### Example 2: Loading CSV via Web Interface
243
+
244
+ ```
245
+ User enters "sample.csv" and clicks "Load Chart"
246
+ ```
247
+
248
+ **Step-by-step**:
249
+ 1. User types filename in input field
250
+ 2. `app.js` event handler captures click
251
+ 3. `app.loadChart()` → `chartManager.loadAndRender(filename)`
252
+ 4. `data-client.js` constructs API URL: `/chart-data?filename=sample.csv`
253
+ 5. FastAPI receives request in `routes.py`
254
+ 6. `processor.process_chart_request()` validates filename
255
+ 7. `loader.py` reads CSV from `data/` directory
256
+ 8. `detector.py` auto-detects column names
257
+ 9. `indicators.py` calculates any requested indicators
258
+ 10. `processor.py` formats data as uPlot-compatible JSON
259
+ 11. Response sent back to browser
260
+ 12. `multi-chart.js` renders charts
261
+ 13. `app.buildIndicatorControls()` creates checkboxes for toggling indicators
262
+
263
+ ### Example 3: Adding Indicators Dynamically
264
+
265
+ ```
266
+ User checks "RSI 14" checkbox
267
+ ```
268
+
269
+ **Step-by-step**:
270
+ 1. Checkbox change event captured by `app.js`
271
+ 2. `chartManager.toggleSubplot('rsi_14')` called
272
+ 3. Updates `visibleSubplots` set
273
+ 4. Updates `config.subplots` array
274
+ 5. Calls `multi-chart.initialize()` to re-render
275
+ 6. Fetches data with new subplot: `/chart-data?subplots=rsi_14`
276
+ 7. `processor.py` calculates RSI if not in CSV
277
+ 8. Returns data with RSI column
278
+ 9. `multi-chart.js` creates new subplot panel
279
+ 10. `divider.js` adds divider above new subplot
280
+ 11. All charts re-synchronized
281
+
282
+ ---
283
+
284
+ ## API Reference
285
+
286
+ ### Python API
287
+
288
+ #### `charting.plot(data, **kwargs)`
289
+
290
+ Plot financial data with a single command.
291
+
292
+ **Parameters**:
293
+ - `data` (DataFrame | str): DataFrame with OHLC data or path to CSV file
294
+ - `overlays` (list[str], optional): Indicators to plot on main chart (e.g., `['sma_20', 'ema_12']`)
295
+ - `subplots` (list[str], optional): Indicators to plot in separate panels (e.g., `['rsi_14', 'macd']`)
296
+
297
+ **Returns**: URL string where chart is served
298
+
299
+ **Example**:
300
+ ```python
301
+ import charting
302
+ charting.plot("data/sample.csv", overlays=['sma_20'], subplots=['rsi_14'])
303
+ ```
304
+
305
+ #### `Charting` Class
306
+
307
+ Advanced usage with more control:
308
+
309
+ ```python
310
+ from charting import Charting
311
+
312
+ chart = Charting()
313
+ url = chart.load(df, overlays=['sma_20'], subplots=['rsi_14'])
314
+ # Server keeps running...
315
+ chart.close() # Stop server
316
+ ```
317
+
318
+ **Methods**:
319
+ - `load(df, **kwargs)`: Load data and start server
320
+ - `close()`: Stop the server
321
+ - `is_running()`: Check if server is running
322
+
323
+ ### HTTP API
324
+
325
+ #### `GET /chart-data`
326
+
327
+ Fetch chart data with optional indicators and timeframe resampling.
328
+
329
+ **Query Parameters**:
330
+ - `filename` (required): CSV file name (relative to `data/` directory)
331
+ - `overlays` (optional): Comma-separated indicator names (e.g., `sma_20,ema_12`)
332
+ - `subplots` (optional): Comma-separated indicator names (e.g., `rsi_14,macd`)
333
+ - `timeframe` (optional): Resample to timeframe (e.g., `5min`, `1h`, `1D`)
334
+
335
+ **Response**:
336
+ ```json
337
+ {
338
+ "data": [
339
+ [1609459200000, 1609459260000, ...], // timestamps
340
+ [100.0, 101.0, ...], // open
341
+ [102.0, 103.0, ...], // high
342
+ [99.0, 100.5, ...], // low
343
+ [101.0, 102.0, ...], // close
344
+ [1000, 1500, ...], // volume
345
+ [100.5, 101.2, ...], // sma_20 (if requested)
346
+ [45.2, 52.1, ...] // rsi_14 (if requested)
347
+ ],
348
+ "metadata": {
349
+ "overlays": ["sma_20"],
350
+ "subplots": ["rsi_14"],
351
+ "filename": "sample.csv",
352
+ "timeframe": "1min"
353
+ }
354
+ }
355
+ ```
356
+
357
+ #### `GET /health`
358
+
359
+ Health check endpoint.
360
+
361
+ **Response**:
362
+ ```json
363
+ {
364
+ "status": "ok",
365
+ "version": "0.1.0"
366
+ }
367
+ ```
368
+
369
+ ---
370
+
371
+ ## Indicators
372
+
373
+ ### Available Indicators
374
+
375
+ #### Overlay Indicators (on main chart)
376
+ - **SMA** - Simple Moving Average
377
+ - `sma_10`, `sma_20`, `sma_50`, `sma_200`
378
+ - **EMA** - Exponential Moving Average
379
+ - `ema_9`, `ema_12`, `ema_21`, `ema_26`
380
+ - **Bollinger Bands**
381
+ - `bb_upper`, `bb_middle`, `bb_lower`
382
+
383
+ #### Subplot Indicators (separate panels)
384
+ - **RSI** - Relative Strength Index
385
+ - `rsi_14` (default period: 14)
386
+ - **MACD** - Moving Average Convergence Divergence
387
+ - `macd`, `macd_signal`, `macd_hist`
388
+ - **Stochastic Oscillator**
389
+ - `stoch_k`, `stoch_d`
390
+ - **Volume SMA**
391
+ - `volume_sma` (volume with 20-period SMA overlay)
392
+
393
+ ### Adding Custom Indicators
394
+
395
+ To add indicators to your data:
396
+
397
+ ```python
398
+ import pandas as pd
399
+
400
+ # Load data
401
+ df = pd.read_csv("data/sample.csv")
402
+ df['timestamp'] = pd.to_datetime(df['timestamp'])
403
+ df.set_index('timestamp', inplace=True)
404
+
405
+ # Calculate indicators
406
+ df['sma_20'] = df['close'].rolling(window=20).mean()
407
+ df['ema_12'] = df['close'].ewm(span=12, adjust=False).mean()
408
+
409
+ # Calculate RSI
410
+ def calculate_rsi(series, period=14):
411
+ delta = series.diff()
412
+ gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
413
+ loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
414
+ rs = gain / loss
415
+ return 100 - (100 / (1 + rs))
416
+
417
+ df['rsi_14'] = calculate_rsi(df['close'], 14)
418
+
419
+ # Plot with indicators
420
+ import charting
421
+ charting.plot(df, overlays=['sma_20', 'ema_12'], subplots=['rsi_14'])
422
+ ```
423
+
424
+ ---
425
+
426
+ ## Frontend Features
427
+
428
+ ### Interactive Controls
429
+
430
+ 1. **Indicator Toggles**: Check/uncheck indicators to show/hide them
431
+ 2. **Draggable Dividers**: Resize chart panels by dragging horizontal dividers
432
+ 3. **Synchronized Zoom**: Zoom/pan on any chart affects all charts
433
+ 4. **Synchronized Crosshair**: Hover cursor synchronized across all panels
434
+ 5. **Timeframe Selection**: Resample data to different timeframes
435
+ 6. **Scrollable Layout**: Page scrolls when you have many indicators
436
+
437
+ ### Keyboard Shortcuts
438
+
439
+ - **Scroll**: Zoom in/out
440
+ - **Click + Drag**: Pan chart
441
+ - **Hover**: Show crosshair with values
442
+
443
+ ---
444
+
445
+ ## Project Structure
446
+
447
+ ```
448
+ charting/
449
+ ├── src/
450
+ │ └── charting/ # Main package
451
+ │ ├── __init__.py # Public API (plot function)
452
+ │ ├── charting.py # Charting class
453
+ │ ├── server.py # Server management
454
+ │ ├── browser.py # Browser launcher
455
+ │ ├── launcher.py # Process management
456
+ │ ├── transformer.py # Data transformation
457
+ │ ├── detector.py # Column detection
458
+ │ ├── mapper.py # Column mapping
459
+ │ │
460
+ │ ├── api/ # FastAPI backend
461
+ │ │ ├── main.py # App entry, static serving
462
+ │ │ ├── routes.py # API endpoints
463
+ │ │ ├── processor.py # Request processing
464
+ │ │ ├── models.py # Pydantic models
465
+ │ │ └── exceptions.py # Custom exceptions
466
+ │ │
467
+ │ ├── ingestion/ # Data loading
468
+ │ │ ├── loader.py # CSV reader
469
+ │ │ └── schema.py # Validation
470
+ │ │
471
+ │ ├── processing/ # Data processing
472
+ │ │ ├── indicators.py # Technical indicators
473
+ │ │ ├── resampler.py # Timeframe conversion
474
+ │ │ └── pivot.py # Data transformation
475
+ │ │
476
+ │ └── frontend/ # Web UI
477
+ │ ├── index.html # Main page
478
+ │ ├── app.js # Application logic
479
+ │ ├── multi-chart.js # Multi-chart manager
480
+ │ ├── chart.js # Single chart (legacy)
481
+ │ ├── divider.js # Resizable dividers
482
+ │ ├── divider.css # Divider styles
483
+ │ ├── data-client.js # API client
484
+ │ ├── layout-manager.js # Layout utilities
485
+ │ └── ...
486
+
487
+ ├── examples/
488
+ │ ├── simple_plot.py # Basic usage example
489
+ │ └── demo_all_features.py # Advanced example
490
+
491
+ ├── data/ # Sample CSV files
492
+ │ ├── sample.csv # Moderate volatility
493
+ │ ├── crypto.csv # High volatility
494
+ │ └── stock.csv # Low volatility
495
+
496
+ ├── tests/ # Test suite
497
+ │ ├── test_api_*.py # API tests
498
+ │ ├── test_indicators_*.py # Indicator tests
499
+ │ ├── test_frontend_*.py # Frontend tests
500
+ │ └── ...
501
+
502
+ ├── pyproject.toml # Poetry config
503
+ ├── README.md # This file
504
+ └── run.py # CLI launcher
505
+ ```
506
+
507
+ ---
508
+
509
+ ## Development
510
+
511
+ ### Running Tests
512
+
513
+ ```bash
514
+ # Run all tests
515
+ poetry run pytest
516
+
517
+ # Run specific test file
518
+ poetry run pytest tests/test_indicators.py
519
+
520
+ # Run with coverage
521
+ poetry run pytest --cov=src --cov-report=html
522
+
523
+ # Run only fast tests (skip integration)
524
+ poetry run pytest -m "not integration"
525
+ ```
526
+
527
+ ### Code Quality
528
+
529
+ ```bash
530
+ # Format code
531
+ poetry run black src tests
532
+
533
+ # Check types
534
+ poetry run mypy src
535
+
536
+ # Lint
537
+ poetry run ruff check src tests
538
+ ```
539
+
540
+ ### Adding Dependencies
541
+
542
+ ```bash
543
+ # Production dependency
544
+ poetry add package-name
545
+
546
+ # Development dependency
547
+ poetry add --group dev package-name
548
+ ```
549
+
550
+ ---
551
+
552
+ ## Configuration
553
+
554
+ ### Server Configuration
555
+
556
+ The server automatically:
557
+ - Finds an available port (starts at 8000, increments if busy)
558
+ - Enables CORS for local development
559
+ - Serves static files from `src/charting/frontend/`
560
+ - Handles graceful shutdown
561
+
562
+ ### Data Requirements
563
+
564
+ CSV files must have:
565
+ - **Required columns**: timestamp, open, high, low, close
566
+ - **Optional columns**: volume, any indicator columns
567
+ - **Timestamp format**: ISO8601, Unix timestamp, or parseable date string
568
+
569
+ **Example CSV**:
570
+ ```csv
571
+ timestamp,open,high,low,close,volume
572
+ 2024-01-01 00:00:00,100.0,102.0,99.0,101.0,1000
573
+ 2024-01-01 00:01:00,101.0,103.0,100.5,102.0,1500
574
+ ```
575
+
576
+ ---
577
+
578
+ ## Performance
579
+
580
+ ### Benchmarks
581
+
582
+ - **Render**: 500k+ points at 60fps
583
+ - **Load**: 100MB CSV in <2 seconds
584
+ - **Interaction**: <16ms zoom/pan latency
585
+ - **Memory**: Efficient columnar data storage
586
+
587
+ ### Optimization Tips
588
+
589
+ 1. **Use appropriate timeframes**: Higher timeframes = less data = faster rendering
590
+ 2. **Limit indicators**: Each indicator adds a render pass
591
+ 3. **CSV optimization**: Pre-calculate indicators and save to CSV
592
+ 4. **Batch operations**: Load multiple indicators at once instead of one-by-one
593
+
594
+ ---
595
+
596
+ ## Troubleshooting
597
+
598
+ ### Common Issues
599
+
600
+ **"Failed to load chart"**
601
+ - Ensure CSV file exists in `data/` directory
602
+ - Check CSV format (must have OHLC columns)
603
+ - Verify server is running (`http://localhost:8000/health`)
604
+
605
+ **"Module not found"**
606
+ - Run `poetry install` to install dependencies
607
+ - Ensure you're using `poetry run python` or `poetry shell`
608
+
609
+ **"Port already in use"**
610
+ - Server auto-increments to find available port
611
+ - Check terminal output for actual port number
612
+ - Or manually kill process: `lsof -ti:8000 | xargs kill -9`
613
+
614
+ **Charts not rendering**
615
+ - Open browser console (F12) to check for JavaScript errors
616
+ - Verify data is being returned: `http://localhost:8000/chart-data?filename=sample.csv`
617
+ - Check that uPlot CDN is accessible
618
+
619
+ **Indicators not showing**
620
+ - Ensure indicator data exists in CSV or can be calculated
621
+ - Check browser console for errors
622
+ - Verify indicator names match expected format (e.g., `rsi_14`, not `RSI-14`)
623
+
624
+ ---
625
+
626
+ ## Additional Resources
627
+
628
+ ### Sample Data
629
+
630
+ Generate custom sample data:
631
+ ```bash
632
+ poetry run python scripts/generate_sample_data.py \
633
+ --output data/custom.csv \
634
+ --periods 10000 \
635
+ --freq 1min \
636
+ --price 100.0 \
637
+ --volatility 0.02
638
+ ```
639
+
640
+ ### API Documentation
641
+
642
+ Interactive API docs available at:
643
+ - Swagger UI: `http://localhost:8000/docs`
644
+ - ReDoc: `http://localhost:8000/redoc`
645
+
646
+ ---
647
+
648
+ ## License
649
+
650
+ MIT License - see LICENSE file for details
651
+
652
+ ---
653
+
654
+ ## Contributing
655
+
656
+ Contributions welcome! Please:
657
+ 1. Fork the repository
658
+ 2. Create a feature branch
659
+ 3. Add tests for new functionality
660
+ 4. Ensure all tests pass
661
+ 5. Submit a pull request
662
+
663
+ ---
664
+
665
+ ## Support
666
+
667
+ For issues, questions, or suggestions:
668
+ - Open an issue on GitHub
669
+ - Check existing issues for solutions
670
+ - Review documentation and examples
671
+
672
+ ---
673
+
674
+ Built with ❤️ using FastAPI, uPlot, and Python
675
+ ---
676
+ Built with ❤️ from Dubai