Packages

Elixir client library for cryptocurrency exchanges — generated from CCXT specs via compile-time macros.

Current section

Files

Jump to
ccxt_client lib mix tasks ccxt.classify_signing.ex
Raw

lib/mix/tasks/ccxt.classify_signing.ex

defmodule Mix.Tasks.Ccxt.ClassifySigning do
@shortdoc "Report signing pattern classification for all exchanges"
@moduledoc """
Reports signing pattern classification for all exchanges.
Loads every compiled exchange spec (priority tiers by default — Tier 1 +
Tier 2 + DEX), classifies each into one of 9 signing patterns, and prints
a summary grouped by pattern.
## Usage
mix ccxt.classify_signing
"""
use Mix.Task
alias CCXT.Signing.Classifier
@impl true
def run(_args) do
exchanges = CCXT.Spec.exchanges()
results =
Enum.map(exchanges, fn exchange_id ->
spec = CCXT.Spec.load!(exchange_id)
{pattern, config} = Classifier.classify(spec)
{exchange_id, pattern, config}
end)
by_pattern = Enum.group_by(results, fn {_, pattern, _} -> pattern end)
print_summary(by_pattern, length(exchanges))
print_details(by_pattern)
print_custom_review(results)
end
defp print_summary(by_pattern, total) do
IO.puts("\n=== Signing Pattern Classification ===\n")
by_pattern
|> Enum.sort_by(fn {_pattern, exchanges} -> -length(exchanges) end)
|> Enum.each(fn {pattern, exchanges} ->
IO.puts(" #{format_pattern(pattern)} #{length(exchanges)} exchanges")
end)
IO.puts("\n Total: #{total} exchanges\n")
end
defp print_details(by_pattern) do
IO.puts("=== Details by Pattern ===\n")
by_pattern
|> Enum.sort_by(fn {pattern, _} -> Atom.to_string(pattern) end)
|> Enum.each(fn {pattern, exchanges} ->
ids = exchanges |> Enum.map(fn {id, _, _} -> id end) |> Enum.sort()
IO.puts(" #{format_pattern(pattern)}")
IO.puts(" #{Enum.join(ids, ", ")}\n")
end)
end
defp print_custom_review(results) do
custom =
Enum.filter(results, fn {_, pattern, _} -> pattern == :custom end)
if custom == [], do: :ok, else: do_print_custom(custom)
end
defp do_print_custom(custom) do
IO.puts("=== Custom Exchanges (manual review needed) ===\n")
Enum.each(custom, &print_custom_exchange/1)
IO.puts("")
end
defp print_custom_exchange({exchange_id, _, _}) do
parent = Classifier.parent_for(exchange_id)
suffix = if parent, do: " (inherits from #{parent})", else: ""
IO.puts(" #{exchange_id}#{suffix}")
end
@pattern_width 40
defp format_pattern(pattern) do
String.pad_trailing(inspect(pattern), @pattern_width)
end
end