@@ -426,6 +426,100 @@ export class MyCustomAggregator implements IAggregator {
426426 }
427427}
428428```
429+ apps/aggregator/
430+ ├── src/
431+ │ ├── main.ts # Application entry point
432+ │ ├── app.module.ts # Root module
433+ │ ├── interfaces/ # Type definitions
434+ │ │ ├── normalized-price.interface.ts
435+ │ │ └── normalizer.interface.ts
436+ │ ├── normalizers/ # Source-specific normalizers
437+ │ │ ├── base.normalizer.ts
438+ │ │ ├── alpha-vantage.normalizer.ts
439+ │ │ ├── finnhub.normalizer.ts
440+ │ │ ├── yahoo-finance.normalizer.ts
441+ │ │ └── mock.normalizer.ts
442+ │ ├── services/ # Business logic
443+ │ │ └── normalization.service.ts
444+ │ ├── modules/ # Feature modules
445+ │ │ └── normalization.module.ts
446+ │ └── exceptions/ # Custom exceptions
447+ │ └── normalization.exception.ts
448+ ├── .env.example # Example environment variables
449+ ├── nest-cli.json # NestJS CLI configuration
450+ ├── package.json # Dependencies and scripts
451+ ├── tsconfig.json # TypeScript configuration
452+ └── README.md # This file
453+ ```
454+
455+ ## Data Normalization
456+
457+ ### NormalizedPrice Interface
458+
459+ The standard internal format for normalized price data:
460+
461+ ```typescript
462+ interface NormalizedPrice {
463+ symbol: string; // Normalized ticker (e.g., 'AAPL')
464+ price: number; // Price rounded to 4 decimal places
465+ timestamp: string; // ISO 8601 UTC (e.g., '2024-01-15T14:30:00.000Z')
466+ originalTimestamp: number; // Original Unix timestamp in milliseconds
467+ source: NormalizedSource; // Enum: 'alpha_vantage' | 'finnhub' | 'yahoo_finance' | 'mock'
468+ metadata: {
469+ originalSource: string; // Original source string
470+ originalSymbol: string; // Original symbol before normalization
471+ normalizedAt: string; // When normalization occurred
472+ normalizerVersion: string; // Version of normalizer used
473+ wasTransformed: boolean; // Whether transformations were applied
474+ transformations: string[]; // List of transformations applied
475+ };
476+ }
477+ ```
478+
479+ ### Supported Sources and Transformations
480+
481+ | Source | Detected By | Symbol Transformations |
482+ | --------| -------------| ------------------------|
483+ | ** Alpha Vantage** | ` alphavantage ` , ` alpha_vantage ` , ` alpha-vantage ` | Removes ` .US ` , ` .NYSE ` , ` .NASDAQ ` , ` .LSE ` , ` .TSX ` , ` .ASX ` , ` .HK ` suffixes |
484+ | ** Finnhub** | ` finnhub ` | Removes ` US- ` , ` CRYPTO- ` , ` FX- ` , ` INDICES- ` prefixes |
485+ | ** Yahoo Finance** | ` yahoo ` , ` yahoofinance ` , ` yahoo_finance ` , ` yahoo-finance ` | Removes ` .L ` , ` .T ` , ` .AX ` , ` .HK ` , ` .SI ` , ` .KS ` , ` .TW ` , ` .NS ` , ` .BO ` , ` .TO ` , ` .DE ` , ` .PA ` suffixes; removes ` ^ ` index prefix |
486+ | ** Mock** | ` mock ` | Basic cleanup (trim, uppercase) |
487+
488+ ### Common Transformations
489+
490+ All normalizers apply these transformations:
491+ - ** Symbol** : Trimmed and uppercased
492+ - ** Price** : Rounded to 4 decimal places
493+ - ** Timestamp** : Converted to ISO 8601 UTC format
494+
495+ ### Usage Example
496+
497+ ``` typescript
498+ import { NormalizationService } from ' ./services/normalization.service' ;
499+
500+ // Inject via NestJS DI
501+ constructor (private readonly normalizationService : NormalizationService ) {}
502+
503+ // Normalize a single price
504+ const rawPrice = {
505+ symbol: ' AAPL.US' ,
506+ price: 150.123456 ,
507+ timestamp: Date .now (),
508+ source: ' AlphaVantage' ,
509+ };
510+ const normalized = this .normalizationService .normalize (rawPrice );
511+ // Result: { symbol: 'AAPL', price: 150.1235, timestamp: '2024-01-15T14:30:00.000Z', ... }
512+
513+ // Normalize multiple prices (skips failures)
514+ const results = this .normalizationService .normalizeMany (rawPrices );
515+
516+ // Normalize with error tracking
517+ const { successful, failed } = this .normalizationService .normalizeManyWithErrors (rawPrices );
518+ ```
519+
520+ ## Status
521+
522+ 🚧 Under construction - Aggregation and filtering logic will be implemented in subsequent issues.
429523
4305242 . Register in ` AggregationService ` constructor:
431525
0 commit comments