tenth version
Deploy / Test, build and deploy (push) Successful in 1m46s

This commit is contained in:
2026-06-08 14:58:56 +00:00
parent 20cc8506ad
commit 7626c1b831
17 changed files with 917 additions and 27 deletions
+4 -4
View File
@@ -250,11 +250,12 @@ func (e Engine) RunWithMinuteCandles(candlesByInstrument map[string][]domain.Can
for _, c := range dayCandidates {
entryIntervalVolume, exitIntervalVolume := e.windowVolumes(c, preparedMinutes[c.instrumentUID])
capacity := decimal.Zero
if entryIntervalVolume.IsPositive() && exitIntervalVolume.IsPositive() {
switch {
case entryIntervalVolume.IsPositive() && exitIntervalVolume.IsPositive():
capacity = money.Min(entryIntervalVolume, exitIntervalVolume).Mul(e.cfg.MaxParticipationRate)
} else if e.cfg.UseMinuteModel {
case e.cfg.UseMinuteModel:
continue
} else {
default:
entryIntervalVolume = e.unconstrainedIntervalVolume(equity)
exitIntervalVolume = entryIntervalVolume
}
@@ -469,7 +470,6 @@ func (e Engine) evaluateCandidate(instrumentUID string, candles []domain.Candle,
rawEdge := decimal.NewFromFloat(short.Mean).Mul(decimal.NewFromInt(10_000))
spreadBps := e.assumedSpreadBps(instrumentUID)
cost := spreadBps.
Add(spreadBps).
Add(e.cfg.EntrySlippageBps).
Add(e.cfg.ExitSlippageBps).
Add(e.cfg.CommissionRoundtripBps).
+28
View File
@@ -107,6 +107,34 @@ func TestEvaluateCandidateUsesInstrumentLotAndTick(t *testing.T) {
}
}
func TestEvaluateCandidateChargesOneFullSpreadRoundTrip(t *testing.T) {
requireZero := false
engine := New(Config{
RollingShort: 2,
RollingLong: 2,
MinTStat60: decimal.NewFromInt(-1),
MinWinRate60: decimal.NewFromFloat(0.1),
MinNetEdgeBps: decimal.NewFromInt(-1000),
MinADVRUB: decimal.NewFromInt(1),
AssumedSpreadBps: decimal.NewFromInt(10),
EntrySlippageBps: decimal.NewFromInt(2),
ExitSlippageBps: decimal.NewFromInt(3),
CommissionRoundtripBps: decimal.NewFromInt(4),
RiskBufferBps: decimal.NewFromInt(5),
RequireZeroCommission: &requireZero,
})
got, ok, err := engine.evaluateCandidate("uid", candidateCandles("uid"), 4)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatal("expected candidate")
}
if !got.netEdge.Equal(decimal.NewFromInt(126)) {
t.Fatalf("net edge=%s, want raw 150 - cost 24", got.netEdge)
}
}
func TestWindowCapacityUsesMinuteEntryAndExitWindows(t *testing.T) {
engine := New(Config{
Lot: 10,