redesign fully scaffolded and web login works

This commit is contained in:
2026-03-17 20:10:47 -04:00
parent b9cc397e05
commit f6bd22a8ef
143 changed files with 17317 additions and 693 deletions

View File

@@ -0,0 +1,227 @@
# Trading Strategy Best Practices
## Code Organization
### Separation of Concerns
```typescript
// Good: Clear separation
class Strategy {
async analyze(data: MarketData): Promise<Signal> { }
}
class RiskManager {
validateSignal(signal: Signal): boolean { }
}
class ExecutionEngine {
async execute(signal: Signal): Promise<Order> { }
}
// Bad: Everything in one function
async function trade() {
// Analysis, risk, execution all mixed
}
```
### Configuration Management
```typescript
// Good: External configuration
interface StrategyConfig {
stopLossPercent: number;
takeProfitPercent: number;
maxPositionSize: number;
riskPerTrade: number;
}
const config = loadConfig('strategy.yaml');
// Bad: Hardcoded values scattered throughout
const stopLoss = price * 0.95; // What if you want to change this?
```
## Testing Considerations
### Testable Code
```typescript
// Good: Pure functions, easy to test
function calculateRSI(prices: number[], period: number = 14): number {
// Pure calculation, no side effects
return rsi;
}
// Bad: Hard to test
async function strategy() {
const data = await fetchLiveData(); // Can't control in tests
const signal = analyze(data);
await executeTrade(signal); // Side effects
}
```
### Mock-Friendly Design
```typescript
// Good: Dependency injection
class Strategy {
constructor(
private dataProvider: DataProvider,
private executor: OrderExecutor
) {}
async run() {
const data = await this.dataProvider.getData();
// ...
}
}
// In tests: inject mocks
const strategy = new Strategy(mockDataProvider, mockExecutor);
```
## Performance Optimization
### Avoid Recalculation
```typescript
// Good: Cache indicator results
class IndicatorCache {
private cache = new Map<string, { value: number, timestamp: number }>();
get(key: string, ttl: number, calculator: () => number): number {
const cached = this.cache.get(key);
if (cached && Date.now() - cached.timestamp < ttl) {
return cached.value;
}
const value = calculator();
this.cache.set(key, { value, timestamp: Date.now() });
return value;
}
}
// Bad: Recalculate every time
for (const ticker of tickers) {
const rsi = calculateRSI(await getData(ticker)); // Slow
}
```
### Batch Operations
```typescript
// Good: Batch API calls
const results = await Promise.all(
tickers.map(ticker => dataProvider.getOHLC(ticker))
);
// Bad: Sequential API calls
const results = [];
for (const ticker of tickers) {
results.push(await dataProvider.getOHLC(ticker)); // Slow
}
```
## Error Handling
### Graceful Degradation
```typescript
// Good: Fallback behavior
async function getMarketData(ticker: string): Promise<OHLC[]> {
try {
return await primarySource.fetch(ticker);
} catch (error) {
logger.warn('Primary source failed, trying backup');
try {
return await backupSource.fetch(ticker);
} catch (backupError) {
logger.error('All sources failed');
return getCachedData(ticker); // Last resort
}
}
}
// Bad: Let it crash
async function getMarketData(ticker: string) {
return await api.fetch(ticker); // Uncaught errors
}
```
### Detailed Logging
```typescript
// Good: Structured logging with context
logger.info({
action: 'order_placed',
ticker: 'BTC/USDT',
side: 'buy',
size: 0.1,
price: 50000,
orderId: 'abc123',
strategy: 'mean-reversion'
});
// Bad: String concatenation
console.log('Placed order'); // No context
```
## Documentation
### Self-Documenting Code
```typescript
// Good: Clear naming and JSDoc
/**
* Calculate position size using Kelly Criterion
* @param winRate Probability of winning (0-1)
* @param avgWin Average win amount
* @param avgLoss Average loss amount
* @param capital Total available capital
* @returns Optimal position size in base currency
*/
function calculateKellyPosition(
winRate: number,
avgWin: number,
avgLoss: number,
capital: number
): number {
const kellyPercent = (winRate * avgWin - (1 - winRate) * avgLoss) / avgWin;
return Math.max(0, Math.min(kellyPercent * capital, capital * 0.25)); // Cap at 25%
}
// Bad: Cryptic names
function calc(w: number, a: number, b: number, c: number) {
return (w * a - (1 - w) * b) / a * c;
}
```
## Security
### Input Validation
```typescript
// Good: Validate all external inputs
function validateTicker(ticker: string): boolean {
return /^[A-Z]+:[A-Z]+\/[A-Z]+$/.test(ticker);
}
function validatePeriod(period: string): boolean {
return ['1m', '5m', '15m', '1h', '4h', '1d', '1w'].includes(period);
}
// Bad: Trust user input
function getOHLC(ticker: string, period: string) {
return db.query(`SELECT * FROM ohlc WHERE ticker='${ticker}'`); // SQL injection!
}
```
### Rate Limiting
```typescript
// Good: Prevent API abuse
class RateLimiter {
private calls: number[] = [];
async throttle(maxCallsPerMinute: number): Promise<void> {
const now = Date.now();
this.calls = this.calls.filter(t => now - t < 60000);
if (this.calls.length >= maxCallsPerMinute) {
const wait = 60000 - (now - this.calls[0]);
await sleep(wait);
}
this.calls.push(now);
}
}
```