moved to zod, packages messed up still

This commit is contained in:
Bojan Kucera 2025-06-07 14:24:28 -04:00
parent 15dd03c0ec
commit a8ee4022bf
35 changed files with 3245 additions and 691 deletions

View file

@ -1,29 +1,31 @@
/**
* Admin interfaces configuration using envalid
* Admin interfaces configuration using Zod
* PgAdmin, Mongo Express, Redis Insight for database management
*/
import { cleanEnv, str, port, bool } from 'envalid';
import { cleanEnv, envValidators } from './env-utils';
const { str, port, bool, strWithChoices } = envValidators;
/**
* PgAdmin configuration with validation and defaults
*/
export const pgAdminConfig = cleanEnv(process.env, {
// PgAdmin Server
PGADMIN_HOST: str({ default: 'localhost', desc: 'PgAdmin host' }),
PGADMIN_PORT: port({ default: 8080, desc: 'PgAdmin port' }),
PGADMIN_HOST: str('localhost', 'PgAdmin host'),
PGADMIN_PORT: port(8080, 'PgAdmin port'),
// Authentication
PGADMIN_DEFAULT_EMAIL: str({ default: 'admin@tradingbot.local', desc: 'PgAdmin default admin email' }),
PGADMIN_DEFAULT_PASSWORD: str({ default: 'admin123', desc: 'PgAdmin default admin password' }),
PGADMIN_DEFAULT_EMAIL: str('admin@tradingbot.local', 'PgAdmin default admin email'),
PGADMIN_DEFAULT_PASSWORD: str('admin123', 'PgAdmin default admin password'),
// Configuration
PGADMIN_SERVER_MODE: bool({ default: false, desc: 'Enable server mode (multi-user)' }),
PGADMIN_DISABLE_POSTFIX: bool({ default: true, desc: 'Disable postfix for email' }),
PGADMIN_CONFIG_ENHANCED_COOKIE_PROTECTION: bool({ default: true, desc: 'Enhanced cookie protection' }),
PGADMIN_SERVER_MODE: bool(false, 'Enable server mode (multi-user)'),
PGADMIN_DISABLE_POSTFIX: bool(true, 'Disable postfix for email'),
PGADMIN_CONFIG_ENHANCED_COOKIE_PROTECTION: bool(true, 'Enhanced cookie protection'),
// Security
PGADMIN_MASTER_PASSWORD_REQUIRED: bool({ default: false, desc: 'Require master password' }),
PGADMIN_SESSION_TIMEOUT: str({ default: '60', desc: 'Session timeout in minutes' }),
PGADMIN_MASTER_PASSWORD_REQUIRED: bool(false, 'Require master password'),
PGADMIN_SESSION_TIMEOUT: str('60', 'Session timeout in minutes'),
});
/**
@ -31,26 +33,23 @@ export const pgAdminConfig = cleanEnv(process.env, {
*/
export const mongoExpressConfig = cleanEnv(process.env, {
// Mongo Express Server
MONGO_EXPRESS_HOST: str({ default: 'localhost', desc: 'Mongo Express host' }),
MONGO_EXPRESS_PORT: port({ default: 8081, desc: 'Mongo Express port' }),
MONGO_EXPRESS_HOST: str('localhost', 'Mongo Express host'),
MONGO_EXPRESS_PORT: port(8081, 'Mongo Express port'),
// MongoDB Connection
MONGO_EXPRESS_MONGODB_SERVER: str({ default: 'mongodb', desc: 'MongoDB server name/host' }),
MONGO_EXPRESS_MONGODB_PORT: port({ default: 27017, desc: 'MongoDB port' }),
MONGO_EXPRESS_MONGODB_ADMINUSERNAME: str({ default: 'trading_admin', desc: 'MongoDB admin username' }),
MONGO_EXPRESS_MONGODB_ADMINPASSWORD: str({ default: '', desc: 'MongoDB admin password' }),
MONGO_EXPRESS_MONGODB_SERVER: str('mongodb', 'MongoDB server name/host'),
MONGO_EXPRESS_MONGODB_PORT: port(27017, 'MongoDB port'),
MONGO_EXPRESS_MONGODB_ADMINUSERNAME: str('trading_admin', 'MongoDB admin username'),
MONGO_EXPRESS_MONGODB_ADMINPASSWORD: str('', 'MongoDB admin password'),
// Basic Authentication for Mongo Express
MONGO_EXPRESS_BASICAUTH_USERNAME: str({ default: 'admin', desc: 'Basic auth username for Mongo Express' }),
MONGO_EXPRESS_BASICAUTH_PASSWORD: str({ default: 'admin123', desc: 'Basic auth password for Mongo Express' }),
MONGO_EXPRESS_BASICAUTH_USERNAME: str('admin', 'Basic auth username for Mongo Express'),
MONGO_EXPRESS_BASICAUTH_PASSWORD: str('admin123', 'Basic auth password for Mongo Express'),
// Configuration
MONGO_EXPRESS_ENABLE_ADMIN: bool({ default: true, desc: 'Enable admin features' }),
MONGO_EXPRESS_OPTIONS_EDITOR_THEME: str({
default: 'rubyblue',
desc: 'Editor theme (rubyblue, 3024-night, etc.)'
}),
MONGO_EXPRESS_REQUEST_SIZE: str({ default: '100kb', desc: 'Maximum request size' }),
MONGO_EXPRESS_ENABLE_ADMIN: bool(true, 'Enable admin features'),
MONGO_EXPRESS_OPTIONS_EDITOR_THEME: str('rubyblue', 'Editor theme (rubyblue, 3024-night, etc.)'),
MONGO_EXPRESS_REQUEST_SIZE: str('100kb', 'Maximum request size'),
});
/**
@ -58,23 +57,16 @@ export const mongoExpressConfig = cleanEnv(process.env, {
*/
export const redisInsightConfig = cleanEnv(process.env, {
// Redis Insight Server
REDIS_INSIGHT_HOST: str({ default: 'localhost', desc: 'Redis Insight host' }),
REDIS_INSIGHT_PORT: port({ default: 8001, desc: 'Redis Insight port' }),
REDIS_INSIGHT_HOST: str('localhost', 'Redis Insight host'),
REDIS_INSIGHT_PORT: port(8001, 'Redis Insight port'),
// Redis Connection Settings
REDIS_INSIGHT_REDIS_HOSTS: str({
default: 'local:dragonfly:6379',
desc: 'Redis hosts in format name:host:port,name:host:port'
}),
REDIS_INSIGHT_REDIS_HOSTS: str('local:dragonfly:6379', 'Redis hosts in format name:host:port,name:host:port'),
// Configuration
REDIS_INSIGHT_LOG_LEVEL: str({
default: 'info',
choices: ['error', 'warn', 'info', 'verbose', 'debug'],
desc: 'Redis Insight log level'
}),
REDIS_INSIGHT_DISABLE_ANALYTICS: bool({ default: true, desc: 'Disable analytics collection' }),
REDIS_INSIGHT_BUILD_TYPE: str({ default: 'DOCKER', desc: 'Build type identifier' }),
REDIS_INSIGHT_LOG_LEVEL: strWithChoices(['error', 'warn', 'info', 'verbose', 'debug'], 'info', 'Redis Insight log level'),
REDIS_INSIGHT_DISABLE_ANALYTICS: bool(true, 'Disable analytics collection'),
REDIS_INSIGHT_BUILD_TYPE: str('DOCKER', 'Build type identifier'),
});
// Export typed configuration objects

View file

@ -1,5 +1,5 @@
/**
* Core configuration module for the Stock Bot platform using envalid
* Core configuration module for the Stock Bot platform using Zod
*/
import { config as dotenvConfig } from 'dotenv';
import path from 'node:path';

View file

@ -1,7 +1,9 @@
/**
* Data provider configurations using envalid
* Data provider configurations using Zod
*/
import { cleanEnv, str, num, bool } from 'envalid';
import { cleanEnv, envValidators } from './env-utils';
const { str, num, bool, strWithChoices } = envValidators;
export interface ProviderConfig {
name: string;
@ -21,45 +23,41 @@ export interface ProviderConfig {
*/
export const dataProvidersConfig = cleanEnv(process.env, {
// Default Provider
DEFAULT_DATA_PROVIDER: str({
choices: ['alpaca', 'polygon', 'yahoo', 'iex'],
default: 'alpaca',
desc: 'Default data provider'
}),
DEFAULT_DATA_PROVIDER: strWithChoices(['alpaca', 'polygon', 'yahoo', 'iex'], 'alpaca', 'Default data provider'),
// Alpaca Configuration
ALPACA_API_KEY: str({ default: '', desc: 'Alpaca API key' }),
ALPACA_API_SECRET: str({ default: '', desc: 'Alpaca API secret' }),
ALPACA_BASE_URL: str({ default: 'https://data.alpaca.markets/v1beta1', desc: 'Alpaca base URL' }),
ALPACA_RATE_LIMIT: num({ default: 200, desc: 'Alpaca rate limit per minute' }),
ALPACA_ENABLED: bool({ default: true, desc: 'Enable Alpaca provider' }),
ALPACA_API_KEY: str('', 'Alpaca API key'),
ALPACA_API_SECRET: str('', 'Alpaca API secret'),
ALPACA_BASE_URL: str('https://data.alpaca.markets/v1beta1', 'Alpaca base URL'),
ALPACA_RATE_LIMIT: num(200, 'Alpaca rate limit per minute'),
ALPACA_ENABLED: bool(true, 'Enable Alpaca provider'),
// Polygon Configuration
POLYGON_API_KEY: str({ default: '', desc: 'Polygon API key' }),
POLYGON_BASE_URL: str({ default: 'https://api.polygon.io', desc: 'Polygon base URL' }),
POLYGON_RATE_LIMIT: num({ default: 5, desc: 'Polygon rate limit per minute' }),
POLYGON_ENABLED: bool({ default: false, desc: 'Enable Polygon provider' }),
POLYGON_API_KEY: str('', 'Polygon API key'),
POLYGON_BASE_URL: str('https://api.polygon.io', 'Polygon base URL'),
POLYGON_RATE_LIMIT: num(5, 'Polygon rate limit per minute'),
POLYGON_ENABLED: bool(false, 'Enable Polygon provider'),
// Yahoo Finance Configuration
YAHOO_BASE_URL: str({ default: 'https://query1.finance.yahoo.com', desc: 'Yahoo Finance base URL' }),
YAHOO_RATE_LIMIT: num({ default: 2000, desc: 'Yahoo Finance rate limit per hour' }),
YAHOO_ENABLED: bool({ default: true, desc: 'Enable Yahoo Finance provider' }),
YAHOO_BASE_URL: str('https://query1.finance.yahoo.com', 'Yahoo Finance base URL'),
YAHOO_RATE_LIMIT: num(2000, 'Yahoo Finance rate limit per hour'),
YAHOO_ENABLED: bool(true, 'Enable Yahoo Finance provider'),
// IEX Cloud Configuration
IEX_API_KEY: str({ default: '', desc: 'IEX Cloud API key' }),
IEX_BASE_URL: str({ default: 'https://cloud.iexapis.com/stable', desc: 'IEX Cloud base URL' }),
IEX_RATE_LIMIT: num({ default: 100, desc: 'IEX Cloud rate limit per second' }),
IEX_ENABLED: bool({ default: false, desc: 'Enable IEX Cloud provider' }),
IEX_API_KEY: str('', 'IEX Cloud API key'),
IEX_BASE_URL: str('https://cloud.iexapis.com/stable', 'IEX Cloud base URL'),
IEX_RATE_LIMIT: num(100, 'IEX Cloud rate limit per second'),
IEX_ENABLED: bool(false, 'Enable IEX Cloud provider'),
// Connection Settings
DATA_PROVIDER_TIMEOUT: num({ default: 30000, desc: 'Request timeout in milliseconds' }),
DATA_PROVIDER_RETRIES: num({ default: 3, desc: 'Number of retry attempts' }),
DATA_PROVIDER_RETRY_DELAY: num({ default: 1000, desc: 'Retry delay in milliseconds' }),
DATA_PROVIDER_TIMEOUT: num(30000, 'Request timeout in milliseconds'),
DATA_PROVIDER_RETRIES: num(3, 'Number of retry attempts'),
DATA_PROVIDER_RETRY_DELAY: num(1000, 'Retry delay in milliseconds'),
// Cache Settings
DATA_CACHE_ENABLED: bool({ default: true, desc: 'Enable data caching' }),
DATA_CACHE_TTL: num({ default: 300000, desc: 'Cache TTL in milliseconds' }),
DATA_CACHE_MAX_SIZE: num({ default: 1000, desc: 'Maximum cache entries' }),
DATA_CACHE_ENABLED: bool(true, 'Enable data caching'),
DATA_CACHE_TTL: num(300000, 'Cache TTL in milliseconds'),
DATA_CACHE_MAX_SIZE: num(1000, 'Maximum cache entries'),
});
/**

View file

@ -1,34 +1,36 @@
/**
* Database configuration using envalid
* Database configuration using Zod
*/
import { cleanEnv, str, port, bool, num } from 'envalid';
import { cleanEnv, envValidators } from './env-utils.js';
const { str, port, num, bool } = envValidators;
/**
* Database configuration with validation and defaults
*/
export const databaseConfig = cleanEnv(process.env, {
// PostgreSQL Configuration
DB_HOST: str({ default: 'localhost', desc: 'Database host' }),
DB_PORT: port({ default: 5432, desc: 'Database port' }),
DB_NAME: str({ default: 'stockbot', desc: 'Database name' }),
DB_USER: str({ default: 'stockbot', desc: 'Database user' }),
DB_PASSWORD: str({ default: '', desc: 'Database password' }),
DB_HOST: str('localhost', 'Database host'),
DB_PORT: port(5432, 'Database port'),
DB_NAME: str('stockbot', 'Database name'),
DB_USER: str('stockbot', 'Database user'),
DB_PASSWORD: str('', 'Database password'),
// Connection Pool Settings
DB_POOL_MIN: num({ default: 2, desc: 'Minimum pool connections' }),
DB_POOL_MAX: num({ default: 10, desc: 'Maximum pool connections' }),
DB_POOL_IDLE_TIMEOUT: num({ default: 30000, desc: 'Pool idle timeout in ms' }),
DB_POOL_MIN: num(2, 'Minimum pool connections'),
DB_POOL_MAX: num(10, 'Maximum pool connections'),
DB_POOL_IDLE_TIMEOUT: num(30000, 'Pool idle timeout in ms'),
// SSL Configuration
DB_SSL: bool({ default: false, desc: 'Enable SSL for database connection' }),
DB_SSL_REJECT_UNAUTHORIZED: bool({ default: true, desc: 'Reject unauthorized SSL certificates' }),
DB_SSL: bool(false, 'Enable SSL for database connection'),
DB_SSL_REJECT_UNAUTHORIZED: bool(true, 'Reject unauthorized SSL certificates'),
// Additional Settings
DB_QUERY_TIMEOUT: num({ default: 30000, desc: 'Query timeout in ms' }),
DB_CONNECTION_TIMEOUT: num({ default: 5000, desc: 'Connection timeout in ms' }),
DB_STATEMENT_TIMEOUT: num({ default: 30000, desc: 'Statement timeout in ms' }),
DB_LOCK_TIMEOUT: num({ default: 10000, desc: 'Lock timeout in ms' }),
DB_IDLE_IN_TRANSACTION_SESSION_TIMEOUT: num({ default: 60000, desc: 'Idle in transaction timeout in ms' }),
DB_QUERY_TIMEOUT: num(30000, 'Query timeout in ms'),
DB_CONNECTION_TIMEOUT: num(5000, 'Connection timeout in ms'),
DB_STATEMENT_TIMEOUT: num(30000, 'Statement timeout in ms'),
DB_LOCK_TIMEOUT: num(10000, 'Lock timeout in ms'),
DB_IDLE_IN_TRANSACTION_SESSION_TIMEOUT: num(60000, 'Idle in transaction timeout in ms'),
});
// Export typed configuration object

View file

@ -1,51 +1,53 @@
/**
* Dragonfly (Redis replacement) configuration using envalid
* Dragonfly (Redis replacement) configuration using Zod
* High-performance caching and event streaming
*/
import { cleanEnv, str, port, bool, num } from 'envalid';
import { cleanEnv, envValidators } from './env-utils.js';
const { str, port, num, bool } = envValidators;
/**
* Dragonfly configuration with validation and defaults
*/
export const dragonflyConfig = cleanEnv(process.env, {
// Dragonfly Connection
DRAGONFLY_HOST: str({ default: 'localhost', desc: 'Dragonfly host' }),
DRAGONFLY_PORT: port({ default: 6379, desc: 'Dragonfly port' }),
DRAGONFLY_PASSWORD: str({ default: '', desc: 'Dragonfly password (if auth enabled)' }),
DRAGONFLY_USERNAME: str({ default: '', desc: 'Dragonfly username (if ACL enabled)' }),
DRAGONFLY_HOST: str('localhost', 'Dragonfly host'),
DRAGONFLY_PORT: port(6379, 'Dragonfly port'),
DRAGONFLY_PASSWORD: str('', 'Dragonfly password (if auth enabled)'),
DRAGONFLY_USERNAME: str('', 'Dragonfly username (if ACL enabled)'),
// Database Selection
DRAGONFLY_DATABASE: num({ default: 0, desc: 'Dragonfly database number (0-15)' }),
DRAGONFLY_DATABASE: num(0, 'Dragonfly database number (0-15)'),
// Connection Pool Settings
DRAGONFLY_MAX_RETRIES: num({ default: 3, desc: 'Maximum retry attempts' }),
DRAGONFLY_RETRY_DELAY: num({ default: 50, desc: 'Retry delay in ms' }),
DRAGONFLY_CONNECT_TIMEOUT: num({ default: 10000, desc: 'Connection timeout in ms' }),
DRAGONFLY_COMMAND_TIMEOUT: num({ default: 5000, desc: 'Command timeout in ms' }),
DRAGONFLY_MAX_RETRIES: num(3, 'Maximum retry attempts'),
DRAGONFLY_RETRY_DELAY: num(50, 'Retry delay in ms'),
DRAGONFLY_CONNECT_TIMEOUT: num(10000, 'Connection timeout in ms'),
DRAGONFLY_COMMAND_TIMEOUT: num(5000, 'Command timeout in ms'),
// Pool Configuration
DRAGONFLY_POOL_SIZE: num({ default: 10, desc: 'Connection pool size' }),
DRAGONFLY_POOL_MIN: num({ default: 1, desc: 'Minimum pool connections' }),
DRAGONFLY_POOL_MAX: num({ default: 20, desc: 'Maximum pool connections' }),
DRAGONFLY_POOL_SIZE: num(10, 'Connection pool size'),
DRAGONFLY_POOL_MIN: num(1, 'Minimum pool connections'),
DRAGONFLY_POOL_MAX: num(20, 'Maximum pool connections'),
// TLS Settings
DRAGONFLY_TLS: bool({ default: false, desc: 'Enable TLS for Dragonfly connection' }),
DRAGONFLY_TLS_CERT_FILE: str({ default: '', desc: 'Path to TLS certificate file' }),
DRAGONFLY_TLS_KEY_FILE: str({ default: '', desc: 'Path to TLS key file' }),
DRAGONFLY_TLS_CA_FILE: str({ default: '', desc: 'Path to TLS CA certificate file' }),
DRAGONFLY_TLS_SKIP_VERIFY: bool({ default: false, desc: 'Skip TLS certificate verification' }),
DRAGONFLY_TLS: bool(false, 'Enable TLS for Dragonfly connection'),
DRAGONFLY_TLS_CERT_FILE: str('', 'Path to TLS certificate file'),
DRAGONFLY_TLS_KEY_FILE: str('', 'Path to TLS key file'),
DRAGONFLY_TLS_CA_FILE: str('', 'Path to TLS CA certificate file'),
DRAGONFLY_TLS_SKIP_VERIFY: bool(false, 'Skip TLS certificate verification'),
// Performance Settings
DRAGONFLY_ENABLE_KEEPALIVE: bool({ default: true, desc: 'Enable TCP keepalive' }),
DRAGONFLY_KEEPALIVE_INTERVAL: num({ default: 60, desc: 'Keepalive interval in seconds' }),
DRAGONFLY_ENABLE_KEEPALIVE: bool(true, 'Enable TCP keepalive'),
DRAGONFLY_KEEPALIVE_INTERVAL: num(60, 'Keepalive interval in seconds'),
// Clustering (if using cluster mode)
DRAGONFLY_CLUSTER_MODE: bool({ default: false, desc: 'Enable cluster mode' }),
DRAGONFLY_CLUSTER_NODES: str({ default: '', desc: 'Comma-separated list of cluster nodes (host:port)' }),
DRAGONFLY_CLUSTER_MODE: bool(false, 'Enable cluster mode'),
DRAGONFLY_CLUSTER_NODES: str('', 'Comma-separated list of cluster nodes (host:port)'),
// Memory and Cache Settings
DRAGONFLY_MAX_MEMORY: str({ default: '2gb', desc: 'Maximum memory usage' }),
DRAGONFLY_CACHE_MODE: bool({ default: true, desc: 'Enable cache mode' }),
DRAGONFLY_MAX_MEMORY: str('2gb', 'Maximum memory usage'),
DRAGONFLY_CACHE_MODE: bool(true, 'Enable cache mode'),
});
// Export typed configuration object

View file

@ -0,0 +1,91 @@
/**
* Environment validation utilities using Zod
*/
import { z } from 'zod';
import { config } from 'dotenv';
// Load environment variables
config();
/**
* Creates a Zod schema for environment variable validation
*/
export function createEnvSchema<T extends z.ZodRawShape>(shape: T) {
return z.object(shape);
}
/**
* Validates environment variables against a Zod schema
*/
export function validateEnv<T extends z.ZodRawShape>(
schema: z.ZodObject<T>,
env = process.env
): z.infer<z.ZodObject<T>> {
const result = schema.safeParse(env);
if (!result.success) {
console.error('❌ Invalid environment variables:');
result.error.issues.forEach((issue: any) => {
console.error(` ${issue.path.join('.')}: ${issue.message}`);
});
throw new Error('Environment validation failed');
}
return result.data;
}
/**
* Helper functions for common validation patterns
*/
export const envValidators = { // String with default
str: (defaultValue?: string, description?: string) =>
z.string().default(defaultValue || '').describe(description || ''),
// String with choices (enum)
strWithChoices: (choices: string[], defaultValue?: string, description?: string) =>
z.enum(choices as [string, ...string[]])
.default((defaultValue || choices[0]) as any)
.describe(description || ''),
// Required string
requiredStr: (description?: string) =>
z.string().min(1, 'Required').describe(description || ''),
// Port number
port: (defaultValue?: number, description?: string) =>
z.string().transform((val: string) => parseInt(val, 10))
.pipe(z.number().int().min(1).max(65535))
.default(defaultValue?.toString() || '3000')
.describe(description || ''),
// Number with default
num: (defaultValue?: number, description?: string) =>
z.string().transform((val: string) => parseInt(val, 10))
.pipe(z.number())
.default(defaultValue?.toString() || '0')
.describe(description || ''),
// Boolean with default
bool: (defaultValue?: boolean, description?: string) =>
z.string().transform((val: string) => val === 'true' || val === '1')
.default(defaultValue?.toString() || 'false')
.describe(description || ''),
// URL validation
url: (defaultValue?: string, description?: string) =>
z.string().url().default(defaultValue || 'http://localhost')
.describe(description || ''),
// Email validation
email: (description?: string) =>
z.string().email().describe(description || ''),
};
/**
* Legacy compatibility - creates a cleanEnv-like function
*/
export function cleanEnv<T extends z.ZodRawShape>(
env: Record<string, string | undefined>,
validators: T
): z.infer<z.ZodObject<T>> {
const schema = createEnvSchema(validators);
return validateEnv(schema, env);
}

View file

@ -1,7 +1,7 @@
/**
* Example usage of the Stock Bot configuration library
*
* This file demonstrates how to use the envalid-based configuration
* This file demonstrates how to use the Zod-based configuration
* system for various services in the Stock Bot platform.
*/

View file

@ -1,25 +1,20 @@
/**
* @stock-bot/config
*
* Configuration management library for Stock Bot platform using envalid
* Configuration management library for Stock Bot platform using Zod
*/
// Core configuration functionality
// Re-export everything from all modules
export * from './env-utils';
export * from './core';
// Database configurations
export * from './admin-interfaces';
export * from './database';
export * from './dragonfly';
export * from './postgres';
export * from './questdb';
export * from './mongodb';
export * from './dragonfly';
// Logging and monitoring configurations
export * from './logging';
export * from './loki';
export * from './monitoring';
// Data provider configurations
export * from './data-providers';
// Risk management configurations
export * from './risk';

View file

@ -1,55 +1,48 @@
/**
* Logging configuration using envalid
* Logging configuration using Zod
* Application logging settings without Loki (Loki config is in monitoring.ts)
*/
import { cleanEnv, str, bool, num } from 'envalid';
import { cleanEnv, envValidators } from './env-utils';
const { str, bool, num, strWithChoices } = envValidators;
/**
* Logging configuration with validation and defaults
*/
export const loggingConfig = cleanEnv(process.env, {
// Basic Logging Settings
LOG_LEVEL: str({
default: 'info',
choices: ['debug' , 'info' , 'warn' , 'error'],
desc: 'Logging level'
}),
LOG_FORMAT: str({
default: 'json',
choices: ['json', 'simple', 'combined'],
desc: 'Log output format'
}),
LOG_CONSOLE: bool({ default: true, desc: 'Enable console logging' }),
LOG_FILE: bool({ default: false, desc: 'Enable file logging' }),
LOG_LEVEL: strWithChoices(['debug', 'info', 'warn', 'error'], 'info', 'Logging level'),
LOG_FORMAT: strWithChoices(['json', 'simple', 'combined'], 'json', 'Log output format'),
LOG_CONSOLE: bool(true, 'Enable console logging'),
LOG_FILE: bool(false, 'Enable file logging'),
// File Logging Settings
LOG_FILE_PATH: str({ default: 'logs', desc: 'Log file directory path' }),
LOG_FILE_MAX_SIZE: str({ default: '20m', desc: 'Maximum log file size' }),
LOG_FILE_MAX_FILES: num({ default: 14, desc: 'Maximum number of log files to keep' }),
LOG_FILE_DATE_PATTERN: str({ default: 'YYYY-MM-DD', desc: 'Log file date pattern' }),
LOG_FILE_PATH: str('logs', 'Log file directory path'),
LOG_FILE_MAX_SIZE: str('20m', 'Maximum log file size'),
LOG_FILE_MAX_FILES: num(14, 'Maximum number of log files to keep'),
LOG_FILE_DATE_PATTERN: str('YYYY-MM-DD', 'Log file date pattern'),
// Error Logging
LOG_ERROR_FILE: bool({ default: true, desc: 'Enable separate error log file' }),
LOG_ERROR_STACK: bool({ default: true, desc: 'Include stack traces in error logs' }),
LOG_ERROR_FILE: bool(true, 'Enable separate error log file'),
LOG_ERROR_STACK: bool(true, 'Include stack traces in error logs'),
// Performance Logging
LOG_PERFORMANCE: bool({ default: false, desc: 'Enable performance logging' }),
LOG_SQL_QUERIES: bool({ default: false, desc: 'Log SQL queries' }),
LOG_HTTP_REQUESTS: bool({ default: true, desc: 'Log HTTP requests' }),
LOG_PERFORMANCE: bool(false, 'Enable performance logging'),
LOG_SQL_QUERIES: bool(false, 'Log SQL queries'),
LOG_HTTP_REQUESTS: bool(true, 'Log HTTP requests'),
// Structured Logging
LOG_STRUCTURED: bool({ default: true, desc: 'Use structured logging format' }),
LOG_TIMESTAMP: bool({ default: true, desc: 'Include timestamps in logs' }),
LOG_CALLER_INFO: bool({ default: false, desc: 'Include caller information in logs' }),
// Log Filtering
LOG_SILENT_MODULES: str({ default: '', desc: 'Comma-separated list of modules to silence' }),
LOG_VERBOSE_MODULES: str({ default: '', desc: 'Comma-separated list of modules for verbose logging' }),
LOG_STRUCTURED: bool(true, 'Use structured logging format'),
LOG_TIMESTAMP: bool(true, 'Include timestamps in logs'),
LOG_CALLER_INFO: bool(false, 'Include caller information in logs'),
// Log Filtering
LOG_SILENT_MODULES: str('', 'Comma-separated list of modules to silence'),
LOG_VERBOSE_MODULES: str('', 'Comma-separated list of modules for verbose logging'),
// Application Context
LOG_SERVICE_NAME: str({ default: 'stock-bot', desc: 'Service name for log context' }),
LOG_SERVICE_VERSION: str({ default: '1.0.0', desc: 'Service version for log context' }),
LOG_ENVIRONMENT: str({ default: 'development', desc: 'Environment for log context' }),
LOG_SERVICE_NAME: str('stock-bot', 'Service name for log context'),
LOG_SERVICE_VERSION: str('1.0.0', 'Service version for log context'),
LOG_ENVIRONMENT: str('development', 'Environment for log context'),
});
// Export typed configuration object

View file

@ -1,40 +1,42 @@
/**
* Loki log aggregation configuration using envalid
* Loki log aggregation configuration using Zod
* Centralized logging configuration for the Stock Bot platform
*/
import { cleanEnv, str, port, bool, num } from 'envalid';
import { cleanEnv, envValidators } from './env-utils';
const { str, port, bool, num } = envValidators;
/**
* Loki configuration with validation and defaults
*/
export const lokiConfig = cleanEnv(process.env, {
// Loki Server
LOKI_HOST: str({ default: 'localhost', desc: 'Loki host' }),
LOKI_PORT: port({ default: 3100, desc: 'Loki port' }),
LOKI_URL: str({ default: '', desc: 'Complete Loki URL (overrides host/port)' }),
LOKI_HOST: str('localhost', 'Loki host'),
LOKI_PORT: port(3100, 'Loki port'),
LOKI_URL: str('', 'Complete Loki URL (overrides host/port)'),
// Authentication
LOKI_USERNAME: str({ default: '', desc: 'Loki username (if auth enabled)' }),
LOKI_PASSWORD: str({ default: '', desc: 'Loki password (if auth enabled)' }),
LOKI_TENANT_ID: str({ default: '', desc: 'Loki tenant ID (for multi-tenancy)' }),
LOKI_USERNAME: str('', 'Loki username (if auth enabled)'),
LOKI_PASSWORD: str('', 'Loki password (if auth enabled)'),
LOKI_TENANT_ID: str('', 'Loki tenant ID (for multi-tenancy)'),
// Push Configuration
LOKI_PUSH_TIMEOUT: num({ default: 10000, desc: 'Push timeout in ms' }),
LOKI_BATCH_SIZE: num({ default: 1024, desc: 'Batch size for log entries' }),
LOKI_BATCH_WAIT: num({ default: 5, desc: 'Batch wait time in ms' }),
LOKI_PUSH_TIMEOUT: num(10000, 'Push timeout in ms'),
LOKI_BATCH_SIZE: num(1024, 'Batch size for log entries'),
LOKI_BATCH_WAIT: num(5, 'Batch wait time in ms'),
// Retention Settings
LOKI_RETENTION_PERIOD: str({ default: '30d', desc: 'Log retention period' }),
LOKI_MAX_CHUNK_AGE: str({ default: '1h', desc: 'Maximum chunk age' }),
LOKI_RETENTION_PERIOD: str('30d', 'Log retention period'),
LOKI_MAX_CHUNK_AGE: str('1h', 'Maximum chunk age'),
// TLS Settings
LOKI_TLS_ENABLED: bool({ default: false, desc: 'Enable TLS for Loki' }),
LOKI_TLS_INSECURE: bool({ default: false, desc: 'Skip TLS verification' }),
LOKI_TLS_ENABLED: bool(false, 'Enable TLS for Loki'),
LOKI_TLS_INSECURE: bool(false, 'Skip TLS verification'),
// Log Labels
LOKI_DEFAULT_LABELS: str({ default: '', desc: 'Default labels for all log entries (JSON format)' }),
LOKI_SERVICE_LABEL: str({ default: 'stock-bot', desc: 'Service label for log entries' }),
LOKI_ENVIRONMENT_LABEL: str({ default: 'development', desc: 'Environment label for log entries' }),
LOKI_DEFAULT_LABELS: str('', 'Default labels for all log entries (JSON format)'),
LOKI_SERVICE_LABEL: str('stock-bot', 'Service label for log entries'),
LOKI_ENVIRONMENT_LABEL: str('development', 'Environment label for log entries'),
});
// Export typed configuration object

View file

@ -1,50 +1,48 @@
/**
* MongoDB configuration using envalid
* MongoDB configuration using Zod
* Document storage for sentiment data, raw documents, and unstructured data
*/
import { cleanEnv, str, port, bool, num } from 'envalid';
import { cleanEnv, envValidators } from './env-utils';
const { str, port, bool, num, strWithChoices } = envValidators;
/**
* MongoDB configuration with validation and defaults
*/
export const mongodbConfig = cleanEnv(process.env, {
// MongoDB Connection
MONGODB_HOST: str({ default: 'localhost', desc: 'MongoDB host' }),
MONGODB_PORT: port({ default: 27017, desc: 'MongoDB port' }),
MONGODB_DATABASE: str({ default: 'trading_documents', desc: 'MongoDB database name' }),
MONGODB_HOST: str('localhost', 'MongoDB host'),
MONGODB_PORT: port(27017, 'MongoDB port'),
MONGODB_DATABASE: str('trading_documents', 'MongoDB database name'),
// Authentication
MONGODB_USERNAME: str({ default: 'trading_admin', desc: 'MongoDB username' }),
MONGODB_PASSWORD: str({ default: '', desc: 'MongoDB password' }),
MONGODB_AUTH_SOURCE: str({ default: 'admin', desc: 'MongoDB authentication database' }),
MONGODB_USERNAME: str('trading_admin', 'MongoDB username'),
MONGODB_PASSWORD: str('', 'MongoDB password'),
MONGODB_AUTH_SOURCE: str('admin', 'MongoDB authentication database'),
// Connection URI (alternative to individual settings)
MONGODB_URI: str({ default: '', desc: 'Complete MongoDB connection URI (overrides individual settings)' }),
MONGODB_URI: str('', 'Complete MongoDB connection URI (overrides individual settings)'),
// Connection Pool Settings
MONGODB_MAX_POOL_SIZE: num({ default: 10, desc: 'Maximum connection pool size' }),
MONGODB_MIN_POOL_SIZE: num({ default: 0, desc: 'Minimum connection pool size' }),
MONGODB_MAX_IDLE_TIME: num({ default: 30000, desc: 'Maximum idle time for connections in ms' }),
MONGODB_MAX_POOL_SIZE: num(10, 'Maximum connection pool size'),
MONGODB_MIN_POOL_SIZE: num(0, 'Minimum connection pool size'),
MONGODB_MAX_IDLE_TIME: num(30000, 'Maximum idle time for connections in ms'),
// Timeouts
MONGODB_CONNECT_TIMEOUT: num({ default: 10000, desc: 'Connection timeout in ms' }),
MONGODB_SOCKET_TIMEOUT: num({ default: 30000, desc: 'Socket timeout in ms' }),
MONGODB_SERVER_SELECTION_TIMEOUT: num({ default: 5000, desc: 'Server selection timeout in ms' }),
MONGODB_CONNECT_TIMEOUT: num(10000, 'Connection timeout in ms'),
MONGODB_SOCKET_TIMEOUT: num(30000, 'Socket timeout in ms'),
MONGODB_SERVER_SELECTION_TIMEOUT: num(5000, 'Server selection timeout in ms'),
// SSL/TLS Settings
MONGODB_TLS: bool({ default: false, desc: 'Enable TLS for MongoDB connection' }),
MONGODB_TLS_INSECURE: bool({ default: false, desc: 'Allow invalid certificates in TLS mode' }),
MONGODB_TLS_CA_FILE: str({ default: '', desc: 'Path to TLS CA certificate file' }),
MONGODB_TLS: bool(false, 'Enable TLS for MongoDB connection'),
MONGODB_TLS_INSECURE: bool(false, 'Allow invalid certificates in TLS mode'),
MONGODB_TLS_CA_FILE: str('', 'Path to TLS CA certificate file'),
// Additional Settings
MONGODB_RETRY_WRITES: bool({ default: true, desc: 'Enable retryable writes' }),
MONGODB_JOURNAL: bool({ default: true, desc: 'Enable write concern journal' }),
MONGODB_READ_PREFERENCE: str({
default: 'primary',
choices: ['primary', 'primaryPreferred', 'secondary', 'secondaryPreferred', 'nearest'],
desc: 'MongoDB read preference'
}),
MONGODB_WRITE_CONCERN: str({ default: 'majority', desc: 'Write concern level' }),
MONGODB_RETRY_WRITES: bool(true, 'Enable retryable writes'),
MONGODB_JOURNAL: bool(true, 'Enable write concern journal'),
MONGODB_READ_PREFERENCE: strWithChoices(['primary', 'primaryPreferred', 'secondary', 'secondaryPreferred', 'nearest'], 'primary', 'MongoDB read preference'),
MONGODB_WRITE_CONCERN: str('majority', 'Write concern level'),
});
// Export typed configuration object

View file

@ -1,30 +1,32 @@
/**
* Monitoring configuration using envalid
* Monitoring configuration using Zod
* Prometheus metrics, Grafana visualization, and Loki logging
*/
import { cleanEnv, str, port, bool, num } from 'envalid';
import { cleanEnv, envValidators } from './env-utils';
const { str, port, bool, num, strWithChoices } = envValidators;
/**
* Prometheus configuration with validation and defaults
*/
export const prometheusConfig = cleanEnv(process.env, {
// Prometheus Server
PROMETHEUS_HOST: str({ default: 'localhost', desc: 'Prometheus host' }),
PROMETHEUS_PORT: port({ default: 9090, desc: 'Prometheus port' }),
PROMETHEUS_URL: str({ default: '', desc: 'Complete Prometheus URL (overrides host/port)' }),
PROMETHEUS_HOST: str('localhost', 'Prometheus host'),
PROMETHEUS_PORT: port(9090, 'Prometheus port'),
PROMETHEUS_URL: str('', 'Complete Prometheus URL (overrides host/port)'),
// Authentication
PROMETHEUS_USERNAME: str({ default: '', desc: 'Prometheus username (if auth enabled)' }),
PROMETHEUS_PASSWORD: str({ default: '', desc: 'Prometheus password (if auth enabled)' }),
PROMETHEUS_USERNAME: str('', 'Prometheus username (if auth enabled)'),
PROMETHEUS_PASSWORD: str('', 'Prometheus password (if auth enabled)'),
// Metrics Collection
PROMETHEUS_SCRAPE_INTERVAL: str({ default: '15s', desc: 'Default scrape interval' }),
PROMETHEUS_EVALUATION_INTERVAL: str({ default: '15s', desc: 'Rule evaluation interval' }),
PROMETHEUS_RETENTION_TIME: str({ default: '15d', desc: 'Data retention time' }),
PROMETHEUS_SCRAPE_INTERVAL: str('15s', 'Default scrape interval'),
PROMETHEUS_EVALUATION_INTERVAL: str('15s', 'Rule evaluation interval'),
PROMETHEUS_RETENTION_TIME: str('15d', 'Data retention time'),
// TLS Settings
PROMETHEUS_TLS_ENABLED: bool({ default: false, desc: 'Enable TLS for Prometheus' }),
PROMETHEUS_TLS_INSECURE: bool({ default: false, desc: 'Skip TLS verification' }),
PROMETHEUS_TLS_ENABLED: bool(false, 'Enable TLS for Prometheus'),
PROMETHEUS_TLS_INSECURE: bool(false, 'Skip TLS verification'),
});
/**
@ -32,29 +34,25 @@ export const prometheusConfig = cleanEnv(process.env, {
*/
export const grafanaConfig = cleanEnv(process.env, {
// Grafana Server
GRAFANA_HOST: str({ default: 'localhost', desc: 'Grafana host' }),
GRAFANA_PORT: port({ default: 3000, desc: 'Grafana port' }),
GRAFANA_URL: str({ default: '', desc: 'Complete Grafana URL (overrides host/port)' }),
GRAFANA_HOST: str('localhost', 'Grafana host'),
GRAFANA_PORT: port(3000, 'Grafana port'),
GRAFANA_URL: str('', 'Complete Grafana URL (overrides host/port)'),
// Authentication
GRAFANA_ADMIN_USER: str({ default: 'admin', desc: 'Grafana admin username' }),
GRAFANA_ADMIN_PASSWORD: str({ default: 'admin', desc: 'Grafana admin password' }),
GRAFANA_ADMIN_USER: str('admin', 'Grafana admin username'),
GRAFANA_ADMIN_PASSWORD: str('admin', 'Grafana admin password'),
// Security Settings
GRAFANA_ALLOW_SIGN_UP: bool({ default: false, desc: 'Allow user sign up' }),
GRAFANA_SECRET_KEY: str({ default: '', desc: 'Grafana secret key for encryption' }),
GRAFANA_ALLOW_SIGN_UP: bool(false, 'Allow user sign up'),
GRAFANA_SECRET_KEY: str('', 'Grafana secret key for encryption'),
// Database Settings
GRAFANA_DATABASE_TYPE: str({
default: 'sqlite3',
choices: ['mysql', 'postgres', 'sqlite3'],
desc: 'Grafana database type'
}),
GRAFANA_DATABASE_URL: str({ default: '', desc: 'Grafana database URL' }),
GRAFANA_DATABASE_TYPE: strWithChoices(['mysql', 'postgres', 'sqlite3'], 'sqlite3', 'Grafana database type'),
GRAFANA_DATABASE_URL: str('', 'Grafana database URL'),
// Feature Flags
GRAFANA_DISABLE_GRAVATAR: bool({ default: true, desc: 'Disable Gravatar avatars' }),
GRAFANA_ENABLE_GZIP: bool({ default: true, desc: 'Enable gzip compression' }),
GRAFANA_DISABLE_GRAVATAR: bool(true, 'Disable Gravatar avatars'),
GRAFANA_ENABLE_GZIP: bool(true, 'Enable gzip compression'),
});
// Export typed configuration objects

View file

@ -1,34 +1,36 @@
/**
* PostgreSQL configuration using envalid
* PostgreSQL configuration using Zod
*/
import { cleanEnv, str, port, bool, num } from 'envalid';
import { cleanEnv, envValidators } from './env-utils';
const { str, port, bool, num } = envValidators;
/**
* PostgreSQL configuration with validation and defaults
*/
export const postgresConfig = cleanEnv(process.env, {
// PostgreSQL Connection Settings
POSTGRES_HOST: str({ default: 'localhost', desc: 'PostgreSQL host' }),
POSTGRES_PORT: port({ default: 5432, desc: 'PostgreSQL port' }),
POSTGRES_DATABASE: str({ default: 'stockbot', desc: 'PostgreSQL database name' }),
POSTGRES_USERNAME: str({ default: 'stockbot', desc: 'PostgreSQL username' }),
POSTGRES_PASSWORD: str({ default: '', desc: 'PostgreSQL password' }),
POSTGRES_HOST: str('localhost', 'PostgreSQL host'),
POSTGRES_PORT: port(5432, 'PostgreSQL port'),
POSTGRES_DATABASE: str('stockbot', 'PostgreSQL database name'),
POSTGRES_USERNAME: str('stockbot', 'PostgreSQL username'),
POSTGRES_PASSWORD: str('', 'PostgreSQL password'),
// Connection Pool Settings
POSTGRES_POOL_MIN: num({ default: 2, desc: 'Minimum pool connections' }),
POSTGRES_POOL_MAX: num({ default: 10, desc: 'Maximum pool connections' }),
POSTGRES_POOL_IDLE_TIMEOUT: num({ default: 30000, desc: 'Pool idle timeout in ms' }),
POSTGRES_POOL_MIN: num(2, 'Minimum pool connections'),
POSTGRES_POOL_MAX: num(10, 'Maximum pool connections'),
POSTGRES_POOL_IDLE_TIMEOUT: num(30000, 'Pool idle timeout in ms'),
// SSL Configuration
POSTGRES_SSL: bool({ default: false, desc: 'Enable SSL for PostgreSQL connection' }),
POSTGRES_SSL_REJECT_UNAUTHORIZED: bool({ default: true, desc: 'Reject unauthorized SSL certificates' }),
POSTGRES_SSL: bool(false, 'Enable SSL for PostgreSQL connection'),
POSTGRES_SSL_REJECT_UNAUTHORIZED: bool(true, 'Reject unauthorized SSL certificates'),
// Additional Settings
POSTGRES_QUERY_TIMEOUT: num({ default: 30000, desc: 'Query timeout in ms' }),
POSTGRES_CONNECTION_TIMEOUT: num({ default: 5000, desc: 'Connection timeout in ms' }),
POSTGRES_STATEMENT_TIMEOUT: num({ default: 30000, desc: 'Statement timeout in ms' }),
POSTGRES_LOCK_TIMEOUT: num({ default: 10000, desc: 'Lock timeout in ms' }),
POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT: num({ default: 60000, desc: 'Idle in transaction timeout in ms' }),
POSTGRES_QUERY_TIMEOUT: num(30000, 'Query timeout in ms'),
POSTGRES_CONNECTION_TIMEOUT: num(5000, 'Connection timeout in ms'),
POSTGRES_STATEMENT_TIMEOUT: num(30000, 'Statement timeout in ms'),
POSTGRES_LOCK_TIMEOUT: num(10000, 'Lock timeout in ms'),
POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT: num(60000, 'Idle in transaction timeout in ms'),
});
// Export typed configuration object

View file

@ -1,35 +1,37 @@
/**
* QuestDB configuration using envalid
* QuestDB configuration using Zod
* Time-series database for OHLCV data, indicators, and performance metrics
*/
import { cleanEnv, str, port, bool, num } from 'envalid';
import { cleanEnv, envValidators } from './env-utils';
const { str, port, bool, num } = envValidators;
/**
* QuestDB configuration with validation and defaults
*/
export const questdbConfig = cleanEnv(process.env, {
// QuestDB Connection
QUESTDB_HOST: str({ default: 'localhost', desc: 'QuestDB host' }),
QUESTDB_HTTP_PORT: port({ default: 9000, desc: 'QuestDB HTTP port (web console)' }),
QUESTDB_PG_PORT: port({ default: 8812, desc: 'QuestDB PostgreSQL wire protocol port' }),
QUESTDB_INFLUX_PORT: port({ default: 9009, desc: 'QuestDB InfluxDB line protocol port' }),
QUESTDB_HOST: str('localhost', 'QuestDB host'),
QUESTDB_HTTP_PORT: port(9000, 'QuestDB HTTP port (web console)'),
QUESTDB_PG_PORT: port(8812, 'QuestDB PostgreSQL wire protocol port'),
QUESTDB_INFLUX_PORT: port(9009, 'QuestDB InfluxDB line protocol port'),
// Authentication (if enabled)
QUESTDB_USER: str({ default: '', desc: 'QuestDB username (if auth enabled)' }),
QUESTDB_PASSWORD: str({ default: '', desc: 'QuestDB password (if auth enabled)' }),
QUESTDB_USER: str('', 'QuestDB username (if auth enabled)'),
QUESTDB_PASSWORD: str('', 'QuestDB password (if auth enabled)'),
// Connection Settings
QUESTDB_CONNECTION_TIMEOUT: num({ default: 5000, desc: 'Connection timeout in ms' }),
QUESTDB_REQUEST_TIMEOUT: num({ default: 30000, desc: 'Request timeout in ms' }),
QUESTDB_RETRY_ATTEMPTS: num({ default: 3, desc: 'Number of retry attempts' }),
QUESTDB_CONNECTION_TIMEOUT: num(5000, 'Connection timeout in ms'),
QUESTDB_REQUEST_TIMEOUT: num(30000, 'Request timeout in ms'),
QUESTDB_RETRY_ATTEMPTS: num(3, 'Number of retry attempts'),
// TLS Settings
QUESTDB_TLS_ENABLED: bool({ default: false, desc: 'Enable TLS for QuestDB connection' }),
QUESTDB_TLS_VERIFY_SERVER_CERT: bool({ default: true, desc: 'Verify server certificate' }),
QUESTDB_TLS_ENABLED: bool(false, 'Enable TLS for QuestDB connection'),
QUESTDB_TLS_VERIFY_SERVER_CERT: bool(true, 'Verify server certificate'),
// Database Settings
QUESTDB_DEFAULT_DATABASE: str({ default: 'qdb', desc: 'Default database name' }),
QUESTDB_TELEMETRY_ENABLED: bool({ default: false, desc: 'Enable telemetry' }),
QUESTDB_DEFAULT_DATABASE: str('qdb', 'Default database name'),
QUESTDB_TELEMETRY_ENABLED: bool(false, 'Enable telemetry'),
});
// Export typed configuration object

View file

@ -1,54 +1,52 @@
/**
* Risk management configuration using envalid
* Risk management configuration using Zod
*/
import { cleanEnv, str, num, bool } from 'envalid';
import { cleanEnv, envValidators } from './env-utils';
const { str, num, bool, strWithChoices } = envValidators;
/**
* Risk configuration with validation and defaults
*/
export const riskConfig = cleanEnv(process.env, {
// Position Sizing
RISK_MAX_POSITION_SIZE: num({ default: 0.1, desc: 'Maximum position size as percentage of portfolio' }),
RISK_MAX_PORTFOLIO_EXPOSURE: num({ default: 0.8, desc: 'Maximum portfolio exposure percentage' }),
RISK_MAX_SINGLE_ASSET_EXPOSURE: num({ default: 0.2, desc: 'Maximum exposure to single asset' }),
RISK_MAX_SECTOR_EXPOSURE: num({ default: 0.3, desc: 'Maximum exposure to single sector' }),
RISK_MAX_POSITION_SIZE: num(0.1, 'Maximum position size as percentage of portfolio'),
RISK_MAX_PORTFOLIO_EXPOSURE: num(0.8, 'Maximum portfolio exposure percentage'),
RISK_MAX_SINGLE_ASSET_EXPOSURE: num(0.2, 'Maximum exposure to single asset'),
RISK_MAX_SECTOR_EXPOSURE: num(0.3, 'Maximum exposure to single sector'),
// Stop Loss and Take Profit
RISK_DEFAULT_STOP_LOSS: num({ default: 0.05, desc: 'Default stop loss percentage' }),
RISK_DEFAULT_TAKE_PROFIT: num({ default: 0.15, desc: 'Default take profit percentage' }),
RISK_TRAILING_STOP_ENABLED: bool({ default: true, desc: 'Enable trailing stop losses' }),
RISK_TRAILING_STOP_DISTANCE: num({ default: 0.03, desc: 'Trailing stop distance percentage' }),
RISK_DEFAULT_STOP_LOSS: num(0.05, 'Default stop loss percentage'),
RISK_DEFAULT_TAKE_PROFIT: num(0.15, 'Default take profit percentage'),
RISK_TRAILING_STOP_ENABLED: bool(true, 'Enable trailing stop losses'),
RISK_TRAILING_STOP_DISTANCE: num(0.03, 'Trailing stop distance percentage'),
// Risk Limits
RISK_MAX_DAILY_LOSS: num({ default: 0.05, desc: 'Maximum daily loss percentage' }),
RISK_MAX_WEEKLY_LOSS: num({ default: 0.1, desc: 'Maximum weekly loss percentage' }),
RISK_MAX_MONTHLY_LOSS: num({ default: 0.2, desc: 'Maximum monthly loss percentage' }),
RISK_MAX_DAILY_LOSS: num(0.05, 'Maximum daily loss percentage'),
RISK_MAX_WEEKLY_LOSS: num(0.1, 'Maximum weekly loss percentage'),
RISK_MAX_MONTHLY_LOSS: num(0.2, 'Maximum monthly loss percentage'),
// Volatility Controls
RISK_MAX_VOLATILITY_THRESHOLD: num({ default: 0.4, desc: 'Maximum volatility threshold' }),
RISK_VOLATILITY_LOOKBACK_DAYS: num({ default: 20, desc: 'Volatility calculation lookback period' }),
RISK_MAX_VOLATILITY_THRESHOLD: num(0.4, 'Maximum volatility threshold'),
RISK_VOLATILITY_LOOKBACK_DAYS: num(20, 'Volatility calculation lookback period'),
// Correlation Controls
RISK_MAX_CORRELATION_THRESHOLD: num({ default: 0.7, desc: 'Maximum correlation between positions' }),
RISK_CORRELATION_LOOKBACK_DAYS: num({ default: 60, desc: 'Correlation calculation lookback period' }),
RISK_MAX_CORRELATION_THRESHOLD: num(0.7, 'Maximum correlation between positions'),
RISK_CORRELATION_LOOKBACK_DAYS: num(60, 'Correlation calculation lookback period'),
// Leverage Controls
RISK_MAX_LEVERAGE: num({ default: 2.0, desc: 'Maximum leverage allowed' }),
RISK_MARGIN_CALL_THRESHOLD: num({ default: 0.3, desc: 'Margin call threshold' }),
RISK_MAX_LEVERAGE: num(2.0, 'Maximum leverage allowed'),
RISK_MARGIN_CALL_THRESHOLD: num(0.3, 'Margin call threshold'),
// Circuit Breakers
RISK_CIRCUIT_BREAKER_ENABLED: bool({ default: true, desc: 'Enable circuit breakers' }),
RISK_CIRCUIT_BREAKER_LOSS_THRESHOLD: num({ default: 0.1, desc: 'Circuit breaker loss threshold' }),
RISK_CIRCUIT_BREAKER_COOLDOWN_MINUTES: num({ default: 60, desc: 'Circuit breaker cooldown period' }),
RISK_CIRCUIT_BREAKER_ENABLED: bool(true, 'Enable circuit breakers'),
RISK_CIRCUIT_BREAKER_LOSS_THRESHOLD: num(0.1, 'Circuit breaker loss threshold'),
RISK_CIRCUIT_BREAKER_COOLDOWN_MINUTES: num(60, 'Circuit breaker cooldown period'),
// Risk Model
RISK_MODEL_TYPE: str({
choices: ['var', 'cvar', 'expected_shortfall'],
default: 'var',
desc: 'Risk model type'
}),
RISK_CONFIDENCE_LEVEL: num({ default: 0.95, desc: 'Risk model confidence level' }),
RISK_TIME_HORIZON_DAYS: num({ default: 1, desc: 'Risk time horizon in days' }),
RISK_MODEL_TYPE: strWithChoices(['var', 'cvar', 'expected_shortfall'], 'var', 'Risk model type'),
RISK_CONFIDENCE_LEVEL: num(0.95, 'Risk model confidence level'),
RISK_TIME_HORIZON_DAYS: num(1, 'Risk time horizon in days'),
});
// Export typed configuration object