• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

moconnell / yolo / 19116466348

05 Nov 2025 09:12PM UTC coverage: 35.004% (-23.2%) from 58.251%
19116466348

push

github

web-flow
Merge pull request #37 from moconnell/36-feat-support-pure-unravel-factor-trading

Feat: support pure Unravel trading

107 of 364 branches covered (29.4%)

Branch coverage included in aggregate %.

30 of 368 new or added lines in 9 files covered. (8.15%)

1 existing line in 1 file now uncovered.

284 of 753 relevant lines covered (37.72%)

15.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/YoloAbstractions/Extensions/VectorExtensions.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using MathNet.Numerics.LinearAlgebra;
5

6
namespace YoloAbstractions.Extensions;
7

8
public static class VectorExtensions
9
{
10
    /// <summary>
11
    /// Cross-sectional transform of a single row vector (already-normalized signal):
12
    /// - Rank into q-tiles [0..q-1]
13
    /// - Map to [-1,+1] via 2*(bin/maxBin)-1
14
    /// - L1-normalize so sum|w|=1
15
    /// - If marketNeutral=false, rectifies negatives to 0 then renormalizes to sum=1 (long-only)
16
    /// Returns NaN for assets with NaN input.
17
    /// </summary>
18
    /// <param name="vector">Vector of daily factor values</param>
19
    /// <param name="qTiles">Number of bins</param>
20
    /// <param name="marketNeutral">If true, output should roughly sum to zero</param>
21
    public static Vector<double> QTiledRowToWeights(this Vector<double> vector, int qTiles, bool marketNeutral = true)
NEW
22
    {
×
NEW
23
        var n = vector.Count;
×
NEW
24
        var outVec = Vector<double>.Build.Dense(n, double.NaN);
×
25

26
        // collect valid indices
NEW
27
        var items = new List<(double v, int j)>(n);
×
NEW
28
        for (var j = 0; j < n; j++)
×
NEW
29
        {
×
NEW
30
            var v = vector[j];
×
NEW
31
            if (!double.IsNaN(v))
×
NEW
32
                items.Add((v, j));
×
NEW
33
        }
×
34

NEW
35
        if (items.Count == 0)
×
NEW
36
            return outVec;
×
37

NEW
38
        items.Sort((a, b) => a.v.CompareTo(b.v)); // ascending
×
39

40
        // assign q-tiles [0..qTiles-1]
NEW
41
        var m = items.Count;
×
NEW
42
        var bins = new int[m];
×
NEW
43
        for (var k = 0; k < m; k++)
×
NEW
44
        {
×
NEW
45
            var b = (int) Math.Floor((k + 1) / (double) m * qTiles) - 1;
×
NEW
46
            if (b < 0)
×
NEW
47
                b = 0;
×
NEW
48
            if (b > qTiles - 1)
×
NEW
49
                b = qTiles - 1;
×
NEW
50
            bins[k] = b;
×
NEW
51
        }
×
52

NEW
53
        var maxBin = bins.Max();
×
NEW
54
        if (maxBin <= 0)
×
NEW
55
            return outVec; // all equal → no signal
×
56

57
        // map to [-1,+1]
NEW
58
        var w = new double[m];
×
NEW
59
        for (var k = 0; k < m; k++)
×
NEW
60
            w[k] = 2.0 * (bins[k] / (double) maxBin) - 1.0;
×
61

NEW
62
        if (!marketNeutral)
×
NEW
63
        {
×
64
            // long-only: rectify, then L1 normalize to sum = 1
NEW
65
            for (var k = 0; k < m; k++)
×
NEW
66
                w[k] = Math.Max(0.0, w[k]);
×
NEW
67
            var sum = w.Sum();
×
NEW
68
            if (sum > 0)
×
NEW
69
                for (var k = 0; k < m; k++)
×
NEW
70
                    w[k] /= sum;
×
71
            // write back
NEW
72
            for (var k = 0; k < m; k++)
×
NEW
73
                outVec[items[k].j] = w[k];
×
NEW
74
            return outVec;
×
75
        }
76

77
        // market-neutral: L1 normalize so sum|w| = 1
NEW
78
        var denom = w.Sum(Math.Abs);
×
NEW
79
        if (denom > 0)
×
NEW
80
            for (var k = 0; k < m; k++)
×
NEW
81
                w[k] /= denom;
×
82

NEW
83
        for (var k = 0; k < m; k++)
×
NEW
84
            outVec[items[k].j] = w[k];
×
85

NEW
86
        return outVec;
×
NEW
87
    }
×
88
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc