feat: GridBot als zweite Paper-Engine — No-Stop-XRP-Grid live
processGridCycle (Paritätstest gegen runGridBacktest), GridEngine mit DB-Recovery (grid_state/grid_lots, bot_state id=2), bot-Spalte in paper_trades/equity_snapshots, /api/grid, Dashboard-Panel. Bewusster Paper-Probelauf trotz Gate-Fail (User-Entscheidung 2026-06-10). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@ export const positions = pgTable('positions', {
|
||||
|
||||
export const paperTrades = pgTable('paper_trades', {
|
||||
id: serial('id').primaryKey(),
|
||||
bot: text('bot').notNull().default('trend'), // 'trend' | 'grid'
|
||||
pair: varchar('pair', { length: 16 }).notNull(),
|
||||
side: text('side').notNull(),
|
||||
entryTs: timestamp('entry_ts', { withTimezone: true }).notNull(),
|
||||
@@ -69,10 +70,38 @@ export const botState = pgTable('bot_state', {
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
});
|
||||
|
||||
export const equitySnapshots = pgTable('equity_snapshots', {
|
||||
ts: timestamp('ts', { withTimezone: true }).primaryKey(), // 4h-Bucket
|
||||
equity: doublePrecision('equity').notNull(),
|
||||
cash: doublePrecision('cash').notNull(),
|
||||
export const equitySnapshots = pgTable(
|
||||
'equity_snapshots',
|
||||
{
|
||||
bot: text('bot').notNull().default('trend'),
|
||||
ts: timestamp('ts', { withTimezone: true }).notNull(), // 4h-Bucket
|
||||
equity: doublePrecision('equity').notNull(),
|
||||
cash: doublePrecision('cash').notNull(),
|
||||
},
|
||||
(t) => [primaryKey({ columns: [t.bot, t.ts] })],
|
||||
);
|
||||
|
||||
/** Aktives Grid je Pair (No-Stop-GridBot). */
|
||||
export const gridState = pgTable('grid_state', {
|
||||
pair: varchar('pair', { length: 16 }).primaryKey(),
|
||||
center: doublePrecision('center').notNull(),
|
||||
spacing: doublePrecision('spacing').notNull(),
|
||||
lowerBound: doublePrecision('lower_bound').notNull(),
|
||||
upperBound: doublePrecision('upper_bound').notNull(),
|
||||
budgetPerLevel: doublePrecision('budget_per_level').notNull(),
|
||||
activatedTs: timestamp('activated_ts', { withTimezone: true }).notNull(),
|
||||
});
|
||||
|
||||
/** Offene Grid-Lots (Inventar). */
|
||||
export const gridLots = pgTable('grid_lots', {
|
||||
id: serial('id').primaryKey(),
|
||||
pair: varchar('pair', { length: 16 }).notNull(),
|
||||
levelIdx: integer('level_idx').notNull(),
|
||||
qty: doublePrecision('qty').notNull(),
|
||||
entryTs: timestamp('entry_ts', { withTimezone: true }).notNull(),
|
||||
entryPrice: doublePrecision('entry_price').notNull(),
|
||||
entryCost: doublePrecision('entry_cost').notNull(),
|
||||
riskAmount: doublePrecision('risk_amount').notNull(),
|
||||
});
|
||||
|
||||
export const backtestRuns = pgTable('backtest_runs', {
|
||||
|
||||
Reference in New Issue
Block a user