.NET WinForms-Anwendung (Core, Modules/CongressTrading, UI). Enthaelt .gitignore und settings.example.json als Konfigurationsvorlage. Echte settings.json mit Zugangsdaten ist bewusst ausgeschlossen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
86 lines
3.9 KiB
C#
86 lines
3.9 KiB
C#
using IBKRTrader.Core.Logging;
|
|
|
|
namespace IBKRTrader.Core.Database.Migrations;
|
|
|
|
/// <summary>
|
|
/// Erstellt die core_ibkr_xxx-Tabellen idempotent (IF NOT EXISTS).
|
|
/// Wird beim App-Start nach CoreMigrations ausgeführt.
|
|
/// </summary>
|
|
public class IBKRMigrations
|
|
{
|
|
private readonly DatabaseService _db;
|
|
private readonly LoggingService _logger;
|
|
|
|
public IBKRMigrations(DatabaseService db, LoggingService logger)
|
|
{
|
|
_db = db;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task RunAsync()
|
|
{
|
|
_logger.Info("Core", "Starte IBKR-Datenbankmigrationen...");
|
|
await CreateInstrumentsTableAsync();
|
|
await CreateMarketDataTableAsync();
|
|
await CreateExternalIdentifiersTableAsync();
|
|
_logger.Info("Core", "IBKR-Migrationen abgeschlossen.");
|
|
}
|
|
|
|
// ─── Tabellen ─────────────────────────────────────────────────────────────
|
|
|
|
private Task CreateInstrumentsTableAsync() => _db.ExecuteAsync(@"
|
|
CREATE TABLE IF NOT EXISTS `core_ibkr_instruments` (
|
|
`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
`ibkr_conid` BIGINT NOT NULL UNIQUE,
|
|
`symbol` VARCHAR(20) NOT NULL,
|
|
`sec_type` VARCHAR(10) NOT NULL DEFAULT 'STK',
|
|
`exchange` VARCHAR(20) NOT NULL DEFAULT 'SMART',
|
|
`primary_exchange` VARCHAR(20),
|
|
`currency` VARCHAR(5) NOT NULL DEFAULT 'USD',
|
|
`company_name` TEXT,
|
|
`isin` VARCHAR(12),
|
|
`sector` VARCHAR(100),
|
|
`industry` VARCHAR(100),
|
|
`description` TEXT,
|
|
`active` TINYINT(1) NOT NULL DEFAULT 1,
|
|
`last_fetched` DATETIME,
|
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
ON UPDATE CURRENT_TIMESTAMP,
|
|
INDEX `idx_symbol` (`symbol`),
|
|
INDEX `idx_conid` (`ibkr_conid`),
|
|
INDEX `idx_active` (`active`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
|
|
|
private Task CreateMarketDataTableAsync() => _db.ExecuteAsync(@"
|
|
CREATE TABLE IF NOT EXISTS `core_ibkr_market_data` (
|
|
`instrument_id` BIGINT NOT NULL,
|
|
`bar_size` VARCHAR(10) NOT NULL DEFAULT 'daily',
|
|
`timestamp` DATETIME NOT NULL,
|
|
`open` DECIMAL(12,6),
|
|
`high` DECIMAL(12,6),
|
|
`low` DECIMAL(12,6),
|
|
`close` DECIMAL(12,6),
|
|
`volume` BIGINT,
|
|
`wap` DECIMAL(12,6),
|
|
`bar_count` INT,
|
|
PRIMARY KEY (`instrument_id`, `bar_size`, `timestamp`),
|
|
INDEX `idx_timestamp` (`timestamp`),
|
|
CONSTRAINT `fk_md_instrument` FOREIGN KEY (`instrument_id`)
|
|
REFERENCES `core_ibkr_instruments` (`id`) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
|
|
|
private Task CreateExternalIdentifiersTableAsync() => _db.ExecuteAsync(@"
|
|
CREATE TABLE IF NOT EXISTS `core_ibkr_external_identifiers` (
|
|
`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
`instrument_id` BIGINT NOT NULL,
|
|
`source` VARCHAR(50) NOT NULL,
|
|
`ticker` VARCHAR(50) NOT NULL,
|
|
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE KEY `uq_mapping` (`instrument_id`, `source`, `ticker`),
|
|
INDEX `idx_source_ticker` (`source`, `ticker`),
|
|
CONSTRAINT `fk_ext_instrument` FOREIGN KEY (`instrument_id`)
|
|
REFERENCES `core_ibkr_instruments` (`id`) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
|
}
|