AllTick
米国株フラクショナル株(Fractional Shares)取引ルールとシステム実装完全解析(Java / Python / TypeScript コード例付き)
ブログ

米国株フラクショナル株(Fractional Shares)取引ルールとシステム実装完全解析(Java / Python / TypeScript コード例付き)

一、フラクショナル株とは 米国株のフラクショナル株とは、投資家が株やETFを整数株単位に限定されず、小数株単位で購入できる仕組みです。典型的には最小取引単位 0.0001 株まで対応し、多くの証券会社では「金額指定」注文 […]

AllTick読了 3 分

一、フラクショナル株とは

米国株のフラクショナル株とは、投資家が株や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();
}
}

七、実装ステップまとめ

  1. データモデル統一

    銘柄:fractionableminFractionQty



    口座:canFractionalcanShortcanMargin

  2. 注文フロー改修

    qty / notional 対応



    小数精度対応



    timeInForce=DAY 強制

  3. リスク管理

    銘柄・口座能力チェック



    空売り禁止



    最小数量・金額チェック

  4. 清算・報告

    内部8~10桁小数



    FINRA報告6桁小数に変換

  5. 配当・企業行動対応

    配当再投資(DRIP)



    株式分割・併合対応

これらのプロセスがすべて整備されれば、あなたのシステムは米国株のフラクショナル株取引をスムーズにサポートできるようになり、複数の証券会社(または自前のマッチングシステム)との接続にも対応可能になります。

今すぐマーケットデータ配信を開始

数秒で無料 API キーを発行し、1 つのエンドポイントからすべての市場に接続できます。