refactor: rewrite SDK to align with OpenAPI spec

- Split monolithic models.go (738 lines) into 6 domain files
- Fix schema drift: BasicInfo, PersonalInfo, TotalCashDerivativeResponse,
  derivative order types, money transfer types aligned to spec
- Add missing REST endpoints: bsa-ext, bsa-month (supply/demand)
- Add WebSocket support for 5 streaming endpoints (nhooyr.io/websocket)
- Add 45 httptest-based tests (74.9% coverage)
- Rewrite README with full API coverage table

BREAKING CHANGE: struct fields and types changed to match OpenAPI spec.
BasicInfo reduced to 5 fields, TokenResponse uses 'token' field,
PlaceOrderRequest uses int types, derivative order types renamed.
This commit is contained in:
2026-04-05 12:00:18 +07:00
parent 9519521dd7
commit f9d80e582a
25 changed files with 2362 additions and 777 deletions
+20 -3
View File
@@ -22,7 +22,7 @@ func main() {
if err != nil {
log.Fatalf("Failed to get token: %v", err)
}
fmt.Printf("Token obtained, expires in %d seconds\n", token.ExpiresIn)
fmt.Printf("Token obtained: %s\n", token.Token)
// Or set token directly if you already have one:
// client.SetToken("your-jwt-token")
@@ -33,7 +33,10 @@ func main() {
log.Fatalf("Failed to get account info: %v", err)
}
if account.BasicInfo != nil {
fmt.Printf("Account: %s - %s\n", account.BasicInfo.Code105C, account.BasicInfo.FullName)
fmt.Printf("Account: %s (status: %s)\n", account.BasicInfo.Code105C, account.BasicInfo.Status)
}
if account.PersonalInfo != nil {
fmt.Printf("Name: %s\n", account.PersonalInfo.FullName)
}
// 3. Get stock prices
@@ -49,7 +52,7 @@ func main() {
order, err := client.PlaceOrder(ctx, "0001170730", &tcbs.PlaceOrderRequest{
Symbol: "FPT",
ExecType: "NB", // Buy
OrderQtty: 100,
Quantity: 100,
Price: 120000,
PriceType: "LO", // Limit order
})
@@ -89,4 +92,18 @@ func main() {
for _, d := range derivatives {
fmt.Printf("%s: last=%.1f OI=%.0f\n", d.Ticker, d.LastPrice, d.OpenInterest)
}
// 9. Get supply/demand (15-minute)
sd, err := client.GetSupplyDemand(ctx, "FPT", "all")
if err != nil {
log.Fatalf("Failed to get supply/demand: %v", err)
}
fmt.Printf("Supply/demand data points: %d\n", len(sd.Data))
// 10. Get monthly supply/demand
sdm, err := client.GetSupplyDemandMonth(ctx, "FPT", "all")
if err != nil {
log.Fatalf("Failed to get monthly supply/demand: %v", err)
}
fmt.Printf("Monthly supply/demand data points: %d\n", len(sdm.Data))
}