initial setup

This commit is contained in:
Bojan Kucera 2025-06-02 08:15:20 -04:00
commit 232a63dfe8
61 changed files with 4985 additions and 0 deletions

View file

@ -0,0 +1,21 @@
{
"name": "@stock-bot/config",
"version": "1.0.0",
"description": "Shared configuration for the trading bot",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"dev": "tsc --watch",
"clean": "rm -rf dist",
"test": "echo \"No tests yet\""
},
"dependencies": {
"@stock-bot/shared-types": "workspace:*",
"dotenv": "^16.4.5"
},
"devDependencies": {
"typescript": "^5.4.5",
"@types/node": "^20.12.12"
}
}

View file

@ -0,0 +1,156 @@
import { config } from 'dotenv';
import type { DatabaseConfig, BrokerConfig, DataProviderConfig } from '@stock-bot/shared-types';
// Load environment variables
config();
export const env = {
NODE_ENV: process.env.NODE_ENV || 'development',
PORT: parseInt(process.env.PORT || '3000'),
// Database URLs
QUESTDB_URL: process.env.QUESTDB_URL || 'postgresql://admin:quest@localhost:8812/qdb',
POSTGRES_URL: process.env.POSTGRES_URL || 'postgresql://postgres:password@localhost:5432/stockbot',
DRAGONFLY_URL: process.env.DRAGONFLY_URL || 'redis://localhost:6379',
// API Keys
ALPHA_VANTAGE_API_KEY: process.env.ALPHA_VANTAGE_API_KEY || '',
ALPACA_API_KEY: process.env.ALPACA_API_KEY || '',
ALPACA_SECRET_KEY: process.env.ALPACA_SECRET_KEY || '',
// Trading Configuration
PAPER_TRADING: process.env.PAPER_TRADING === 'true',
MAX_POSITION_SIZE: parseFloat(process.env.MAX_POSITION_SIZE || '0.1'),
MAX_DAILY_LOSS: parseFloat(process.env.MAX_DAILY_LOSS || '1000'),
// Logging
LOG_LEVEL: process.env.LOG_LEVEL || 'info',
// Feature Flags
ENABLE_ML_SIGNALS: process.env.ENABLE_ML_SIGNALS === 'true',
ENABLE_SENTIMENT_ANALYSIS: process.env.ENABLE_SENTIMENT_ANALYSIS === 'true',
} as const;
export const databaseConfig: DatabaseConfig = {
questdb: {
host: process.env.QUESTDB_HOST || 'localhost',
port: parseInt(process.env.QUESTDB_PORT || '9000'),
database: process.env.QUESTDB_DATABASE || 'qdb',
},
postgres: {
host: process.env.POSTGRES_HOST || 'localhost',
port: parseInt(process.env.POSTGRES_PORT || '5432'),
database: process.env.POSTGRES_DATABASE || 'stockbot',
username: process.env.POSTGRES_USERNAME || 'postgres',
password: process.env.POSTGRES_PASSWORD || 'password',
}, dragonfly: {
host: process.env.DRAGONFLY_HOST || 'localhost',
port: parseInt(process.env.DRAGONFLY_PORT || '6379'),
password: process.env.DRAGONFLY_PASSWORD,
},
};
export const brokerConfigs: Record<string, BrokerConfig> = {
alpaca: {
name: 'Alpaca',
apiKey: env.ALPACA_API_KEY,
secretKey: env.ALPACA_SECRET_KEY,
baseUrl: env.PAPER_TRADING
? 'https://paper-api.alpaca.markets'
: 'https://api.alpaca.markets',
sandbox: env.PAPER_TRADING,
},
};
export const dataProviderConfigs: Record<string, DataProviderConfig> = {
alphaVantage: {
name: 'Alpha Vantage',
apiKey: env.ALPHA_VANTAGE_API_KEY,
baseUrl: 'https://www.alphavantage.co',
rateLimits: {
requestsPerSecond: 5,
requestsPerDay: 500,
},
},
};
export const serviceDefaults = {
healthCheckInterval: 30000, // 30 seconds
retryAttempts: 3,
requestTimeout: 10000, // 10 seconds
circuitBreakerThreshold: 5,
circuitBreakerTimeout: 60000, // 1 minute
};
export const tradingHours = {
market: {
open: '09:30',
close: '16:00',
timezone: 'America/New_York',
},
premarket: {
open: '04:00',
close: '09:30',
timezone: 'America/New_York',
},
afterHours: {
open: '16:00',
close: '20:00',
timezone: 'America/New_York',
},
};
export const riskDefaults = {
maxPositionSize: 0.1, // 10% of portfolio
maxDailyLoss: 0.02, // 2% of portfolio
maxDrawdown: 0.1, // 10% of portfolio
stopLossPercent: 0.05, // 5%
takeProfitPercent: 0.15, // 15%
};
// Environment-specific configurations
export const getConfig = () => {
const base = {
env: env.NODE_ENV,
port: env.PORT,
database: databaseConfig,
brokers: brokerConfigs,
dataProviders: dataProviderConfigs,
services: serviceDefaults,
trading: {
hours: tradingHours,
risk: riskDefaults,
paperTrading: env.PAPER_TRADING,
},
};
switch (env.NODE_ENV) {
case 'development':
return {
...base,
logging: {
level: 'debug',
console: true,
file: false,
},
cache: {
ttl: 300, // 5 minutes
},
};
case 'production':
return {
...base,
logging: {
level: 'info',
console: false,
file: true,
},
cache: {
ttl: 60, // 1 minute
},
};
default:
return base;
}
};

View file

@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"declaration": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}