Fix min-day target for 0% consistency accounts + daysTraded consistency
trading-logic: when baseAmount=0 (consistency=0%), target cappedByFuture directly instead of collapsing to minDayPnL. For a $4000 target with $150 min-day and 5 days, day 1 now correctly targets $3400 ($4000 - 4×$150) then $150 for each remaining mandatory day. tradovate-class: make fetchDaysTraded() public so auto-trade can call it immediately after a trade exits. Fix daysTraded to count only positive-P&L days from the FIFO results, consistent with computeDailyTarget's positiveDays.length — previously counted all raw fill dates. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
5cba4ef175
commit
68075059d0
@@ -79,7 +79,11 @@ export function computeDailyTarget(
|
|||||||
// Floor: must make at least minDayPnL today (or whatever is left if less)
|
// Floor: must make at least minDayPnL today (or whatever is left if less)
|
||||||
const floor = Math.min(effectiveMinDay, remaining);
|
const floor = Math.min(effectiveMinDay, remaining);
|
||||||
|
|
||||||
const amount = Math.max(floor, Math.min(baseAmount, cappedByFuture));
|
// When consistency = 0% (baseAmount = 0), there's no consistency-based upper bound —
|
||||||
|
// target cappedByFuture directly (make as much as possible today, reserve future days).
|
||||||
|
// When consistency > 0%, treat baseAmount as the consistency cap.
|
||||||
|
const consistencyCapped = baseAmount > 0 ? Math.min(baseAmount, cappedByFuture) : cappedByFuture;
|
||||||
|
const amount = Math.max(floor, consistencyCapped);
|
||||||
return { amount: Math.round(amount * 100) / 100, path };
|
return { amount: Math.round(amount * 100) / 100, path };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ export class TradovateClient {
|
|||||||
this.ws.send('user/syncrequest\n3\n\n{"splitResponses":false}');
|
this.ws.send('user/syncrequest\n3\n\n{"splitResponses":false}');
|
||||||
}
|
}
|
||||||
|
|
||||||
private async fetchDaysTraded(): Promise<void> {
|
public async fetchDaysTraded(): Promise<void> {
|
||||||
if (!this.accessInfo?.accessToken) return;
|
if (!this.accessInfo?.accessToken) return;
|
||||||
this.fetchDaysComplete = false;
|
this.fetchDaysComplete = false;
|
||||||
|
|
||||||
@@ -378,8 +378,6 @@ export class TradovateClient {
|
|||||||
commission: number;
|
commission: number;
|
||||||
};
|
};
|
||||||
const fills: Fill[] = JSON.parse(raw);
|
const fills: Fill[] = JSON.parse(raw);
|
||||||
const uniqueDays = new Set(fills.map(f => f._tradeDate));
|
|
||||||
this.daysTraded[account.id] = uniqueDays.size;
|
|
||||||
|
|
||||||
// POINT_VALUES imported from trading-logic.ts
|
// POINT_VALUES imported from trading-logic.ts
|
||||||
|
|
||||||
@@ -428,9 +426,13 @@ export class TradovateClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dailyPnL[account.id] = Object.entries(dailyMap)
|
const entries = Object.entries(dailyMap)
|
||||||
.map(([date, pnl]) => ({ date, pnl: Math.round(pnl * 100) / 100 }))
|
.map(([date, pnl]) => ({ date, pnl: Math.round(pnl * 100) / 100 }))
|
||||||
.sort((a, b) => a.date.localeCompare(b.date));
|
.sort((a, b) => a.date.localeCompare(b.date));
|
||||||
|
|
||||||
|
this.dailyPnL[account.id] = entries;
|
||||||
|
// Count only positive-P&L days — consistent with computeDailyTarget's positiveDays
|
||||||
|
this.daysTraded[account.id] = entries.filter(d => d.pnl > 0).length;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const msg = err instanceof Error ? `${err.message}` : String(err);
|
const msg = err instanceof Error ? `${err.message}` : String(err);
|
||||||
console.error(`[fetchDaysTraded] ${account.name}:`, msg);
|
console.error(`[fetchDaysTraded] ${account.name}:`, msg);
|
||||||
|
|||||||
Reference in New Issue
Block a user