-
-
Notifications
You must be signed in to change notification settings - Fork 266
/
finance.go
127 lines (109 loc) · 2.7 KB
/
finance.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package gofakeit
import (
"strconv"
"unicode"
)
const cusipStr = upperStr + numericStr
// CUSIP
func Cusip() string {
return cusip(GlobalFaker)
}
func (f *Faker) Cusip() string {
return cusip(f)
}
func cusip(f *Faker) string {
cusipBytes := make([]byte, 8)
for i := 0; i < len(cusipBytes); i++ {
cusipBytes[i] = byte(cusipStr[f.IntN(len(cusipStr))])
}
baseCusip := string(cusipBytes)
chkDigit := cusipChecksumDigit(baseCusip)
return baseCusip + chkDigit
}
// ISIN
func Isin() string {
return isin(GlobalFaker)
}
func (f *Faker) Isin() string {
return isin(f)
}
func isin(f *Faker) string {
countryCode := countryAbr(f)
nsin := cusip(f)
isinChkDig := isinChecksumDigit(countryCode + nsin)
return countryCode + nsin + isinChkDig
}
// cusipChecksumDigit returns the checksum digit for a CUSIP
func cusipChecksumDigit(cusip string) string {
sum := 0
for i, c := range cusip {
v := 0
if unicode.IsDigit(c) {
v = int(c - '0')
}
if unicode.IsLetter(c) {
//0-indexed ordinal position of Letter + 10
v = int(c-'A') + 10
}
if i%2 != 0 {
// Multiply odd digits by two
v = v * 2
}
sum = sum + int(v/10) + v%10
}
return strconv.Itoa((10 - (sum % 10)) % 10)
}
// isinChecksumDigit returns the checksum digit for an ISIN
func isinChecksumDigit(isin string) string {
isinDigits := make([]int, 0)
for _, c := range isin {
if unicode.IsLetter(c) {
letterVal := int(c) - 55
// Each digit is added as a separate value
isinDigits = append(isinDigits, letterVal/10)
isinDigits = append(isinDigits, letterVal%10)
}
if unicode.IsDigit(c) {
isinDigits = append(isinDigits, int(c-'0'))
}
}
oddSum := 0
evenSum := 0
// Take the per digit sum of the digitized ISIN, doubling even indexed digits
for i, d := range isinDigits {
if i%2 == 0 {
elem := 2 * d
if elem > 9 {
// If the element now has two digits, sum those digits
elem = (elem % 10) + (elem / 10)
}
evenSum += elem
} else {
oddSum += d
}
}
return strconv.Itoa((10 - (oddSum+evenSum)%10) % 10)
}
// Lookup Adds
func addFinanceLookup() {
AddFuncLookup("cusip", Info{
Display: "CUSIP",
Category: "finance",
Description: "Unique identifier for securities, especially bonds, in the United States and Canada",
Example: "38259P508",
Output: "string",
Generate: func(f *Faker, m *MapParams, info *Info) (any, error) {
return cusip(f), nil
},
})
AddFuncLookup("isin", Info{
Display: "ISIN",
Category: "finance",
Description: "International standard code for uniquely identifying securities worldwide",
Example: "CVLRQCZBXQ97",
Output: "string",
Generate: func(f *Faker, m *MapParams, info *Info) (any, error) {
return isin(f), nil
},
})
}