| Line 656... |
Line 656... |
| 656 |
scheduledTasks.resetHardLimit();
|
656 |
scheduledTasks.resetHardLimit();
|
| 657 |
}
|
657 |
}
|
| 658 |
|
658 |
|
| 659 |
/**
|
659 |
/**
|
| 660 |
* Investment snapshot for every active partner, then the credit limit for the partners whose
|
660 |
* Investment snapshot for every active partner, then the credit limit for the partners whose
|
| 661 |
* base moved. Replaces the old 20-minute full rescan: the limit now follows a payment within
|
661 |
* base moved. This is the path that keeps limits current: it replaces the 20-minute full rescan,
|
| 662 |
* ~2 minutes instead of up to 20, which matters because a quarter of advance payments are
|
662 |
* so a limit follows a payment within ~2 minutes instead of up to 20 — which matters because a
|
| 663 |
* followed by an order within five minutes.
|
663 |
* quarter of advance payments are followed by an order within five minutes.
|
| - |
|
664 |
*
|
| - |
|
665 |
* <p>Measured on production: ~3 partners per 2-minute window show a changed base (peak 18), so
|
| - |
|
666 |
* the limit work behind this is a handful of rows rather than a 980-partner scan.
|
| 664 |
*/
|
667 |
*/
|
| 665 |
@Scheduled(cron = "0 0/2 * * * *")
|
668 |
@Scheduled(cron = "0 0/2 * * * *")
|
| 666 |
public void sweepPartnerInvestment() throws Throwable {
|
669 |
public void sweepPartnerInvestment() throws Throwable {
|
| 667 |
batchScheduledTasks.sweepPartnerInvestment();
|
670 |
batchScheduledTasks.sweepPartnerInvestment();
|
| 668 |
}
|
671 |
}
|
| 669 |
|
672 |
|
| 670 |
/**
|
673 |
/**
|
| - |
|
674 |
* Daily: refresh the time-driven haircuts, then run a full limit pass.
|
| - |
|
675 |
*
|
| 671 |
* Full safety-net pass: recomputes every partner's limit regardless of whether the sweep saw the
|
676 |
* <p>The 2-minute sweep already recalculates the limit for every partner whose base moved, which
|
| - |
|
677 |
* covers investment and utilisation. The full pass exists only for inputs the base cannot see —
|
| - |
|
678 |
* credit risk, the SIDBI floor and hard_limit — and those move on a far slower clock: risk
|
| 672 |
* base move. Covers anything the sweep could not observe — a changed listing price that moves
|
679 |
* decays on a 90-day threshold, and the SIDBI sanction table has had no new row since Oct 2024
|
| - |
|
680 |
* and no recorded settlement. Running a 980-partner rescan every 20 minutes to catch that was 72
|
| - |
|
681 |
* wasted passes a day.
|
| - |
|
682 |
*
|
| - |
|
683 |
* <p>Order matters: the haircut refresh changes base for the partners whose Apple or demo stock
|
| 673 |
* stock value for every holder, or a snapshot write that was lost.
|
684 |
* crossed its threshold overnight, so the limit pass runs after it and sees the new values.
|
| 674 |
*/
|
685 |
*/
|
| 675 |
@Scheduled(cron = "0 0/20 * * * *")
|
- |
|
| 676 |
public void updatePartnerLimit() throws Throwable {
|
- |
|
| 677 |
batchScheduledTasks.updatePartnerLimitWithBatch();
|
- |
|
| 678 |
}
|
- |
|
| 679 |
|
- |
|
| 680 |
/** Aged-Apple and live-demo haircuts move with the clock, so they are refreshed once a day. */
|
- |
|
| 681 |
@Scheduled(cron = "0 20 0 * * *")
|
686 |
@Scheduled(cron = "0 20 0 * * *")
|
| 682 |
public void refreshAgedStockDaily() throws Throwable {
|
687 |
public void refreshAgedStockDaily() throws Throwable {
|
| 683 |
batchScheduledTasks.refreshAgedStockDaily();
|
688 |
batchScheduledTasks.refreshAgedStockDaily();
|
| - |
|
689 |
batchScheduledTasks.updatePartnerLimitWithBatch();
|
| 684 |
}
|
690 |
}
|
| 685 |
|
691 |
|
| 686 |
@Scheduled(cron = "0 0 9,14,18 * * *")
|
692 |
@Scheduled(cron = "0 0 9,14,18 * * *")
|
| 687 |
public void createOpeningStockPartyWise() throws Throwable {
|
693 |
public void createOpeningStockPartyWise() throws Throwable {
|
| 688 |
scheduledTasks.createOpeningStockPartyWise();
|
694 |
scheduledTasks.createOpeningStockPartyWise();
|