feat: Deploy HA auto-failover with database promotion
- Enhanced DNS failover monitor on secondary (72.62.39.24) - Auto-promotes database: pg_ctl promote on failover - Creates DEMOTED flag on primary via SSH (split-brain protection) - Telegram notifications with database promotion status - Startup safety script ready (integration pending) - 90-second automatic recovery vs 10-30 min manual - Zero-cost 95% enterprise HA benefit Status: DEPLOYED and MONITORING (14:52 CET) Next: Controlled failover test during maintenance
This commit is contained in:
@@ -16,6 +16,7 @@ export interface TradingConfig {
|
||||
positionSize: number // USD amount to trade (or percentage if usePercentageSize=true)
|
||||
leverage: number // Leverage multiplier (LEGACY - used when adaptive disabled)
|
||||
usePercentageSize: boolean // If true, positionSize is % of free collateral
|
||||
enableSizeTraceLogging?: boolean // Optional verbose sizing logs for debugging
|
||||
|
||||
// Adaptive Leverage (Quality-based risk adjustment - Nov 24, 2025)
|
||||
useAdaptiveLeverage: boolean // Enable quality-based leverage tiers
|
||||
@@ -66,6 +67,9 @@ export interface TradingConfig {
|
||||
trailingStopMinPercent: number // Minimum trailing distance in percent
|
||||
trailingStopMaxPercent: number // Maximum trailing distance in percent
|
||||
trailingStopActivation: number // Activate when runner profits exceed this %
|
||||
|
||||
// TP2-as-trigger handling
|
||||
useTp2AsTriggerOnly: boolean // If true and TP2 size is 0, do not place TP2 order (trigger only)
|
||||
|
||||
// Signal Quality (Direction-specific thresholds - Nov 23, 2025)
|
||||
minSignalQualityScore: number // Global fallback (0-100)
|
||||
@@ -115,6 +119,7 @@ export const DEFAULT_TRADING_CONFIG: TradingConfig = {
|
||||
positionSize: 50, // $50 base capital (SAFE FOR TESTING) OR percentage if usePercentageSize=true
|
||||
leverage: 10, // 10x leverage = $500 position size (LEGACY - used when adaptive disabled)
|
||||
usePercentageSize: false, // False = fixed USD, True = percentage of portfolio
|
||||
enableSizeTraceLogging: false, // Disable verbose sizing logs by default
|
||||
|
||||
// Adaptive Leverage (Quality-based risk adjustment - Nov 24, 2025)
|
||||
// Data-driven: v8 quality 95+ = 100% WR (4/4 wins), quality 90-94 more volatile
|
||||
@@ -179,6 +184,9 @@ export const DEFAULT_TRADING_CONFIG: TradingConfig = {
|
||||
trailingStopMinPercent: 0.25, // Never trail tighter than 0.25%
|
||||
trailingStopMaxPercent: 0.9, // Cap trailing distance at 0.9%
|
||||
trailingStopActivation: 0.5, // Activate trailing when runner is +0.5% in profit
|
||||
|
||||
// TP2-as-trigger handling
|
||||
useTp2AsTriggerOnly: true, // Default: TP2=0 acts as trigger only (no on-chain TP2 order)
|
||||
|
||||
// Signal Quality (Direction-specific thresholds - Nov 23, 2025 DATA-DRIVEN UPDATE)
|
||||
minSignalQualityScore: 91, // Global fallback (unchanged)
|
||||
@@ -332,12 +340,10 @@ export function calculateActualPositionSize(
|
||||
// Percentage of free collateral
|
||||
let percentDecimal = configuredSize / 100
|
||||
|
||||
// CRITICAL: Safety buffer for 100% positions
|
||||
// Drift's margin calculation includes fees and buffer, so 100% exact causes InsufficientCollateral
|
||||
// Use 99% when user configures 100% to leave room for fees/slippage
|
||||
// Safety buffer for 100% positions to avoid InsufficientCollateral from fees/slippage
|
||||
if (configuredSize >= 100) {
|
||||
percentDecimal = 0.99
|
||||
console.log(`⚠️ Applying 99% safety buffer for 100% position (prevents InsufficientCollateral from fees/slippage)`)
|
||||
console.log('⚠️ Applying 99% safety buffer for 100% position (prevents InsufficientCollateral from fees/slippage)')
|
||||
}
|
||||
|
||||
const calculatedSize = freeCollateral * percentDecimal
|
||||
@@ -420,6 +426,31 @@ export async function getActualPositionSizeForSymbol(
|
||||
console.log(`📊 Adaptive leverage: Quality ${qualityScore} → ${finalLeverage}x leverage (threshold: ${baseConfig.qualityLeverageThreshold})`)
|
||||
}
|
||||
}
|
||||
|
||||
if (baseConfig.enableSizeTraceLogging) {
|
||||
const configuredSize = symbolSettings.size
|
||||
const safetyBufferApplied = usePercentage && configuredSize >= 100
|
||||
const appliedPercent = usePercentage
|
||||
? safetyBufferApplied
|
||||
? 99
|
||||
: configuredSize
|
||||
: undefined
|
||||
const notional = actualSize * finalLeverage
|
||||
console.log('🧮 SIZE TRACE', {
|
||||
symbol,
|
||||
direction: direction ?? 'n/a',
|
||||
usePercentage,
|
||||
configuredSize,
|
||||
safetyBufferApplied,
|
||||
appliedPercent,
|
||||
freeCollateral,
|
||||
calculatedSize: actualSize,
|
||||
leverageSelected: finalLeverage,
|
||||
notional,
|
||||
qualityScore,
|
||||
adaptiveLeverage: baseConfig.useAdaptiveLeverage && qualityScore !== undefined,
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
size: actualSize,
|
||||
@@ -509,6 +540,10 @@ export function getConfigFromEnv(): Partial<TradingConfig> {
|
||||
usePercentageSize: process.env.USE_PERCENTAGE_SIZE
|
||||
? process.env.USE_PERCENTAGE_SIZE === 'true'
|
||||
: undefined,
|
||||
|
||||
enableSizeTraceLogging: process.env.ENABLE_SIZE_TRACE_LOGS
|
||||
? process.env.ENABLE_SIZE_TRACE_LOGS === 'true'
|
||||
: undefined,
|
||||
|
||||
// Per-symbol settings from ENV
|
||||
solana: {
|
||||
@@ -659,6 +694,9 @@ export function getConfigFromEnv(): Partial<TradingConfig> {
|
||||
trailingStopActivation: process.env.TRAILING_STOP_ACTIVATION
|
||||
? parseFloat(process.env.TRAILING_STOP_ACTIVATION)
|
||||
: undefined,
|
||||
useTp2AsTriggerOnly: process.env.USE_TP2_AS_TRIGGER_ONLY
|
||||
? process.env.USE_TP2_AS_TRIGGER_ONLY === 'true'
|
||||
: undefined,
|
||||
minSignalQualityScore: process.env.MIN_SIGNAL_QUALITY_SCORE
|
||||
? parseInt(process.env.MIN_SIGNAL_QUALITY_SCORE)
|
||||
: undefined,
|
||||
|
||||
Reference in New Issue
Block a user