mirror of
https://github.com/luxfi/broker.git
synced 2026-09-24 00:25:18 +00:00
feat(types): asset_class constants for ch_*, ae_*, eu_* (MiCA taxonomy)
Extends AssetClass vocabulary with 17 new constants: - CH: ch_equity, ch_dlt_security, ch_crypto, ch_fi (FINMA) - AE: ae_equity, ae_crypto, ae_fi, ae_tokenized_security, ae_funds (SCA/DFSA/VARA/FSRA) - EU: eu_equity, eu_mifid_fi, eu_ucits, eu_aif, eu_art, eu_emt, eu_cas, eu_dlt_security (MiCA) AllAssetClasses() and ValidAssetClass() updated, existing tests pass.
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
// Canonical asset class vocabulary. Every routing rule, provider config,
|
||||
// jurisdiction record, and regulated entity references these constants.
|
||||
// There is exactly one way to name an asset class.
|
||||
package types
|
||||
|
||||
// AssetClass is a typed string for compile-time safety.
|
||||
type AssetClass string
|
||||
|
||||
const (
|
||||
// US asset classes
|
||||
AssetClassUSEquity AssetClass = "us_equity"
|
||||
AssetClassUSCrypto AssetClass = "us_crypto"
|
||||
AssetClassUSOptions AssetClass = "us_options"
|
||||
AssetClassUSFixedIncome AssetClass = "us_fixed_income"
|
||||
|
||||
// UK asset classes (FCA)
|
||||
AssetClassUKEquity AssetClass = "uk_equity"
|
||||
AssetClassUKCrypto AssetClass = "uk_crypto"
|
||||
AssetClassUKCFDs AssetClass = "uk_cfds"
|
||||
AssetClassUKFI AssetClass = "uk_fi"
|
||||
|
||||
// India asset classes (SEBI)
|
||||
AssetClassINEquity AssetClass = "in_equity"
|
||||
AssetClassINCommodity AssetClass = "in_commodity"
|
||||
AssetClassINFnO AssetClass = "in_fno"
|
||||
|
||||
// Singapore asset classes (MAS)
|
||||
AssetClassSGEquity AssetClass = "sg_equity"
|
||||
AssetClassSGCrypto AssetClass = "sg_crypto"
|
||||
AssetClassSGREITs AssetClass = "sg_reits"
|
||||
|
||||
// Australia asset classes (ASIC)
|
||||
AssetClassAUEquity AssetClass = "au_equity"
|
||||
AssetClassAUETF AssetClass = "au_etf"
|
||||
AssetClassAUCrypto AssetClass = "au_crypto"
|
||||
|
||||
// Canada asset classes (CIRO)
|
||||
AssetClassCAEquity AssetClass = "ca_equity"
|
||||
AssetClassCAETF AssetClass = "ca_etf"
|
||||
AssetClassCACrypto AssetClass = "ca_crypto"
|
||||
|
||||
// Brazil asset classes (CVM)
|
||||
AssetClassBREquity AssetClass = "br_equity"
|
||||
AssetClassBROptions AssetClass = "br_options"
|
||||
AssetClassBRFIIs AssetClass = "br_fiis"
|
||||
AssetClassBRCrypto AssetClass = "br_crypto"
|
||||
|
||||
// Switzerland asset classes (FINMA)
|
||||
AssetClassCHEquity AssetClass = "ch_equity"
|
||||
AssetClassCHDLTSecurity AssetClass = "ch_dlt_security"
|
||||
AssetClassCHCrypto AssetClass = "ch_crypto"
|
||||
AssetClassCHFI AssetClass = "ch_fi"
|
||||
|
||||
// UAE asset classes (SCA/DFSA/VARA/FSRA)
|
||||
AssetClassAEEquity AssetClass = "ae_equity"
|
||||
AssetClassAECrypto AssetClass = "ae_crypto"
|
||||
AssetClassAEFI AssetClass = "ae_fi"
|
||||
AssetClassAETokenizedSecurity AssetClass = "ae_tokenized_security"
|
||||
AssetClassAEFunds AssetClass = "ae_funds"
|
||||
|
||||
// EU asset classes (MiCA-harmonized)
|
||||
AssetClassEUEquity AssetClass = "eu_equity"
|
||||
AssetClassEUMiFIDFI AssetClass = "eu_mifid_fi"
|
||||
AssetClassEUUCITS AssetClass = "eu_ucits"
|
||||
AssetClassEUAIF AssetClass = "eu_aif"
|
||||
AssetClassEUART AssetClass = "eu_art"
|
||||
AssetClassEUEMT AssetClass = "eu_emt"
|
||||
AssetClassEUCAS AssetClass = "eu_cas"
|
||||
AssetClassEUDLTSecurity AssetClass = "eu_dlt_security"
|
||||
|
||||
// Wildcard — matches any asset class in routing rules
|
||||
AssetClassWildcard AssetClass = "*"
|
||||
)
|
||||
|
||||
// AllAssetClasses returns every defined asset class (excluding wildcard).
|
||||
func AllAssetClasses() []AssetClass {
|
||||
return []AssetClass{
|
||||
AssetClassUSEquity, AssetClassUSCrypto, AssetClassUSOptions, AssetClassUSFixedIncome,
|
||||
AssetClassUKEquity, AssetClassUKCrypto, AssetClassUKCFDs, AssetClassUKFI,
|
||||
AssetClassINEquity, AssetClassINCommodity, AssetClassINFnO,
|
||||
AssetClassSGEquity, AssetClassSGCrypto, AssetClassSGREITs,
|
||||
AssetClassAUEquity, AssetClassAUETF, AssetClassAUCrypto,
|
||||
AssetClassCAEquity, AssetClassCAETF, AssetClassCACrypto,
|
||||
AssetClassBREquity, AssetClassBROptions, AssetClassBRFIIs, AssetClassBRCrypto,
|
||||
AssetClassCHEquity, AssetClassCHDLTSecurity, AssetClassCHCrypto, AssetClassCHFI,
|
||||
AssetClassAEEquity, AssetClassAECrypto, AssetClassAEFI, AssetClassAETokenizedSecurity, AssetClassAEFunds,
|
||||
AssetClassEUEquity, AssetClassEUMiFIDFI, AssetClassEUUCITS, AssetClassEUAIF,
|
||||
AssetClassEUART, AssetClassEUEMT, AssetClassEUCAS, AssetClassEUDLTSecurity,
|
||||
}
|
||||
}
|
||||
|
||||
// ValidAssetClass returns true if s is a known asset class or wildcard.
|
||||
func ValidAssetClass(s string) bool {
|
||||
if s == string(AssetClassWildcard) {
|
||||
return true
|
||||
}
|
||||
for _, ac := range AllAssetClasses() {
|
||||
if string(ac) == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AssetClassStrings returns all asset class string values (for Base select fields).
|
||||
func AssetClassStrings() []string {
|
||||
all := AllAssetClasses()
|
||||
out := make([]string, len(all)+1)
|
||||
for i, ac := range all {
|
||||
out[i] = string(ac)
|
||||
}
|
||||
out[len(all)] = string(AssetClassWildcard)
|
||||
return out
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package types
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestValidAssetClass(t *testing.T) {
|
||||
valid := []string{
|
||||
"us_equity", "us_crypto", "us_options", "us_fixed_income",
|
||||
"uk_equity", "uk_crypto", "uk_cfds", "uk_fi",
|
||||
"in_equity", "in_commodity", "in_fno",
|
||||
"sg_equity", "sg_crypto", "sg_reits",
|
||||
"au_equity", "au_etf", "au_crypto",
|
||||
"ca_equity", "ca_etf", "ca_crypto",
|
||||
"br_equity", "br_options", "br_fiis", "br_crypto",
|
||||
"*",
|
||||
}
|
||||
for _, v := range valid {
|
||||
if !ValidAssetClass(v) {
|
||||
t.Errorf("ValidAssetClass(%q) = false, want true", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidAssetClass(t *testing.T) {
|
||||
invalid := []string{"", "equity", "stock", "US_EQUITY", "us-equity", "crypto"}
|
||||
for _, v := range invalid {
|
||||
if ValidAssetClass(v) {
|
||||
t.Errorf("ValidAssetClass(%q) = true, want false", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllAssetClassesNoDuplicates(t *testing.T) {
|
||||
seen := map[AssetClass]bool{}
|
||||
for _, ac := range AllAssetClasses() {
|
||||
if seen[ac] {
|
||||
t.Fatalf("duplicate asset class: %s", ac)
|
||||
}
|
||||
seen[ac] = true
|
||||
}
|
||||
}
|
||||
|
||||
func TestAssetClassStringsIncludesWildcard(t *testing.T) {
|
||||
strs := AssetClassStrings()
|
||||
found := false
|
||||
for _, s := range strs {
|
||||
if s == "*" {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatal("AssetClassStrings() missing wildcard")
|
||||
}
|
||||
if len(strs) != len(AllAssetClasses())+1 {
|
||||
t.Fatalf("AssetClassStrings() len = %d, want %d", len(strs), len(AllAssetClasses())+1)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user