ƒxyzƒxyz Network
Algorithms

Community Detection

Louvain modularity optimization for FX currency clusters and network member communities

Community Detection

Community detection identifies groups of nodes that are more densely connected to each other than to the rest of the network. In fXYZ Network, this algorithm operates on two distinct graphs: the FX exchange graph (currency clusters) and the member social graph (circles and working groups).

Implementation: packages/neo4j/src/services/graph-analysis.ts GraphQL query: communities Paper references: A7, C5


Louvain Algorithm

Overview

The Louvain algorithm (Blondel et al. 2008) is a greedy modularity optimization method that scales to large networks. It finds communities by maximizing the modularity score Q — a measure of how much more densely connected the within-community edges are compared to what would be expected in a random graph with the same degree sequence.

Modularity

The modularity Q for a partition of a graph into communities C is:

Q = (1 / 2m) * sum_{ij} [ A_ij - (k_i * k_j) / (2m) ] * delta(c_i, c_j)

Where:
  A_ij  = 1 if edge (i,j) exists, 0 otherwise (or weight if weighted)
  k_i   = degree of node i (sum of edge weights for weighted graphs)
  m     = total number of edges (or total edge weight)
  c_i   = community assignment of node i
  delta(c_i, c_j) = 1 if c_i == c_j, else 0

Q ranges from -1 to 1. A value above 0.3 is generally considered meaningful community structure. Values above 0.7 indicate strong communities.

Algorithm: Two Phases Per Iteration

Phase 1 — Local moves:

For each node v (in random order):
  Compute delta_Q for moving v into each neighbor's community
  Move v to the community giving the largest delta_Q > 0
  If no positive delta_Q: v stays in its own community
Repeat until no node moves

Phase 2 — Graph compression:

Build a new "super-graph" where:
  Each community becomes a single super-node
  Edges between communities become weighted edges between super-nodes
  Self-loops accumulate within-community edge weight

Repeat Phase 1 on the compressed graph. Continue until modularity stops improving.

Resolution Parameter

The standard Louvain algorithm has a resolution limit: it cannot detect communities smaller than a scale that depends on the network size. The resolution parameter gamma modifies the null model:

Q(gamma) = (1 / 2m) * sum_{ij} [ A_ij - gamma * (k_i * k_j) / (2m) ] * delta(c_i, c_j)
  • gamma = 1.0: standard Louvain (default)
  • gamma > 1.0: detects smaller, more numerous communities
  • gamma < 1.0: produces larger, fewer communities

For FX currency networks with ~30 nodes, gamma = 1.0 is appropriate. For the full member graph, higher gamma values reveal more granular working-group structure.

Implementation

// graph-analysis.ts:392
louvainCommunities(
  graph: Map<string, Map<string, number>>,
  resolution?: number
): Community[]

interface Community {
  id: string;
  nodes: string[];
  modularity: number;
  color?: string;  // OKLCH color from cartography palette
}

// GraphQL:
query GetCommunities {
  communities {
    id
    nodes
    modularity
  }
}

Status: WIRED — louvainCommunities() is implemented and exposed via communities GraphQL query. Target UI: /cartography community overlay. Current status: no UI consumer.


FX Currency Communities

When applied to the FX correlation network (using correlation distance as edge weight), Louvain reveals currency clusters that move together:

Typical FX Community Structure

CommunityTypical MembersEconomic Driver
Dollar blocUSD, CAD, MXN, AUDUS trade linkages, commodity pricing
Euro blocEUR, CHF, DKK, SEK, NOKEuropean economic integration
Safe havensJPY, CHF, USDRisk-off flows, reserve status
Commodity currenciesAUD, CAD, NZD, NOKOil, gas, minerals correlation
EM AsiaCNY, HKD, SGD, KRWRegional trade, China linkage

The detected communities shift during crises — safe-haven clustering tightens and commodity currencies diverge. Tracking community structure over time reveals regime changes in FX market microstructure.

Connection to MST

The Louvain communities should be interpreted alongside the MST (see Correlation Algorithms):

  • MST shows the hierarchical backbone
  • Louvain shows which subtrees of the MST form coherent groups
  • Communities that span MST subtrees indicate strong cross-regional linkages

Member Network Communities

The same algorithm applies to the fXYZ member social graph:

  • Nodes: Members
  • Edges: Vouches, circle memberships, collaboration links
  • Communities: Organically formed working groups that may or may not correspond to formal circle boundaries

This reveals "shadow circles" — groups of members who collaborate intensively but have no formal organizational structure — which is useful for governance design.


Cartography Visualization

The Louvain community assignments feed directly into the /cartography page color coding. Each community gets a distinct OKLCH color from the platform's scientific display palette, chosen to maximize perceptual distance between adjacent communities while maintaining accessibility contrast.

// OKLCH palette for communities (from design-system)
const communityColors = [
  "oklch(70% 0.15 30)",   // warm amber
  "oklch(70% 0.15 150)",  // teal
  "oklch(70% 0.15 270)",  // blue-violet
  "oklch(70% 0.15 210)",  // sky
  "oklch(70% 0.15 90)",   // yellow-green
];

Planned Extensions

FX Dynamic Communities (Paper C5)

Track community membership over rolling time windows to detect regime changes. When a currency switches communities, it signals a shift in its correlation structure — potential leading indicator for volatility.

Spectral Clustering (Paper A1)

Alternative to Louvain that uses the eigenvectors of the Laplacian for partitioning. Implemented as getSpectralClusters() in graph-analysis.ts:956 but not yet exposed via GraphQL.


Paper References

PaperTitleRelevance
A7Network Community DetectionLouvain algorithm foundations
C5FX Dynamic CommunitiesRolling-window FX clustering
A1Spectral Graph TheorySpectral clustering alternative