圈存與匯撥
- 圈存與匯撥是下單前的準備作業,不是委託本身。
- 買進處置股需先圈款,賣出處置股或全額交割股需先圈券。
- 這組作業沒有取消機制,送出後不可逆,請在送出前確認內容。
- 作業狀態不會主動回報,需自行以查詢方法輪詢。
這組功能是什麼
新一代 API 提供三種下單前的準備作業:
| 作業 | 方法 | 用途 |
|---|---|---|
| 圈款(預繳) | reserve_cash、query_reserves | 於帳戶內預先圈存一筆款項,供後續買進委託使用 |
| 圈券 | reserve_stock、query_reserved_stocks | 於帳戶內預先圈存特定標的的庫存,供後續賣出委託使用 |
| 匯撥 | query_transfer_inventory、transfer_stock、query_transfers | 將庫存由本帳戶移轉至指定的另一個帳戶 |
圈款與圈券的共同性質是「先把資源保留下來,委託才送得出去」。 交易所對特定標的有預收款券的規定,未先完成圈存就送出委託會被拒絕。
什麼情況需要用
| 情境 | 需要的作業 | 說明 |
|---|---|---|
| 買進處置股 | 圈款 | 處置期間買進採預收款,須先圈存足額款項再送出買進委託 |
| 賣出處置股或全額交割股 | 圈券 | 採預收券,須先圈存標的庫存再送出賣出委託 |
| 同一投資人不同帳戶間調撥庫存 | 匯撥 | 例如主帳戶與子帳戶之間移轉庫存 |
一般標的的委託不需要這些作業,直接送出委託即可。
標的是否被列為處置股或全額交割股會隨時間變動,請於下單前確認當日狀態。
開始之前
呼叫這組功能之前,帳戶需先完成下列準備:
- SDK 版本 fubon-neo 2.2.9 以上。
- 完成電子集保相關約定的簽署。未完成簽署時,作業會被後端拒絕。
- API 金鑰需具備帳務權限。這組功能的申請與查詢皆屬帳務權限範圍。
作業特性
送出後不可逆
這組作業沒有取消或釋放的介面。一旦送出申請,無法透過 API 撤回。 送出前務必確認金額、標的與數量;程式逾時不要直接重送——圈款與圈券可先以 查詢方法比對整戶彙總金額或圈存餘額的變化,確認前一筆是否已成立; 匯撥目前無法以查詢確認(紀錄查詢不會立即反映、流水號亦無法比對,見「完整範例」的說明), 逾時請先洽營業員或分公司對帳後再決定是否重送,否則會實際重複移轉庫存。
申請類作業有服務時段
圈款、圈券與匯撥的申請服務時段為交易日 08:00 ~ 14:30,時段外送出會被後端拒絕並回覆訊息。查詢類不受此限。
狀態不會主動回報
這組作業不走委託回報通道,不會有主動推送的狀態變化通知。 申請送出後間隔數秒再查詢;輪詢設定合理間隔與次數上限, 並以查詢結果(而非申請當下的回應)作為後續下單的判斷依據。
以下操作範例假設已完成登入並取得證券帳戶 account。
圈款(預繳)
申請圈款
預繳新台幣交割款,供後續買進委託使用。
- Python
- Node.js
- C#
- C++
- Go
result = sdk.stock.reserve_cash(account, 10000)
print(result)
Result {
is_success: True,
message: None,
data : ReserveCashRecord {
date: "2026/07/28",
time: "10:53:23.000",
seq_no: "118036",
branch_no: "20207",
account: "9801163",
currency: "TWD",
amount: 10000,
status: 10
}}
const result = sdk.stock.reserveCash(account, 10000)
console.log(result)
{
isSuccess: true,
data: {
date: "2026/07/28",
time: "10:53:23.000",
seqNo: "118036",
branchNo: "20207",
account: "9801163",
currency: "TWD",
amount: 10000,
status: 10
}
}
var result = sdk.Stock.ReserveCash(account, 10000);
Console.WriteLine(result);
{
isSuccess = True,
message = ,
data = ReserveCashRecord{
date = 2026/07/28,
time = 10:53:23.000,
seqNo = 118036,
branchNo = 20207,
account = 9801163,
currency = TWD,
amount = 10000,
status = 10
}
}
auto result = sdk->stock->reserve_cash(account, 10000);
result, err := sdk.Stock.ReserveCash(account, 10000)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
查詢圈款
- Python
- Node.js
- C#
- C++
- Go
result = sdk.stock.query_reserves(account)
print(result)
Result {
is_success: True,
message: None,
data : ReserveCashSummary {
branch_no: "20207",
account: "9801163",
currency: "TWD",
reserved_amount: 9960200,
returned_amount: 0,
ordered_amount: 0,
}}
const result = sdk.stock.queryReserves(account)
console.log(result)
{
isSuccess: true,
data: {
branchNo: "20207",
account: "9801163",
currency: "TWD",
reservedAmount: 9960200,
returnedAmount: 0,
orderedAmount: 0
}
}
var result = sdk.Stock.QueryReserves(account);
Console.WriteLine(result);
{
isSuccess = True,
message = ,
data = ReserveCashSummary{
branchNo = 20207,
account = 9801163,
currency = TWD,
reservedAmount = 9960200,
returnedAmount = 0,
orderedAmount = 0
}
}
auto result = sdk->stock->query_reserves(account);
result, err := sdk.Stock.QueryReserves(account)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
圈券
申請圈券
圈存要賣出的股票。quantity 單位為股(1 張=1,000 股)。
- Python
- Node.js
- C#
- C++
- Go
result = sdk.stock.reserve_stock(account, "2330", 1000)
print(result)
Result {
is_success: True,
message: None,
data : ReserveStockRecord {
seq_no: "118036",
stock_no: "2330",
reserved_share: 1000,
}}
const result = sdk.stock.reserveStock(account, "2330", 1000)
console.log(result)
{
isSuccess: true,
data: {
seqNo: "118036",
stockNo: "2330",
reservedShare: 1000
}
}
var result = sdk.Stock.ReserveStock(account, "2330", 1000);
Console.WriteLine(result);
{
isSuccess = True,
message = ,
data = ReserveStockRecord{
seqNo = 118036,
stockNo = 2330,
reservedShare = 1000
}
}
auto result = sdk->stock->reserve_stock(account, "2330", 1000);
result, err := sdk.Stock.ReserveStock(account, "2330", 1000)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
查詢圈券
- Python
- Node.js
- C#
- C++
- Go
result = sdk.stock.query_reserved_stocks(account)
print(result)
Result {
is_success: True,
message: None,
data : [
ReserveStockItem { stock_no: "2330", market: Taiex, reserved_share: 5599 },
ReserveStockItem { stock_no: "1260", market: Taiemg, reserved_share: 3000 },
]
}
const result = sdk.stock.queryReservedStocks(account)
console.log(result)
{
isSuccess: true,
data: [
{ stockNo: "2330", market: Taiex, reservedShare: 5599 },
{ stockNo: "1260", market: Taiemg, reservedShare: 3000 }
]
}
var result = sdk.Stock.QueryReservedStocks(account);
foreach (var record in result.data)
{
Console.WriteLine(record);
}
{
isSuccess = True,
message = ,
data = [
ReserveStockItem{ stockNo = 2330, market = Taiex, reservedShare = 5599 },
ReserveStockItem{ stockNo = 1260, market = Taiemg, reservedShare = 3000 }
]
}
auto result = sdk->stock->query_reserved_stocks(account);
result, err := sdk.Stock.QueryReservedStocks(account)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
匯撥
查詢可匯撥庫存
回傳各檔可匯撥股數與市場別;申請匯撥前建議先查詢。
- Python
- Node.js
- C#
- C++
- Go
result = sdk.stock.query_transfer_inventory(account)
print(result)
Result {
is_success: True,
message: None,
data : [
TransferInventoryItem { stock_no: "006205", market: Taiex, available_share: 5000 },
TransferInventoryItem { stock_no: "6279", market: Taisdaq, available_share: 2000 },
]
}
const result = sdk.stock.queryTransferInventory(account)
console.log(result)
{
isSuccess: true,
data: [
{ stockNo: "006205", market: Taiex, availableShare: 5000 },
{ stockNo: "6279", market: Taisdaq, availableShare: 2000 }
]
}
var result = sdk.Stock.QueryTransferInventory(account);
foreach (var record in result.data)
{
Console.WriteLine(record);
}
{
isSuccess = True,
message = ,
data = [
TransferInventoryItem{ stockNo = 006205, market = Taiex, availableShare = 5000 },
TransferInventoryItem{ stockNo = 6279, market = Taisdaq, availableShare = 2000 }
]
}
auto result = sdk->stock->query_transfer_inventory(account);
result, err := sdk.Stock.QueryTransferInventory(account)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
申請匯撥
將股票撥出至指定的分公司帳戶。quantity 單位為股(1 張=1,000 股);market 為選填——未帶入時由 SDK 自動判別。僅能於申請服務時段內送出,且送出後不可逆(見作業特性)。
- Python
- Node.js
- C#
- C++
- Go
# 未帶 market 時由 SDK 自動判別
result = sdk.stock.transfer_stock(account, "960C", "7654321", "006205", 2000)
print(result)
Result {
is_success: True,
message: None,
data : TransferRecord {
date: "2026/07/28",
time: "10:53:48.340",
seq_no: "418181",
stock_no: "006205",
market: Taiex,
quantity: 2000,
target_branch_no: "960C",
target_account: "7654321",
status: 10
}}
// 未帶 market 時由 SDK 自動判別
const result = sdk.stock.transferStock(account, "960C", "7654321", "006205", 2000)
console.log(result)
{
isSuccess: true,
data: {
date: "2026/07/28",
time: "10:53:48.340",
seqNo: "418181",
stockNo: "006205",
market: Taiex,
quantity: 2000,
targetBranchNo: "960C",
targetAccount: "7654321",
status: 10
}
}
// 未帶 market 時由 SDK 自動判別
var result = sdk.Stock.TransferStock(account, "960C", "7654321", "006205", 2000);
Console.WriteLine(result);
{
isSuccess = True,
message = ,
data = TransferRecord{
date = 2026/07/28,
time = 10:53:48.340,
seqNo = 418181,
stockNo = 006205,
market = Taiex,
quantity = 2000,
targetBranchNo = 960C,
targetAccount = 7654321,
status = 10
}
}
// 未帶 market 時由 SDK 自動判別
auto result = sdk->stock->transfer_stock(account, "960C", "7654321", "006205", 2000, std::nullopt);
// 未帶 market 時由 SDK 自動判別
result, err := sdk.Stock.TransferStock(account, "960C", "7654321", "006205", 2000, nil)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
查詢匯撥紀錄
- Python
- Node.js
- C#
- C++
- Go
result = sdk.stock.query_transfers(account)
print(result)
Result {
is_success: True,
message: None,
data : [ TransferRecord {
date: "2026/07/28",
time: "10:53:48.340",
seq_no: "418181",
stock_no: "006205",
market: Taiex,
quantity: 2000,
target_branch_no: "960C",
target_account: "7654321",
status: 10, } ]
}
const result = sdk.stock.queryTransfers(account)
console.log(result)
{
isSuccess: true,
data: [ {
date: "2026/07/28",
time: "10:53:48.340",
seqNo: "418181",
stockNo: "006205",
market: Taiex,
quantity: 2000,
targetBranchNo: "960C",
targetAccount: "7654321",
status: 10
} ]
}
var result = sdk.Stock.QueryTransfers(account);
foreach (var record in result.data)
{
Console.WriteLine(record);
}
{
isSuccess = True,
message = ,
data = [ TransferRecord{
date = 2026/07/28,
time = 10:53:48.340,
seqNo = 418181,
stockNo = 006205,
market = Taiex,
quantity = 2000,
targetBranchNo = 960C,
targetAccount = 7654321,
status = 10
} ]
}
auto result = sdk->stock->query_transfers(account, "20260701", "20260722", std::nullopt);
startDate := "20260701"
endDate := "20260722"
result, err := sdk.Stock.QueryTransfers(account, &startDate, &endDate, nil)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
完整範例
買進處置股(圈款 → 確認 → 下單)與帳戶間匯撥:
匯撥紀錄查詢(query_transfers)目前在申請成功後不會立即反映該筆紀錄,
且回傳的 seq_no 為空字串,無法用申請時取得的流水號比對。
請以申請回應的 status(10 為成功、90 為失敗)作為判斷依據,
並保留申請回應的 seq_no 以便日後與營業員或分公司對帳。
- Python
- Node.js
- C#
- C++
- Go
# 1. 圈款:預繳買進處置股所需的交割款
result = sdk.stock.reserve_cash(account, 10000)
if not result.is_success:
print(result.message)
# 2. 間隔數秒後查詢,確認圈款已受理再送出買進委託(見「建立委託單」)
reserves = sdk.stock.query_reserves(account)
print(reserves.data.reserved_amount) # 整戶預收金額
# --- 帳戶間匯撥:以申請回應判斷是否受理 ---
result = sdk.stock.transfer_stock(account, "960C", "7654321", "006205", 1000)
if result.is_success and result.data.status == 10:
print("匯撥已受理,流水號:", result.data.seq_no)
else:
print("匯撥未受理:", result.message)
// 1. 圈款:預繳買進處置股所需的交割款
const result = sdk.stock.reserveCash(account, 10000)
if (!result.isSuccess) console.log(result.message)
// 2. 間隔數秒後查詢,確認圈款已受理再送出買進委託(見「建立委託單」)
const reserves = sdk.stock.queryReserves(account)
console.log(reserves.data.reservedAmount) // 整戶預收金額
// --- 帳戶間匯撥:以申請回應判斷是否受理 ---
const transfer = sdk.stock.transferStock(account, "960C", "7654321", "006205", 1000)
if (transfer.isSuccess && transfer.data.status === 10) {
console.log("匯撥已受理,流水號:", transfer.data.seqNo)
} else {
console.log("匯撥未受理:", transfer.message)
}
// 1. 圈款:預繳買進處置股所需的交割款
var result = sdk.Stock.ReserveCash(account, 10000);
if (!result.isSuccess) Console.WriteLine(result.message);
// 2. 間隔數秒後查詢,確認圈款已受理再送出買進委託(見「建立委託單」)
var reserves = sdk.Stock.QueryReserves(account);
Console.WriteLine(reserves.data.reservedAmount); // 整戶預收金額
// --- 帳戶間匯撥:以申請回應判斷是否受理 ---
var transfer = sdk.Stock.TransferStock(account, "960C", "7654321", "006205", 1000);
if (transfer.isSuccess && transfer.data.status == 10) {
Console.WriteLine("匯撥已受理,流水號: " + transfer.data.seqNo);
} else {
Console.WriteLine("