feat: introduce mnie

This commit is contained in:
Shotaro Nakamura
2026-06-21 21:37:07 +09:00
parent 614ea8a992
commit fed3ac1b61
104 changed files with 1815 additions and 218 deletions
+5
View File
@@ -0,0 +1,5 @@
# client-sbi
SBI provider client for Mnie.
The public finance method contract is exported from `@repo/mnie-types`; this package contains SBI-specific login, parsing, and transport code.
+27
View File
@@ -0,0 +1,27 @@
{
"name": "@repo/client-sbi",
"private": true,
"type": "module",
"module": "index.ts",
"types": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"import": "./src/index.ts"
}
},
"scripts": {
"clean": "rm -rf dist",
"typecheck": "tsc"
},
"dependencies": {
"@repo/mnie-types": "workspace:*",
"iconv-lite": "^0.7.2"
},
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5"
}
}
+48
View File
@@ -0,0 +1,48 @@
export { createMethodsFromSession } from './methods'
export {
SBI_SERVER_ERROR_MESSAGES,
SbiServerError,
getSbiServerErrorMessage,
} from './methods/error-map'
export type { SbiServerErrorOptions } from './methods/error-map'
export { loginWithPasskey } from './session'
export type * from '@repo/mnie-types'
export type {
LoginWithPasskeyOptions,
PasskeyLoginResponse,
PlaintextStoredWebAuthnCredential,
SbiClientOptions,
StoredWebAuthnCredential,
StoredWebAuthnCredentialSecret,
AccountAssetsValuationDetail,
AccountAssetsValuationSummary,
AccountAssetsValuations,
ExchangeAccountKind,
ExchangeOrderPreview,
ExchangeOrderReceipt,
ExchangeOrderSide,
ExchangeRateInfo,
ExchangeSellMethod,
ExchangeSpecificMethod,
WebAuthnAlgorithm,
WebAuthnJwk,
WebAuthnTransport,
WebAuthnUserVerification,
ChartPeriod,
ChartPrice,
IssueChart,
IssueSearchItem,
IssueSearchResult,
IssueSearchStatus,
MarketCode,
OrderCorrectionPreOrder,
OrderCorrectionPreOrderDetail,
OrderPreview,
TradeRecord,
TradeRecordList,
StockOrderPreOrder,
StockOrderPreOrderMarginTradeType,
StockOrderPreOrderPaymentLimit,
StockOrderPreOrderPriceStep,
} from './types'
export type * from './methods/types'
+53
View File
@@ -0,0 +1,53 @@
import type { MarketCode } from './types'
export type MarketRegion = 'domestic' | 'us'
const DOMESTIC_TO_MTS = {
XTKS: 'TKY',
XNGO: 'NGY',
XFKA: 'FKO',
XSAP: 'SPR',
} as const satisfies Record<string, string>
const MTS_TO_DOMESTIC = Object.fromEntries(
Object.entries(DOMESTIC_TO_MTS).map(([mic, mts]) => [mts, mic]),
) as Record<string, MarketCode>
const US_MARKETS = new Set<MarketCode>(['XNAS', 'XNYS', 'ARCX'])
export const marketRegion = (market: MarketCode | undefined, methodName: string): MarketRegion => {
if (!market) throw new Error(`${methodName} requires market`)
if (market in DOMESTIC_TO_MTS) return 'domestic'
if (market === 'STK') return 'domestic'
if (US_MARKETS.has(market)) return 'us'
throw new Error(`${methodName} does not support market: ${market}`)
}
export const isUsMarket = (market: MarketCode | undefined) =>
market != null && US_MARKETS.has(market)
export const domesticMarketToMts = (market: MarketCode | undefined, methodName: string) => {
if (!market) throw new Error(`${methodName} requires market`)
const mts = DOMESTIC_TO_MTS[market as keyof typeof DOMESTIC_TO_MTS]
if (!mts) throw new Error(`${methodName} does not support domestic market: ${market}`)
return mts
}
export const mtsMarketToDomestic = (market: string | undefined): MarketCode | undefined => {
if (!market) return undefined
return MTS_TO_DOMESTIC[market]
}
export const requireDomesticMarket = (market: MarketCode | undefined, methodName: string) => {
const region = marketRegion(market, methodName)
if (region !== 'domestic') {
throw new Error(`${methodName} supports only domestic markets`)
}
}
export const requireUsMarket = (market: MarketCode | undefined, methodName: string) => {
const region = marketRegion(market, methodName)
if (region !== 'us') {
throw new Error(`${methodName} supports only US stock markets`)
}
}
@@ -0,0 +1,134 @@
export const SBI_SERVER_ERROR_MESSAGES: Record<string, string> = {
ME0010: 'No data is available.',
E_0001:
'Access is currently unstable. Try logging in again later or use the desktop website or HYPER SBI.',
E_0002: 'Communication failed. Check your network connection and try again.',
E_0003: 'You were logged out because the session was inactive for 60 minutes. Sign in again.',
E_0004: 'User name is required.',
E_0005: 'Login password is required.',
E_0007: 'The trading password is incorrect.',
E_0008: 'The requested issue does not exist.',
E_0009:
'Login to this app is restricted. Remove the restriction from the SBI Securities website settings.',
E_0010:
'More than 1,000 cash position records cannot be displayed in this app. Check the desktop website.',
E_0011:
'More than 1,000 cash position records cannot be displayed in this app. Try the all-records view.',
E_0012: 'Order quantity is required.',
E_0013: 'Order price is required.',
E_0014: 'Stop order trigger condition is required.',
E_0015: 'Trading password is required.',
E_0016:
'More than 1,000 margin position records cannot be displayed in this app. Check the desktop website.',
E_0017:
'More than 1,000 margin position records cannot be displayed in this app. Try the all-records view.',
E_0018: 'Issue name or issue code is required.',
E_0019: 'There are no sellable cash shares.',
E_0020: 'Failed to sync the watchlist. Sign in again to display the latest watchlist.',
E_0021: 'No matching issues were found. Change the search criteria and try again.',
E_0022:
'More than 1,000 order inquiry records cannot be displayed in this app. Check the desktop website.',
E_0023:
'More than 1,000 open order records cannot be displayed in this app. Check the desktop website.',
E_0024:
'More than 1,000 same-day execution records cannot be displayed in this app. Check the desktop website.',
E_0025: 'No data is available.',
E_0026: 'There are no closeable long margin positions.',
E_0027: 'There are no closeable short margin positions.',
E_0028: 'Watchlist name is required.',
E_0029: 'Too many issues matched, so all issues cannot be displayed.',
E_0030: 'An unexpected error occurred while fetching board prices.',
E_0031: 'The session timed out.',
E_0032: 'An unexpected error occurred.',
E_0033: 'A required parameter is missing.',
E_0034: 'Settings could not be retrieved.',
E_0035: 'A connection or read timeout occurred.',
E_0036:
'Order reception timed out. The order may already have been submitted; check order inquiry.',
E_0038: 'There are no margin positions available for stock receipt.',
E_0039: 'There are no margin positions available for stock delivery.',
E_0040: 'The order quantity exceeds the maximum input quantity.',
E_0041: 'Failed to update the watchlist. It will be synced with the latest watchlist.',
E_0042: 'Failed to sync the watchlist. Sign in again to display the latest watchlist.',
E_0043: 'The selected index cannot be displayed on a chart.',
E_0044: 'The selected issue cannot be traded on the PTS market.',
E_0045: 'Margin trade type is not selected.',
E_0046: 'The selected value is invalid. Select it again.',
E_0047: 'The order quantity is invalid. Enter a valid half-width numeric quantity.',
E_0048:
'Buying power may be insufficient to order all theme component issues. Return to order input to change quantities.',
E_0049:
'The NISA investment limit may be insufficient to order all theme component issues. Return to order input to change quantities.',
E_0050: 'A search error occurred.',
E_0051: 'No target data is available.',
E_0052: 'No details match the conditions.',
E_0053: 'Failed to retrieve registered issues. The registered issue feature is unavailable.',
E_0054: 'No watchlist is registered. Create one from the edit button.',
E_0055:
'The registered issue limit is 50. Delete an issue from notification settings before adding another.',
E_0056: 'The registered issue limit is 50. Delete an issue before adding another.',
E_0057: 'This issue is already registered.',
E_0058: 'No matching issue was found.',
E_0059: 'No issue is registered. Add an issue from the edit icon.',
E_0060: 'OCO1 price is required.',
E_0061: 'OCO2 stop order trigger condition is required.',
E_0062: 'OCO2 price is required.',
E_0063: 'IFD2 price is required.',
E_0064: 'IFD2 stop order trigger condition is required.',
E_0065: 'Order quantity is invalid.',
E_0066: 'Order price is invalid.',
E_0067: 'Stop order trigger condition is invalid.',
E_0068: 'OCO1 price is invalid.',
E_0069: 'OCO2 stop order trigger condition is invalid.',
E_0070: 'OCO2 price is invalid.',
E_0071: 'IFD2 price is invalid.',
E_0072: 'IFD2 stop order trigger condition is invalid.',
E_0073: 'Target value is required.',
E_0074: 'Password reset is required. Complete the reset procedure on the website.',
E_0075: 'An error occurred. Wait a while and try again.',
E_0076:
'Registering a new FIDO smartphone authentication credential will disable the previous one.',
E_0077: 'Signed in with FIDO smartphone authentication.',
E_0078:
'FIDO smartphone authentication is not complete. Scan the QR code with the SBI Securities Smart App on another device, complete authentication, and try again.',
E_0079: 'An error occurred. Start again from login.',
E_0080: 'Login from an invalid device was detected. The app will exit.',
E_0081:
'Identity verification is not complete. Call the authentication phone number from the registered phone number.',
E_0082: 'The request expired. Start the procedure again.',
E_0083: 'An error occurred. Wait a while and try again.',
}
export type SbiServerErrorOptions = {
code: string
status?: string
serverMessage?: string
trCode?: string
requestUrl?: string
}
export class SbiServerError extends Error {
readonly code: string
readonly status?: string
readonly serverMessage?: string
readonly englishMessage: string
readonly trCode?: string
readonly requestUrl?: string
constructor(options: SbiServerErrorOptions) {
const englishMessage = getSbiServerErrorMessage(options.code)
const serverMessage = options.serverMessage ? ` Server message: ${options.serverMessage}` : ''
super(`SBI server error ${options.code}: ${englishMessage}${serverMessage}`)
Object.setPrototypeOf(this, new.target.prototype)
this.name = 'SbiServerError'
this.code = options.code
this.status = options.status
this.serverMessage = options.serverMessage
this.englishMessage = englishMessage
this.trCode = options.trCode
this.requestUrl = options.requestUrl
}
}
export const getSbiServerErrorMessage = (code: string) =>
SBI_SERVER_ERROR_MESSAGES[code] ?? `SBI server returned error code ${code}.`
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
export type * from '@repo/mnie-types'
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+951
View File
@@ -0,0 +1,951 @@
export type WebAuthnAlgorithm = -7 | -257
export type WebAuthnUserVerification = 'required' | 'preferred' | 'discouraged'
export type WebAuthnTransport = 'ble' | 'hybrid' | 'internal' | 'nfc' | 'usb'
export type WebAuthnJwk = {
kty: string
crv?: string
x?: string
y?: string
d?: string
n?: string
e?: string
key_ops?: string[]
ext?: boolean
[key: string]: unknown
}
export type StoredWebAuthnCredentialSecret = {
privateKey: {
format: 'jwk'
jwk: WebAuthnJwk
}
cosePrivateKey?: string
registration?: {
attestationObject?: string
clientDataJSON?: string
}
}
export type StoredWebAuthnCredential = {
version: 1
kind: 'webauthn-credential'
provider: 'sbi-sec'
rpId: string
origin: string
credentialId: string
userHandle?: string
alg: WebAuthnAlgorithm
publicKey: {
format: 'jwk'
jwk: WebAuthnJwk
}
authenticator: {
aaguid?: string
signCount: number
discoverable: boolean
userVerification: WebAuthnUserVerification
transports?: WebAuthnTransport[]
backupEligible?: boolean
backupState?: boolean
}
secret: {
encrypted: true
format: 'jwe-like-v1'
kdf: {
name: 'argon2id' | 'scrypt'
salt: string
params: Record<string, unknown>
}
cipher: {
name: 'AES-256-GCM'
nonce: string
aad: string
ciphertext: string
tag: string
}
}
createdAt: string
updatedAt: string
}
export type PlaintextStoredWebAuthnCredential = Omit<StoredWebAuthnCredential, 'secret'> & {
label?: string
secretPlaintext: StoredWebAuthnCredentialSecret
}
export type PasskeyLoginResponse = {
type: 'passkey-login-response'
requestUrl: string
status: number
body: ArrayBuffer
text: string
accessToken?: string
header: {
sessionId: string
trCode: string
resultCode: string
} | null
}
export type ForeignStockEndpointConfig = {
baseUrl?: string
restUrl: string
graphqlBffUrl: string
graphqlIntUrl: string
userAgent?: string
}
export type ForeignStockSession = {
endpoints: ForeignStockEndpointConfig
ssoToken?: string
sessionId?: string
accountId?: string
marketPriceHash?: string
candleHash?: string
loginAuthenticated?: boolean
}
export type MainSiteAuthCache = {
baseUrl: string
assetsUrl: string
cookieHeader: string
authenticatedAt: string
}
export type MainSiteSession = {
baseUrl?: string
etGatePath?: string
assetsValuationsPath?: string
exchangeOrderInputPath?: string
exchangeOrderPasswordPath?: string
exchangeOrderConfirmPath?: string
exchangeOrderCompletePath?: string
auth?: MainSiteAuthCache
authPromise?: Promise<MainSiteAuthCache>
}
export type SbiSession = {
mtsBaseUrl: string
izanagiBaseUrl?: string
foreignStock?: ForeignStockSession
mainSite?: MainSiteSession
profile: AccountProfile
loginResponse: PasskeyLoginResponse
tradePassword?: string
deviceIdRegistered?: boolean
tradeAuthentication?: SbiTradeAuthenticationOptions
}
export type LoginWithPasskeyOptions = {
passkeyCredential: PlaintextStoredWebAuthnCredential
authBaseUrl?: string
mtsBaseUrl?: string
izanagiBaseUrl?: string
foreignStockBaseUrl?: string
usStockBaseUrl?: string
foreignStockRestUrl?: string
foreignStockGraphqlBffUrl?: string
foreignStockGraphqlIntUrl?: string
foreignStockUserAgent?: string
mainSiteBaseUrl?: string
mainSiteEtGatePath?: string
mainSiteAssetsValuationsPath?: string
mainSiteExchangeOrderInputPath?: string
mainSiteExchangeOrderPasswordPath?: string
mainSiteExchangeOrderConfirmPath?: string
mainSiteExchangeOrderCompletePath?: string
}
export type SbiClientOptions = {
tradePassword?: string
deviceId?: string
tradeAuthentication?: SbiTradeAuthenticationOptions
}
export type SbiTradeAuthenticationRequest = {
type: 'phone'
telNo?: string
phoneNo?: string
sbiCallNo?: string
authLimitTime?: string
}
export type SbiTradeAuthenticationOptions = {
onRequired?: (request: SbiTradeAuthenticationRequest) => void | Promise<void>
confirmAttempts?: number
confirmIntervalMs?: number
}
export type IssueCode = string
export type DomesticMarketCode = 'XTKS' | 'XNGO' | 'XFKA' | 'XSAP'
export type SKabuMarketCode = 'STK'
export type UsStockMarketCode = 'XNAS' | 'XNYS' | 'ARCX'
export type MarketCode = DomesticMarketCode | SKabuMarketCode | UsStockMarketCode
export type OrderId = string
export type WatchlistId = string
export type PositionId = string
export type ThemeId = string
export type CurrencyAmount = {
value: number | null
text: string
currency: 'JPY' | 'USD'
}
export type PercentValue = {
value: number | null
text: string
}
export type SignedTextValue = {
value: number | null
text: string
sign?: 'positive' | 'negative' | 'zero'
}
export type AccountAssetsValuationSummary = {
assetsErrorType: unknown
valuation: number | null
netChange: number | null
percentChange: number | null
monthOnMonth: number | null
monthOnMonthRatio: unknown
profitLoss: number | null
profitLossRate: number | null
acquisitionCost: number | null
}
export type AccountAssetsValuationDetail = AccountAssetsValuationSummary & {
category: string
compositionRatio: number | null
}
export type AccountAssetsValuations = {
fetchedAt: string
summary: AccountAssetsValuationSummary
summaryWithoutDeposit: AccountAssetsValuationSummary
summaryWithoutIdeco?: AccountAssetsValuationSummary
summaryWithoutDepositAndIdeco?: AccountAssetsValuationSummary
summaryDetails: AccountAssetsValuationDetail[]
summaryDetailsWithoutDeposit: AccountAssetsValuationDetail[]
summaryDetailsWithoutIdeco: AccountAssetsValuationDetail[]
summaryDetailsWithoutDepositAndIdeco: AccountAssetsValuationDetail[]
}
export type AccountType =
| 'general'
| 'specific'
| 'growthInvestment'
| 'nisa'
| 'juniorNisa'
| 'unknown'
export type DepositType =
| 'general'
| 'specific'
| 'growthInvestment'
| 'nisa'
| 'juniorNisa'
| 'unknown'
export type TradeSide = 'buy' | 'sell'
export type MarginTradeSide = 'buy' | 'sell'
export type OrderStatus = 'open' | 'executed' | 'cancelled' | 'expired' | 'rejected' | 'unknown'
export type OrderKind = 'market' | 'limit' | 'stop' | 'oco' | 'ifd' | 'ifdo' | 's' | 'unknown'
export type LoginStatus =
| 'success'
| 'invalidUser'
| 'tradeForbidden'
| 'locked'
| 'fidoAuthorizationIncorrect'
| 'fidoAuthorization'
| 'passwordChangeRequired'
| 'unknown'
export type LoginType = 'passkey' | 'password' | 'unknown'
export type SpecificAccountType =
| 'withHolding'
| 'withoutHolding'
| 'nonSpecific'
| 'notApply'
| 'unknown'
export type IsaAccountType =
| 'nisaTradeForbidden'
| 'oldNisaTradePermitted'
| 'newNisaTradePermitted'
| 'nisaTradePermitted'
| 'unknown'
export type IssueRef = {
code: IssueCode
market?: MarketCode
name?: string
}
export type IssueSearchItem = IssueRef & {
extract?: string
extractWord?: string
boldFrom?: string
boldTo?: string
hitString?: string
}
export type IssueSearchStatus = 'success' | 'searchError' | 'tooManyResults' | 'unknown'
export type IssueSearchResult = {
status?: string
statusText: IssueSearchStatus
issues: IssueSearchItem[]
}
export type ChartPeriod = 'minute' | 'day' | 'week' | 'month'
export type ChartPrice = {
dateTime: string
open: CurrencyAmount
high: CurrencyAmount
low: CurrencyAmount
close: CurrencyAmount
volume?: number | null
}
export type IssueChart = {
issue: IssueRef
period: ChartPeriod
unit: number
prices: ChartPrice[]
previousClose?: CurrencyAmount
currentPrice?: CurrencyAmount
highPrice?: CurrencyAmount
lowPrice?: CurrencyAmount
latestDateTime?: string
error?: SbiMethodError
}
export type SessionInfo = {
sessionId: string
loginType: LoginType
resultCode: string
}
export type AccountProfile = {
session: SessionInfo
branchCode?: string
butenCode?: string
accountNumber?: string
userId?: string
loginStatus?: LoginStatus
loginType?: LoginType
accountType?: AccountType
specificAccountType?: SpecificAccountType
hasMarginAccount?: boolean
marginAccount?: string
corporateFlag?: string
commissionPlan?: string
expireDate?: string
lastLoginDate?: string
lastLoginTime?: string
tradingPassword?: string
fxShareCol?: string
fullTerm?: string
fullAccount?: string
securityAuthenticationResponseCode?: string
fidoResponseCode?: string
passkeyStatus?: string
trId?: string
txId?: string
actionToken?: string
nisa?: {
enabled: boolean
tradePermitted?: boolean
juniorEnabled?: boolean
accountType?: IsaAccountType
jrNisaAccount?: string
jrNisaSpecific?: SpecificAccountType
jrNisaSeigen?: string
}
sor?: {
defaultEnabled?: boolean
defaultCode?: string
lastMarket?: MarketCode
juniorNisaLastMarket?: MarketCode
}
notices?: {
hasImportantNotice?: boolean
importantNoticeFlag?: string
count?: number
}
restrictions?: {
tradeRestricted?: boolean
restrictedTradeFlag?: string
message?: string
}
deficit?: {
hasMessage?: boolean
messageFlag?: string
message?: string
}
maintenance?: {
referenceable?: boolean
referenceableMaintenanceFlag?: string
}
}
export type BuyingPower = {
cashBuyingPower?: CurrencyAmount
marginBuyingPower?: CurrencyAmount
withdrawableAmount?: CurrencyAmount
collateralValue?: CurrencyAmount
collateralRatio?: PercentValue
sbiHybridDepositBalance?: CurrencyAmount
noticeMessage?: string
records?: CollateralRatioRecord[]
error?: SbiMethodError
}
export type CollateralRatioRecord = {
marginRequirements?: CurrencyAmount
referenceMarginRequirements?: CurrencyAmount
collateralRatioCash?: CurrencyAmount
substituteSecuritiesValuationAmount?: CurrencyAmount
unsettledPositionLoss?: SignedTextValue
unsettledPositionLossFlag?: string
settlementLoss?: SignedTextValue
settlementLossFlag?: string
paymentExpenses?: SignedTextValue
paymentExpensesFlag?: string
actualCollateral?: CurrencyAmount
positionAmount?: CurrencyAmount
sbiHybridDepositBalance?: CurrencyAmount
minimumCollateral?: CurrencyAmount
}
export type CashPosition = {
issue: IssueRef
accountType?: AccountType
depositType?: DepositType
depositTypeCode?: string
depositTypeText?: string
quantity: number | null
availableQuantity?: number | null
unexecutedOrderQuantity?: number | null
averagePrice?: CurrencyAmount
purchasePrice?: CurrencyAmount
/** Current unit price, not multiplied by quantity. */
currentPrice?: CurrencyAmount
priceText?: string
/** Total position valuation amount. For cash positions this is quantity-adjusted. */
marketValue?: CurrencyAmount
presentValueFlag?: string
/** Raw SBI valuation amount. Kept for source compatibility; prefer `marketValue` for totals. */
valuationPrice?: CurrencyAmount
valuationPriceChange?: SignedTextValue
valuationPriceChangeRate?: PercentValue
valuationPriceChangeFlag?: string
profitLoss?: SignedTextValue
profitLossRate?: PercentValue
profitLossFlag?: string
holdingCategory?: string
accountInformation?: string
}
export type CashPositionList = {
positions: CashPosition[]
index?: number
totalCount?: number
totalMarketValue?: CurrencyAmount
totalProfitLoss?: SignedTextValue
totalProfitLossRate?: PercentValue
totalProfitLossFlag?: string
hasMore?: boolean
error?: SbiMethodError
}
export type MarginPosition = {
id?: PositionId
issue: IssueRef
side: MarginTradeSide
sideText?: string
accountType?: AccountType
tradeKind?: string
quantity: number | null
availableCloseQuantity?: number | null
unexecutedOrderQuantity?: number | null
openPrice?: CurrencyAmount
openAmount?: CurrencyAmount
/** Current unit price or rate, not multiplied by quantity. */
currentPrice?: CurrencyAmount
rate?: CurrencyAmount
/** Total position valuation amount when provided by SBI. */
marketValue?: CurrencyAmount
presentValueFlag?: string
/** Raw SBI valuation amount. Prefer `marketValue` when calculating totals. */
valuationPrice?: CurrencyAmount
valuationPriceChange?: SignedTextValue
valuationPriceChangeRate?: PercentValue
valuationPriceChangeFlag?: string
profitLoss?: SignedTextValue
profitLossRate?: PercentValue
profitLossFlag?: string
openDate?: string
dueDate?: string
dueDateCode?: string
dueDateText?: string
depositTypeText?: string
cost?: CurrencyAmount
commission?: CurrencyAmount
managementFee?: CurrencyAmount
nameTransferFee?: CurrencyAmount
interest?: CurrencyAmount
backwardation?: CurrencyAmount
collateralRatio?: PercentValue
bargainMarketCode?: string
bargainMarket?: string
}
export type MarginPositionList = {
positions: MarginPosition[]
index?: number
totalCount?: number
totalMarketValue?: CurrencyAmount
totalProfitLoss?: SignedTextValue
totalProfitLossRate?: PercentValue
totalProfitLossFlag?: string
hasMore?: boolean
error?: SbiMethodError
}
export type ProfitLossSummary = {
cash?: SignedTextValue
margin?: SignedTextValue
total?: SignedTextValue
totalRate?: PercentValue
error?: SbiMethodError
}
export type Quote = {
issue: IssueRef
price?: CurrencyAmount
change?: SignedTextValue
changeRate?: PercentValue
changeFlag?: string
open?: CurrencyAmount
high?: CurrencyAmount
low?: CurrencyAmount
previousClose?: CurrencyAmount
volume?: number | null
timestamp?: string
nominalPrices?: CurrencyAmount[]
error?: SbiMethodError
}
export type BoardPriceLevel = {
price: CurrencyAmount
quantity?: number | null
}
export type Board = {
issue: IssueRef
bids: BoardPriceLevel[]
asks: BoardPriceLevel[]
quote?: Quote
error?: SbiMethodError
}
export type MarketIndex = {
code?: string
categoryCode?: string
name: string
value?: number | null
valueText?: string
change?: SignedTextValue
changeRate?: PercentValue
colorFlag?: string
timestamp?: string
open?: CurrencyAmount
high?: CurrencyAmount
low?: CurrencyAmount
previousClose?: CurrencyAmount
}
export type DomesticMarket = {
status?: string
indexes: MarketIndex[]
error?: SbiMethodError
}
export type RankingItem = {
rank: number
issue: IssueRef
value?: number | string | null
values?: Array<number | string | null>
change?: SignedTextValue
changeRate?: PercentValue
exchangeName?: string
colorFlag?: string
}
export type Ranking = {
items: RankingItem[]
category?: string
updatedAt?: string
error?: SbiMethodError
}
export type NewsItem = {
id?: string
title: string
source?: string
publishedAt?: string
url?: string
summary?: string
storyDate?: string
storyTime?: string
processedDate?: string
takeTime?: string
pnac?: string
}
export type NewsList = {
items: NewsItem[]
error?: SbiMethodError
}
export type WatchlistItem = {
issue: IssueRef
sortOrder?: number
memo?: string
quote?: Quote
}
export type Watchlist = {
id: WatchlistId
name: string
items: WatchlistItem[]
error?: SbiMethodError
}
export type Order = {
id: OrderId
issue: IssueRef
side: TradeSide
sideText?: string
status: OrderStatus
statusText?: string
executionStatus?: string
executionStatusText?: string
kind?: OrderKind
accountType?: AccountType
depositType?: DepositType
depositTypeCode?: string
depositTypeText?: string
quantity?: number | null
unexecutedQuantity?: number | null
executedQuantity?: number | null
price?: CurrencyAmount
executedPrice?: CurrencyAmount
orderedAt?: string
expiresAt?: string
orderNumber?: string
orderSubNo?: string
tradeId?: string
exchangeCode?: string
accountInformation?: string
cancelable?: boolean
correctable?: boolean
}
export type OrderList = {
orders: Order[]
hasMore?: boolean
error?: SbiMethodError
}
export type TradeRecord = {
id: string
issue: IssueRef
tradeRecordTypeCode?: string
tradeCurrencyCode?: string
listedSecuritiesStatus?: string
orderPriceKindCode?: string
accountType?: AccountType
settlementCurrencyCode?: string
amount?: CurrencyAmount
quantity?: number | null
price?: CurrencyAmount
tradeDate?: string
valueDate?: string
marginCloseLimitType?: string
}
export type TradeRecordList = {
records: TradeRecord[]
hasMore?: boolean
error?: SbiMethodError
}
export type OrderCorrectionPreOrderDetail = {
exchangeName?: string
marketLoanKbn?: string
marketIppanLoanKbn?: string
currentPrice?: CurrencyAmount
tradeColorFlag?: string
priceTick?: string
priceTickText?: string
tradeTime?: string
changeText?: string
volumeText?: string
}
export type OrderCorrectionPreOrder = {
issue: IssueRef
tradeTitle?: string
buyingPowerTotal?: CurrencyAmount
controlledStockCode?: string
hasTradeWarning?: boolean
deficitMessageFlag?: string
deficitMessage?: string
details: OrderCorrectionPreOrderDetail[]
orderNumber?: string
orderId?: string
primaryOrderMethod?: string
primaryTriggerZone?: string
primaryTriggerPrice?: number | null
status?: string
statusText?: string
tradeId?: string
tradeName?: string
quantity?: number | null
quantityText?: string
orderLimit?: string
orderLimitText?: string
priceSteps: StockOrderPreOrderPriceStep[]
sessionRange?: string
inputDateText?: string
primaryOrderTerm?: string
nonSpecificTradeText?: string
marketName?: string
rbeOrderStatus?: string
priceCondition?: string
price?: number | null
priceAmount?: CurrencyAmount
exchangeName?: string
transId?: string
ptsDayNightFlag?: string
smallTickFlag?: string
juniorBuyingPowerTotal?: CurrencyAmount
secondaryPriceCondition?: string
secondaryPrice?: number | null
secondaryPriceAmount?: CurrencyAmount
autoOrderKind?: string
autoOrderNumber?: string
autoOrderInputDate?: string
secondaryOrderMethod?: string
secondaryTriggerZone?: string
secondaryTriggerPrice?: number | null
secondaryOrderCondition?: string
secondaryLimitPrice?: number | null
secondaryLimitPriceAmount?: CurrencyAmount
secondaryOrderTerm?: string
secondaryOcoPriceCondition?: string
secondaryOcoPrice?: number | null
secondaryOcoPriceAmount?: CurrencyAmount
exchangeList?: string
}
export type OrderPreview = {
issue: IssueRef
side: TradeSide
quantity?: number
price?: CurrencyAmount
estimatedAmount?: CurrencyAmount
commission?: CurrencyAmount
tax?: CurrencyAmount
warnings: string[]
confirmationId?: string
message?: string
correction?: OrderCorrectionPreOrder
error?: SbiMethodError
}
export type StockOrderPreOrderPriceStep = {
from?: CurrencyAmount
to?: CurrencyAmount
}
export type StockOrderPreOrderPaymentLimit = {
text?: string
code?: string
}
export type StockOrderPreOrderMarginTradeType =
| 'standard'
| 'generalBuy'
| 'generalSellShort'
| 'generalSellInventoryLimited'
| 'generalSellInventoryUnlimited'
| 'day'
| 'hyper'
export type StockOrderPreOrder = {
issue: IssueRef
tradeTitle?: string
buyingPowerTotal?: CurrencyAmount
controlledStockCode?: string
hasTradeWarning?: boolean
market?: MarketCode
exchangeList?: string
exchangeListName?: string
exchangeListIndexFlag?: string
marketLoanKbn?: string
marketIppanLoanKbn?: string
currentPrice?: CurrencyAmount
tradeColorFlag?: string
priceTick?: string
priceTickText?: string
tradeTime?: string
changeText?: string
volume?: number | null
lotSize?: number | null
priceSteps: StockOrderPreOrderPriceStep[]
sessionRange?: string
basePrice?: CurrencyAmount
orderTerms: string[]
orderTermDates: string[]
paymentLimits: StockOrderPreOrderPaymentLimit[]
nonSpecificTradeText?: string
paymentLimitText?: string
acquisitionPrice?: CurrencyAmount
position?: number | null
unexecutedQuantity?: number | null
lotSize2?: number | null
ptsDayNightFlag?: string
sorServiceType?: string
nisa?: {
serviceKbn?: string
buyLimit?: CurrencyAmount
growthServiceKbn?: string
juniorServiceKbn?: string
juniorBuyLimit?: CurrencyAmount
juniorBuyingPowerTotal?: CurrencyAmount
}
smallTickFlag?: string
margin?: {
tradeTypes?: StockOrderPreOrderMarginTradeType[]
ippanShort?: string
ippanLong?: string
dayBuy?: string
daySell?: string
premiumShortSelling?: string
premiumFee?: CurrencyAmount
ippanPaymentLimit?: string
positionStatus?: string
}
sKabu?: {
code?: string
available?: boolean
}
deficitMessageFlag?: string
deficitMessage?: string
error?: SbiMethodError
}
export type OrderReceipt = {
accepted: boolean
orderId?: OrderId
acceptedAt?: string
message?: string
error?: SbiMethodError
}
export type ExchangeOrderSide = 'buy' | 'sell'
export type ExchangeSpecificMethod = 'foreign' | 'domestic'
export type ExchangeAccountKind = 'GENERAL' | 'JR_NISA'
export type ExchangeSellMethod = 'SELL_PART' | 'SELL_ALL'
export type ExchangeOrderPreview = {
currencyCode: string
currencyName?: string
side: ExchangeOrderSide
exchangeType?: string
accountKind?: ExchangeAccountKind
specificMethod?: ExchangeSpecificMethod
sellMethod?: ExchangeSellMethod | null
tradeQuantity?: string
orderAmount?: string
exchangeRate?: string
netAmount?: string
valueDate?: string
rateDateTime?: string
warningMessage?: string | null
isMaintenance?: boolean
csrfToken: string
}
export type ExchangeOrderReceipt = {
accepted: boolean
currencyCode?: string
side?: ExchangeOrderSide
message?: string
warningMessage?: string | null
rawTitle?: string
}
export type ExchangeRateInfo = {
currencyCode: string
side: ExchangeOrderSide
referenceExchangeRate?: string
computeExchangeRate?: string
basePrice?: string
exchangeTradeType?: string
updateTime?: string
buyPossibleAmount?: string
sellPossibleAmount?: string
buyUnit?: string
sellUnit?: string
buyLimitMin?: string
buyLimitMax?: string
sellLimitMin?: string
sellLimitMax?: string
raw: Record<string, unknown>
}
export type ThemeInvestment = {
id: ThemeId
name: string
issues: ThemeInvestmentIssue[]
minimumAmount?: CurrencyAmount
}
export type ThemeInvestmentIssue = IssueRef & {
controlledStockCode?: string
hasTradeWarning?: boolean
nisaServiceKbn?: string
juniorNisaServiceKbn?: string
growthNisaServiceKbn?: string
sKabuCode?: string
sKabuAvailable?: boolean
lotSize?: number | null
currentPrice?: CurrencyAmount
tradeColorFlag?: string
priceTick?: string
priceTickText?: string
tradeTime?: string
}
export type ThemeInvestmentList = {
themes: ThemeInvestment[]
buyingPowerTotal?: CurrencyAmount
isaBuyLimit?: CurrencyAmount
juniorNisaBuyLimit?: CurrencyAmount
buyingPowerTotalJuniorNisa?: CurrencyAmount
deficitMessage?: string
deficitMessageFlag?: string
error?: SbiMethodError
}
export type SbiMethodError = {
status?: string
code?: string
message?: string
}
+29
View File
@@ -0,0 +1,29 @@
{
"compilerOptions": {
// Environment setup & latest features
"lib": ["ESNext"],
"target": "ESNext",
"module": "Preserve",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
}
}