
一、フラクショナル株とは
米国株のフラクショナル株とは、投資家が株やETFを整数株単位に限定されず、小数株単位で購入できる仕組みです。
典型的には最小取引単位 0.0001 株まで対応し、多くの証券会社では「金額指定」注文も可能です。
例:5ドルで特定株を購入 → 少額から大手株に投資可能。
開発者目線では、取引・リスク管理・清算・レポート全ての処理で小数株や金額指定注文に対応する必要があります。
二、主要ルール(開発視点)
1. 注文方法
- 株数指定(qty):小数可(例:0.1株、0.0001株)
- 金額指定(notional):購入金額で指定(例:10ドルで購入)
互いに排他:同時指定不可
2. 注文種別・有効期限
- 初期は「成行 + 通常取引時間」のみ
- 後に「指値/ストップ/前場・後場」対応拡張あり
- DAY のみ有効(GTC/IOC/FOK 不可)
3. 対象銘柄
- 全銘柄対応ではない
- 流動性高く個人投資家参加率が高い銘柄が中心
fractionableフラグで判定可能
4. 最小数量・最小金額
- 最小株数:0.0001 株
- 最小注文額:1~5 USD
5. 空売り・証拠金
- 多くの口座でフラクション株空売り不可
- 証拠金ルールは整数株と同等、保守的評価のケースあり
6. 株主権利・配当
- 配当:保有株数按分
- DRIP:フラクション株で再投資可能
- 株式分割・併合:株数比例調整、価格変動に対応
7. 清算・報告
- FINRA/SEC対応で数量小数位対応
- 内部8~10桁小数 → 報告時6桁小数に整形
三、API設計と注文モデル(TypeScript例)
export interface FractionalOrderRequest { // alltick.co
symbol: string; // 銘柄コード
side: "buy" | "sell"; // 売買
type: "market" | "limit" | "stop" | "stop_limit";
timeInForce: "day"; // 有効期限
qty?: string; // 株数、小数対応
notional?: string; // 金額指定注文
limitPrice?: string; // 指値
extendedHours?: boolean; // 前場/後場対応
}
// バリデーション例
function validateFractionalOrder(req: FractionalOrderRequest) {
const hasQty = !!req.qty;
const hasNotional = !!req.notional;
if (hasQty === hasNotional) throw new Error("qtyかnotionalのどちらか一方を指定してください");
if (req.timeInForce !== "day") throw new Error("フラクショナル株注文はtimeInForce=dayのみ");
if (["limit","stop","stop_limit"].includes(req.type) && !req.limitPrice) {
throw new Error(`${req.type}注文はlimitPriceが必要`);
}
const checkPrecision = (v: string, field: string) => {
if (!/^\d+(\.\d{1,6})?$/.test(v)) throw new Error(`${field}は最大6桁小数まで`);
};
if (req.qty) checkPrecision(req.qty, "qty");
if (req.notional) checkPrecision(req.notional, "notional");
if (req.limitPrice) checkPrecision(req.limitPrice, "limitPrice");
}
四、Javaバックエンド例
1. DTO
public class FractionalOrderRequest {
private String symbol;
private Side side;
private OrderType type;
private TimeInForce timeInForce;
private String qty;
private String notional;
private String limitPrice;
private Boolean extendedHours;
public enum Side { BUY, SELL }
public enum OrderType { MARKET, LIMIT, STOP, STOP_LIMIT }
public enum TimeInForce { DAY, GTC, IOC }
}
2. 注文バリデーション
import java.math.BigDecimal;
import java.util.Objects;
public class FractionalOrderValidator {
public static void validate(FractionalOrderRequest req) {
Objects.requireNonNull(req.getSymbol(), "symbolは必須");
Objects.requireNonNull(req.getSide(), "sideは必須");
Objects.requireNonNull(req.getType(), "typeは必須");
Objects.requireNonNull(req.getTimeInForce(), "timeInForceは必須");
boolean hasQty = req.getQty() != null && !req.getQty().isEmpty();
boolean hasNotional = req.getNotional() != null && !req.getNotional().isEmpty();
if (hasQty == hasNotional) throw new IllegalArgumentException("qtyかnotionalのどちらか一方を指定");
if (req.getTimeInForce() != FractionalOrderRequest.TimeInForce.DAY)
throw new IllegalArgumentException("フラクショナル株はDAYのみ");
switch(req.getType()) {
case LIMIT:
case STOP:
case STOP_LIMIT:
if (req.getLimitPrice() == null) throw new IllegalArgumentException("limitPrice必須");
}
checkScale(req.getQty(), "qty", 6);
checkScale(req.getNotional(), "notional", 6);
checkScale(req.getLimitPrice(), "limitPrice", 6);
if (hasQty && new BigDecimal(req.getQty()).compareTo(new BigDecimal("0.0001")) < 0)
throw new IllegalArgumentException("最小フラクション株0.0001");
if (hasNotional && new BigDecimal(req.getNotional()).compareTo(new BigDecimal("1")) < 0)
throw new IllegalArgumentException("最小注文金額1USD");
}
private static void checkScale(String value, String field, int scale) {
if(value == null) return;
BigDecimal bd = new BigDecimal(value);
if (bd.scale() > scale) throw new IllegalArgumentException(field+"は最大"+scale+"桁小数");
if (bd.signum() <= 0) throw new IllegalArgumentException(field+"は正の値");
}
}
五、Python例:配当計算
from decimal import Decimal, ROUND_HALF_UP
def calc_dividend(position_shares: str, dividend_per_share: str) -> Decimal:
pos = Decimal(position_shares)
div = Decimal(dividend_per_share)
return (pos * div).quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP)
# 使用例
print(calc_dividend("0.25", "0.10")) # 0.0250
六、清算・報告ユーティリティ(Java)
import java.math.BigDecimal;
import java.math.RoundingMode;
public class ReportingUtil {
public static BigDecimal normalizeInternalQty(BigDecimal qty) {
return qty.setScale(8, RoundingMode.HALF_UP);
}
public static String toFinraFractionalQty(BigDecimal qty) {
return qty.setScale(6, RoundingMode.DOWN).toPlainString();
}
public static int toLegacyWholeShares(BigDecimal qty) {
if(qty.compareTo(BigDecimal.ONE) < 0) return 1;
return qty.setScale(0, RoundingMode.DOWN).intValueExact();
}
}
七、実装ステップまとめ
- データモデル統一
- 銘柄:
fractionable、minFractionQty - 口座:
canFractional、canShort、canMargin
- 銘柄:
- 注文フロー改修
- qty / notional 対応
- 小数精度対応
- timeInForce=DAY 強制
- リスク管理
- 銘柄・口座能力チェック
- 空売り禁止
- 最小数量・金額チェック
- 清算・報告
- 内部8~10桁小数
- FINRA報告6桁小数に変換
- 配当・企業行動対応
- 配当再投資(DRIP)
- 株式分割・併合対応
これらのプロセスがすべて整備されれば、あなたのシステムは米国株のフラクショナル株取引をスムーズにサポートできるようになり、複数の証券会社(または自前のマッチングシステム)との接続にも対応可能になります。


