Randomize daily targets: split big days into legs, bump min-days
Big days (> $1700) now trade as multiple separate legs of random size (each >= $800, $5-rounded), resumable across pauses since the remaining target is derived from realized PnL against a day-anchored target. Min-day targets get a deterministic random $0-25 bump seeded per (account, trade date) so the dashboard, reporter, and orders agree. Strict-consistency accounts randomize only their first trade ever. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
8350601cf0
commit
de9cbffd83
+14
-7
@@ -3,12 +3,13 @@ import { loadDailyPnL } from '@/lib/db';
|
||||
import { getClients } from '@/lib/clients';
|
||||
import { getCachedCatalog } from '@/lib/firm-catalog';
|
||||
import { getAccountConfig, getInferredSize, matchAccountType } from '@/lib/account-type-resolver';
|
||||
import { computeDailyTarget, resolveEffectiveConfig } from '@/lib/trading-logic';
|
||||
import { computeDayPlan, resolveEffectiveConfig, currentTradeDateCT, LEG_COMPLETION_EPSILON } from '@/lib/trading-logic';
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const firms = getCachedCatalog();
|
||||
const clients = getClients();
|
||||
const tradeDate = currentTradeDateCT();
|
||||
|
||||
const state = firms.map((f) => {
|
||||
const client = clients.get(f.id);
|
||||
@@ -53,6 +54,7 @@ export async function GET() {
|
||||
: false;
|
||||
let targetHit = false;
|
||||
let dailyTarget: { amount: number; path: 'first_day' | 'normal_day' | 'reduced_day' } | null = null;
|
||||
let remainingToday: number | null = null;
|
||||
let effectiveProfitTarget: number | null = null;
|
||||
if (cfg && !isDead) {
|
||||
const effective = resolveEffectiveConfig(
|
||||
@@ -65,8 +67,12 @@ export async function GET() {
|
||||
allFundTxns
|
||||
);
|
||||
const equityProfit = cash.amount - cfg.accountSize;
|
||||
const target = computeDailyTarget(effective.profitTarget, effective.consistency, dailyPnL, cfg.minDayPnL, effective.minTradingDays, equityProfit);
|
||||
dailyTarget = target;
|
||||
const plan = computeDayPlan(
|
||||
acc.id, tradeDate, effective.profitTarget, effective.consistency,
|
||||
dailyPnL, cfg.minDayPnL, effective.minTradingDays, equityProfit, cash.realizedPnL
|
||||
);
|
||||
dailyTarget = plan ? { amount: plan.dayTarget, path: plan.path } : null;
|
||||
remainingToday = plan?.remainingToday ?? null;
|
||||
|
||||
// Effective profit target = max(stage target, consistency realTarget).
|
||||
// If a big day forces the consistency rule, the account must reach maxDay/consistency
|
||||
@@ -77,11 +83,11 @@ export async function GET() {
|
||||
? maxDay / effective.consistency : 0;
|
||||
effectiveProfitTarget = Math.max(effective.profitTarget, consistencyReal);
|
||||
// Condition 1: profit target already exceeded (target=0), still need days → any activity counts
|
||||
// Condition 2: target > 0 → must have made at least the computed daily target
|
||||
if (target) {
|
||||
// Condition 2: target > 0 → all legs done (day's remaining target used up)
|
||||
if (plan) {
|
||||
targetHit =
|
||||
(target.amount === 0 && Math.abs(cash.realizedPnL) > 0 && client.daysTraded[acc.id] <= effective.minTradingDays) ||
|
||||
(cash.realizedPnL >= target.amount);
|
||||
(plan.dayTarget === 0 && Math.abs(cash.realizedPnL) > 0 && client.daysTraded[acc.id] <= effective.minTradingDays) ||
|
||||
(cash.realizedPnL > 0 && plan.remainingToday <= LEG_COMPLETION_EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +106,7 @@ export async function GET() {
|
||||
targetHit,
|
||||
stage,
|
||||
dailyTarget,
|
||||
remainingToday,
|
||||
effectiveProfitTarget,
|
||||
dailyPnL,
|
||||
fullDailyPnL: client.fullDailyPnL?.[acc.id] ?? loadDailyPnL(acc.id),
|
||||
|
||||
Reference in New Issue
Block a user