gitee.com/quant1x/engine@v1.8.4/datasource/base/tdx_fundflow.go (about) 1 package base 2 3 import ( 4 "gitee.com/quant1x/exchange" 5 "gitee.com/quant1x/gotdx" 6 "gitee.com/quant1x/gox/api" 7 "gitee.com/quant1x/num" 8 "gitee.com/quant1x/pandas" 9 "strconv" 10 "strings" 11 ) 12 13 const ( 14 kCompanyInfoFundFlow = "资金动向" 15 kCategoryFundFlow = "资金流向" 16 ) 17 18 //【5.资金流向】 19 //日期 主力净额 主力净额 超大单净买入 超大单净买入 大单净买入 大单净买入 主买净额 主买净额 20 // 金额(元) 占比(%) 金额(元) 占比(%) 金额(元) 占比(%) 金额(元) 占比(%) 21 //───────────────────────────────────────────────── 22 //2023-05-15 -8581.10万 -4.95 -3069.63万 -1.77 -5511.47万 -3.18 -1.46亿 -8.44 23 //2023-05-12 -3.26亿 -16.20 -3.01亿 -14.95 -2525.27万 -1.26 -1.62亿 -8.05 24 //2023-05-11 2.75亿 17.10 2.95亿 18.35 -2007.90万 -1.25 -878.46万 -0.55 25 //2023-05-10 -3.27亿 -14.45 -2.35亿 -10.37 -9216.30万 -4.07 -2.43亿 -10.75 26 //2023-05-09 1.96亿 25.91 1.97亿 26.02 -87.68万 -0.12 -3.76亿 -49.78 27 //2023-05-08 -1161.92万 -1.30 -1778.75万 -1.98 616.83万 0.69 -3290.33万 -3.67 28 //2023-05-05 -515.71万 -0.56 -1642.56万 -1.79 1126.85万 1.23 -3437.44万 -3.75 29 //2023-05-04 7685.06万 6.09 3398.48万 2.69 4286.57万 3.40 1.09亿 8.67 30 //2023-04-28 2158.92万 3.00 1249.07万 1.74 909.85万 1.27 4346.58万 6.05 31 //2023-04-27 -1.30亿 -17.61 -7470.81万 -10.13 -5517.81万 -7.48 -2907.44万 -3.94 32 //2023-04-26 2127.77万 2.14 1367.42万 1.37 760.34万 0.76 1.13亿 11.34 33 //2023-04-25 664.05万 1.08 -1458.93万 -2.36 2122.98万 3.44 -139.47万 -0.23 34 //2023-04-24 -126.71万 -0.21 295.24万 0.48 -421.95万 -0.69 -791.00万 -1.29 35 //2023-04-21 -8501.18万 -12.44 -3843.78万 -5.62 -4657.39万 -6.81 -8237.27万 -12.05 36 //2023-04-20 8625.04万 8.14 3603.48万 3.40 5021.56万 4.74 1.23亿 11.57 37 //2023-04-19 9310.97万 8.27 1.11亿 9.82 -1752.71万 -1.56 1.09亿 9.71 38 //2023-04-18 1312.51万 4.22 1552.84万 4.99 -240.34万 -0.77 -1989.31万 -6.39 39 //2023-04-17 -3970.27万 -10.76 -1600.06万 -4.34 -2370.21万 -6.42 -1318.26万 -3.57 40 //2023-04-14 -1514.15万 -3.66 -405.87万 -0.98 -1108.28万 -2.68 -1296.30万 -3.13 41 //2023-04-13 -1.09亿 -14.38 -5319.72万 -7.03 -5555.62万 -7.35 -5555.62万 -7.35 42 //───────────────────────────────────────────────── 43 44 var ( 45 TdxFieldsFundFlow = []string{"日期", "主力净额金额(元)", "主力净额占比(%)", "超大单净买入金额(元)", "超大单净买入占比(%)", "大单净买入金额(元)", "大单净买入占比(%)", "主买净额金额(元)", "主买净额占比(%)"} 46 ) 47 48 func splitContent(content, unit string) (headers []string, lines [][]string) { 49 //c := strings.ReplaceAll(content, "-\\u003e", "->") 50 //arr := strings.Split(c, "\\r\\n\\r\\n") 51 arr := strings.Split(content, "\r\n\r\n") 52 for i, block := range arr { 53 block = strings.TrimSpace(block) 54 if i > 0 && strings.Index(block, unit) >= 0 { 55 arr := strings.Split(block, "\r\n") 56 tmpHeaders := []string{} 57 numberFound := false 58 for _, v := range arr { 59 if strings.Index(v, unit) >= 0 { 60 continue 61 } 62 if strings.HasPrefix(v, "──") { 63 continue 64 } 65 v = strings.TrimSpace(v) 66 // 非数字开头是表头, 数字开头为数据 67 ch := v[0] 68 if ch >= '0' && ch <= '9' { 69 if !numberFound { 70 numberFound = true 71 } 72 cols := []string{} 73 foundDate := false 74 for _, tmp := range strings.Fields(v) { 75 tf := float64(0) 76 tmp = strings.TrimSpace(tmp) 77 //if tmp == "2023-04-17" { 78 // fmt.Println("found") 79 //} 80 if !foundDate { 81 if _, err := api.ParseTime(tmp); err == nil { 82 cols = append(cols, tmp) 83 foundDate = true 84 continue 85 } 86 } 87 if fs, _, ok := strings.Cut(tmp, "万"); ok { 88 tf = num.AnyToFloat64(fs) * 10000 89 } else if fs, _, ok := strings.Cut(tmp, "亿"); ok { 90 tf = num.AnyToFloat64(fs) * 100000000 91 } else { 92 tf = num.AnyToFloat64(fs) 93 } 94 f := strconv.FormatFloat(tf, 'f', -1, 64) 95 cols = append(cols, f) 96 } 97 lines = append(lines, cols) 98 99 } else { 100 tmpHeaders = append(tmpHeaders, v) 101 } 102 103 } 104 if numberFound { 105 tmpHeadersCount := len(tmpHeaders) 106 if tmpHeadersCount >= 1 { 107 headers = strings.Fields(tmpHeaders[0]) 108 } 109 numberOfHeaderFields := len(headers) 110 for j := 1; j < tmpHeadersCount; j++ { 111 remaining := strings.Fields(tmpHeaders[j]) 112 numberOfRemainingFields := len(remaining) 113 for k := 0; k < numberOfRemainingFields; k++ { 114 pos := 1 + k 115 headers[numberOfHeaderFields-pos] += remaining[numberOfRemainingFields-pos] 116 } 117 118 } 119 } 120 break 121 } 122 } 123 return 124 } 125 126 // FundFlow 资金流向 127 // 128 // deprecated: 不推荐 129 func FundFlow(securityCode string) pandas.DataFrame { 130 tdxApi := gotdx.GetTdxApi() 131 securityCode = exchange.CorrectSecurityCode(securityCode) 132 reply, err := tdxApi.GetCompanyInfoContent(securityCode, kCompanyInfoFundFlow) 133 if err != nil { 134 return pandas.DataFrame{Err: err} 135 } 136 //fmt.Println("code:", securityCode) 137 //fmt.Printf("%+v\n", reply) 138 //data, _ := json.Marshal(reply) 139 //text := api.Bytes2String(data) 140 //fmt.Println(text) 141 //dict := reply.Map("资金流向") 142 //dict.Each(func(key interface{}, value interface{}) { 143 // fmt.Println(key, value) 144 //}) 145 146 headers, lines := splitContent(reply.Content, kCategoryFundFlow) 147 //for _, v := range headers { 148 // fmt.Printf("%s|", v) 149 //} 150 //fmt.Println() 151 //for _, vv := range lines { 152 // for _, v := range vv { 153 // fmt.Printf("%s|", v) 154 // } 155 // fmt.Println() 156 //} 157 //fmt.Println() 158 if len(headers) == 0 || len(lines) == 0 || len(headers) != len(lines[0]) { 159 return pandas.DataFrame{} 160 } 161 rows := [][]string{} 162 rows = append(rows, headers) 163 fieldsNum := len(headers) 164 for _, v := range lines { 165 if len(v) != fieldsNum { 166 continue 167 } 168 rows = append(rows, v) 169 } 170 171 df := pandas.LoadRecords(rows) 172 return df 173 }