ninth version
Deploy / Test, build and deploy (push) Failing after 1m6s

This commit is contained in:
2026-06-08 14:25:44 +00:00
parent e8b7d8e27c
commit 20cc8506ad
21 changed files with 847 additions and 148 deletions
+91 -1
View File
@@ -71,12 +71,102 @@ func ComposeDaily(input DailyInput) string {
averageSpread = averageContextDecimal(input.Signals, "spread_bps")
}
fmt.Fprintf(&b, "Средний spread: %s bps\n", averageSpread.StringFixed(2))
fmt.Fprintf(&b, "Среднее проскальзывание: %s bps\n", input.AverageSlipBps.StringFixed(2))
averageSlip := input.AverageSlipBps
if averageSlip.IsZero() {
averageSlip = AverageAdverseSlippageBps(input.Orders, 0)
}
fmt.Fprintf(&b, "Среднее проскальзывание: %s bps\n", averageSlip.StringFixed(2))
writeExecutionErrors(&b, input.Orders)
fmt.Fprintf(&b, "Risk: %s", input.RiskStatus)
return b.String()
}
func AverageAdverseSlippageBps(orders []domain.Order, limit int) decimal.Decimal {
if len(orders) == 0 {
return decimal.Zero
}
sorted := append([]domain.Order(nil), orders...)
sort.Slice(sorted, func(i, j int) bool {
return sorted[i].UpdatedAt.After(sorted[j].UpdatedAt)
})
sum := decimal.Zero
weight := decimal.Zero
count := 0
for _, order := range sorted {
slippage, ok := orderAdverseSlippageBps(order)
if !ok {
continue
}
lots := decimal.NewFromInt(order.FilledLots)
sum = sum.Add(slippage.Mul(lots))
weight = weight.Add(lots)
count++
if limit > 0 && count == limit {
break
}
}
if weight.IsZero() {
return decimal.Zero
}
return sum.Div(weight)
}
func orderAdverseSlippageBps(order domain.Order) (decimal.Decimal, bool) {
if order.FilledLots <= 0 || !order.AvgFillPrice.IsPositive() {
return decimal.Zero, false
}
reference := orderReferencePrice(order)
if !reference.IsPositive() {
return decimal.Zero, false
}
var adverse decimal.Decimal
switch order.Side {
case domain.SideBuy:
adverse = order.AvgFillPrice.Sub(reference)
case domain.SideSell:
adverse = reference.Sub(order.AvgFillPrice)
default:
return decimal.Zero, false
}
if adverse.IsNegative() {
adverse = decimal.Zero
}
return adverse.Div(reference).Mul(decimal.NewFromInt(10_000)), true
}
func orderReferencePrice(order domain.Order) decimal.Decimal {
if mid := rawMidPrice(order.RawStateJSON); mid.IsPositive() {
return mid
}
return order.LimitPrice
}
func rawMidPrice(raw string) decimal.Decimal {
var root map[string]any
if err := json.Unmarshal([]byte(raw), &root); err != nil {
return decimal.Zero
}
if mid := midFromContainer(root); mid.IsPositive() {
return mid
}
if local, ok := root["local"].(map[string]any); ok {
return midFromContainer(local)
}
return decimal.Zero
}
func midFromContainer(container map[string]any) decimal.Decimal {
quote, ok := container["local_quote"].(map[string]any)
if !ok {
return decimal.Zero
}
mid, ok := decimalFromAny(quote["mid"])
if !ok {
return decimal.Zero
}
return mid
}
func groupedReasons(signals []domain.Signal) map[string]int {
out := make(map[string]int)
for _, sig := range signals {