ポートフォリオ可視化スクリプト(1) - 配当月一覧-

  • ポートフォリオの配当月を表示するスクリプト.

ソースコード

dividend__month.py

import os, sys, json5, jinja2, shutil
import yfinance as yf
import pandas   as pd

# ========================================================= #
# ===  dividend__month.py                               === #
# ========================================================= #

def dividend__month():

    # ------------------------------------------------- #
    # --- [1] load settings.json                    --- #
    # ------------------------------------------------- #
    settingFile  = "dat/settings.json"
    with open( settingFile, "r" ) as f:
        params   = ( json5.load( f ) )
        tickers      = params["tickers"]
        slist        = pd.read_csv( "dat/jpx_stock.csv", encoding="utf-8" )
        ticker_dict  = {}
    for ticker in tickers:
        nmatch   = slist[ slist["コード"] == ticker.strip( ".T" ) ]
        if ( not( nmatch.empty ) ):
            ticker_dict[ticker] = ( nmatch.iloc[0]["銘柄名"] ).strip()

    # ------------------------------------------------- #
    # --- [2] 配当月を調査                          --- #
    # ------------------------------------------------- #
    month_to_tickers = {i: [] for i in range(1, 13)}
    for code, name in ticker_dict.items():
        ticker    = yf.Ticker(code)
        dividends = ticker.dividends
        months    = dividends.index.month.unique()
        for month in months:
            if name not in month_to_tickers[month]:
                month_to_tickers[month].append(name)
            
    # ------------------------------------------------- #
    # --- [3] 月ラベルを付けてJinja2用に整形        --- #
    # ------------------------------------------------- #
    month_labels = {
        1: "1月", 2: "2月", 3: "3月", 4:  "4月",  5: "5月",   6: "6月",
        7: "7月", 8: "8月", 9: "9月", 10: "10月", 11: "11月", 12: "12月"
    }
    
    table_data = [
        {"month": month_labels[m], "names": month_to_tickers[m]}
        for m in range(1, 13)
    ]

    # ------------------------------------------------- #
    # --- [4] Jinja2テンプレートでHTML出力         --- #
    # ------------------------------------------------- #
    env           = jinja2.Environment( loader=jinja2.FileSystemLoader("templates") )
    template      = env.get_template( "month_template.html" )
    
    rendered_html = template.render(
        title     ="配当月カレンダー",
        table     = table_data,
        css_path  ="custom.css"
    )

    htmlFile = "html/month.html"
    with open(htmlFile, "w", encoding="utf-8") as f:
        f.write( rendered_html )
        print(" output :: {}".format( htmlFile) )
        
    shutil.copy( "templates/custom.css", "html/" )


# ========================================================= #
# ===   Execution of Pragram                            === #
# ========================================================= #

if ( __name__=="__main__" ):
    dividend__month()

settings.json

{
    "rangecheck": {
        "dividend.yield"   : { "name": "配当利回り (%)"           , "min":3.5,   "max":5.5,  }, 
        "dividend.ratio"   : { "name": "配当性向 (%)"             , "min":10.0,  "max":50.0, }, 
        "oprIncome"        : { "name": "営業利益率 (%)"           , "min":10.0,  "max":null, },
        "PER"              : { "name": "PER"                      , "min":5.0,   "max":15.0, }, 
        "PBR"              : { "name": "PBR"                      , "min":0.5,   "max":1.5,  },
        "ROE"              : { "name": "ROE (%)"                  , "min":8.0,   "max":null, },
        "ROA"              : { "name": "ROA (%)"                  , "min":5.0,   "max":null, },
        "equityRatio"      : { "name": "自己資本比率 (%)"         , "min":50.0,  "max":null, }, 
        "currentRatio"     : { "name": "流動比率 (%)"             , "min":200.0, "max":null, }, 
        "cashRatio"        : { "name": "現金比率 (%)"             , "min":30.0,  "max":null, }, 
        "debtRatio.ebitda" : { "name": "EBITDA有利子負債倍率(倍)" , "min":null,  "max":3.0,  },
        "debtRatio.equity" : { "name": "有利子負債倍率 (%)"       , "min":null,  "max":200,  }, 
    },

    "increment": {
        "revenues.inc"  : { "name":"売上高 (億円)"   }, 
        "oprIncome.inc" : { "name":"営業利益 (億円)" }, 
        "netIncome.inc" : { "name":"純利益 (億円)"   }, 
        "EPS.inc"       : { "name":"EPS (円)"        }, 
        "dividend.inc"  : { "name":"1株配当 (円)"   }, 
    }, 

    // "tickers": [
    //     "8593", 
    // ], 
    "tickers": [
        "2169", "2267", "2914", "3076", "3479", "3763", "3817", "4008",
        "4752", "4928", "5020", "5108", "5192", "5334", "5388", "5401",
        "5464", "5589", "6113", "6247", "6268", "6301", "7247", "7820",
        "7921", "7994", "7995", "8002", "8053", "8058", "8316", "8411",
        "8424", "8425", "8439", "8584", "8593", "8898", "9432", "9433",
        "9513", "9795", "9799", "9986", "1605", "6501", 
    ],
    "owns": [
        "2169", "2267", "2914", "3076", "3479", "3763", "3817", "4008",
        "4752", "4928", "5020", "5108", "5192", "5334", "5388", "5401",
        "5464", "5589", "6113", "6268", "6301", "7247", "7820",
        "7921", "7994", "7995", "8002", "8053", "8058", "8316", "8411",
        "8424", "8425", "8439", "8584", "8593", "8898", "9432", "9433",
        "9513", "9795", "9799", "9986", "1605", "6501", 
    ],
    
    "settings":{
        "mode"            : "all"                       ,   // "all", "select"
        "skip"            : false                       ,   // whether skip or not.
        "div.yield.min"   : 3.0                         ,   // minimum dividend rate
        "cssFile"         : "templates/custom.css"      , 
        "databaseFile"    : "dat/database.json"         ,
        "tickersFile"     : "dat/jpx_tickers.csv"       ,
        "filteredFile"    : "dat/filtered_tickers.csv"  ,
        "markets"         : [ "プライム(内国株式)", "スタンダード(内国株式)" ] , 
        // [ "プライム(内国株式)", "スタンダード(内国株式)", "グロース(内国株式)" ], 
        "html.fancy"      : "html/fancy_table.html"     , 
        "html.screening"  : "html/screening_table.html" , 
        "template.detail" : "fancy_table.j2.html"       , 
        "template.table"  : "screening_table.j2.html"   , 
        "nyears"          : 15                          ,
        "nParallels"      : 4                           , 
        "sort"            : true                        , 
    },

    
}

month_template.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
    <link rel="stylesheet" href="{{ css_path }}">
</head>
<body>
    <h2>{{ title }}</h2>
    <table class="styled-table">
        <thead>
            <tr>
                <th class="month-col">月</th>
                <th class="name-col">配当銘柄</th>
            </tr>
        </thead>
        <tbody>
            {% for row in table %}
            <tr>
                <td>{{ row.month }}</td>
                <td>
                    <ul>
                        {% for name in row.names %}
                        <li>{{ name }}</li>
                        {% endfor %}
                    </ul>
                </td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
</body>
</html>

custom.css

/************************************
 ** 比較表 全体レイアウト(3列対応)
 ************************************/
.compare-box {
    display: flex;
    max-width: 1200px;
    margin: 0 auto 2rem;
    border-radius: 4px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .2);
    background: #fef9ed;
    flex-wrap: nowrap;
}

/* 各列共通 */
.compare-left-wrap {
    width: 50.0%;
    overflow: hidden;
}
.compare-middle-wrap {
    width: 35.0%;
    overflow: hidden;
}
.compare-right-wrap {
    width: 15.0%;
    overflow: hidden;
}

/************************************
 ** 各列のタイトル(修正)
 ************************************/
.compare-left-head,
.compare-middle-head,
.compare-right-head {
    background: #1f3b5b;
    color: #fff;
    font-weight: bold;
    font-size: 15px;
    height: 65px;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    padding: 0 1em;
}

.compare-left-head   { border-radius: 4px 0 0 0; }
.compare-right-head  { border-radius: 0 4px 0 0; }

/************************************
 ** 判定のマーク(◎ / ✗)色付け
 ************************************/
.check-true {
    color: green;
    font-weight: bold;
}
.check-false {
    color: red;
    font-weight: bold;
}


/************************************
 ** 各列の本文
 ************************************/
.compare-left,
.compare-middle,
.compare-right {
    padding: 1.5em;
    font-size: 15px;
    line-height: 2;
    text-align: justify;
    text-justify: inter-ideograph;
}

/************************************
 ** 左列:番号付きリスト(項目名)
 ************************************/
.compare-box .list-number {
    counter-reset: number;
    list-style: none !important;
    padding: 0 !important;
    margin: 0 !important;
    border: none !important;
}
.compare-box .list-number li {
    position: relative;
    margin: 0 !important;
    padding: 0.5em 0 0.5em 2em !important;
    line-height: 1.8;
    border-bottom: 1px dashed #cdcdcd;
}
.compare-box .list-number li:before {
    counter-increment: number;
    content: counter(number);
    background-color: #1f3b5b;
    color: #fff;
    position: absolute;
    font-weight: bold;
    font-size: 12px;
    border-radius: 50%;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 18px;
    height: 18px;
    line-height: 18px;
    text-align: center;
}
.compare-box .list-number li:last-child {
    border: none;
}

/************************************
 ** 中・右列:記号なしリスト(値・判定)
 ************************************/
.list-no-bullet {
    list-style: none !important;
    padding: 0 !important;
    margin: 0 !important;
    border: none !important;
}
.list-no-bullet li {
    padding: 0.5em 0 0.5em 2em !important;
    margin: 0 !important;
    border-bottom: 1px dashed #cdcdcd;
    line-height: 1.8;
}
.list-no-bullet li:last-child {
    border: none;
}


/************************************
 ** マーク ◎ / x 
 ************************************/


.check-icon-true::before {
    content: "✔";
    display: inline-block;
    background-color: #d4f4dd; /* 薄緑 */
    color: #1a7f37; /* 濃い緑 */
    font-weight: bold;
    border-radius: 50%;
    width: 24px;
    height: 24px;
    line-height: 24px;
    text-align: center;
    font-size: 14px;
    box-shadow: 0 0 2px rgba(0,0,0,0.2);
}
.check-icon-false::before {
    content: "✘";
    display: inline-block;
    background-color: #fde2e2; /* 薄赤 */
    color: #d32f2f; /* 濃い赤 */
    font-weight: bold;
    border-radius: 50%;
    width: 24px;
    height: 24px;
    line-height: 24px;
    text-align: center;
    font-size: 14px;
    box-shadow: 0 0 2px rgba(0,0,0,0.2);
}

.compare-left-head,
.compare-middle-head,
.compare-right-head {
    background: #1f3b5b;
    color: #fff;
    font-weight: bold;
    font-size: 15px;
    height: 65px;
    display: flex;
    justify-content: center;
    align-items: center;
    flex: 1;
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

.compare-left-head   { border-radius: 4px 0 0 0; }
.compare-middle-head { border-radius: 0 0 0 0; }  /* 明示的に入れる */
.compare-right-head  { border-radius: 0 4px 0 0; }


/* ---------------------------------------------- */
/* --- month.py                               --- */
/* ---------------------------------------------- */
/* 表全体 */
.styled-table {
    border-collapse: collapse;
    margin: 20px auto;
    font-size: 1em;
    width: 90%;
    border: 1px solid #1f355e; /* 紺色の枠線 */
    background-color: #ffffff; /* 白背景 */
    text-align: left;
}

/* セル共通 */
.styled-table th,
.styled-table td {
    border: 1px solid #1f355e; /* 紺色の枠線 */
    padding: 8px;
    vertical-align: top;
}

/* ヘッダー */
.styled-table th {
    background-color: #1f355e; /* 紺色背景 */
    color: white;              /* 白文字 */
}

/* 奇数行背景(白に統一したい場合はこれを削除してOK) */
.styled-table tr:nth-child(even) {
    background-color: #ffffff; /* 背景は白に */
}

/* 列幅と左寄せ */
.month-col {
    width: 20%;
    text-align: left;
}

.name-col {
    width: 80%;
    text-align: left;
}

/* 箇条書きのスタイル */
.name-col ul {
    margin: 0;
    padding-left: 1em;
}

.name-col li {
    margin-bottom: 0.3em;
}

出力

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>配当月カレンダー</title>
    <link rel="stylesheet" href="custom.css">
</head>
<body>
    <h2>配当月カレンダー</h2>
    <table class="styled-table">
        <thead>
            <tr>
                <th class="month-col">月</th>
                <th class="name-col">配当銘柄</th>
            </tr>
        </thead>
        <tbody>
            
            <tr>
                <td>1月</td>
                <td>
                    <ul>
                        
                    </ul>
                </td>
            </tr>
            
            <tr>
                <td>2月</td>
                <td>
                    <ul>
                        
                    </ul>
                </td>
            </tr>
            
            <tr>
                <td>3月</td>
                <td>
                    <ul>
                        
                        <li>ヤクルト本社</li>
                        
                        <li>日本たばこ産業</li>
                        
                        <li>プロシップ</li>
                        
                        <li>SRAホールディングス</li>
                        
                        <li>住友精化</li>
                        
                        <li>昭和システムエンジニアリング</li>
                        
                        <li>ENEOSホールディングス</li>
                        
                        <li>三ツ星ベルト</li>
                        
                        <li>日本特殊陶業</li>
                        
                        <li>クニミネ工業</li>
                        
                        <li>日本製鉄</li>
                        
                        <li>モリ工業</li>
                        
                        <li>アマダ</li>
                        
                        <li>日阪製作所</li>
                        
                        <li>ナブテスコ</li>
                        
                        <li>小松製作所</li>
                        
                        <li>ミクニ</li>
                        
                        <li>ニホンフラッシュ</li>
                        
                        <li>オカムラ</li>
                        
                        <li>バルカー</li>
                        
                        <li>丸紅</li>
                        
                        <li>住友商事</li>
                        
                        <li>三菱商事</li>
                        
                        <li>三井住友フィナンシャルグループ</li>
                        
                        <li>みずほフィナンシャルグループ</li>
                        
                        <li>芙蓉総合リース</li>
                        
                        <li>みずほリース</li>
                        
                        <li>東京センチュリー</li>
                        
                        <li>ジャックス</li>
                        
                        <li>三菱HCキャピタル</li>
                        
                        <li>センチュリー21・ジャパン</li>
                        
                        <li>日本電信電話</li>
                        
                        <li>KDDI</li>
                        
                        <li>電源開発</li>
                        
                        <li>ステップ</li>
                        
                        <li>旭情報サービス</li>
                        
                        <li>蔵王産業</li>
                        
                    </ul>
                </td>
            </tr>
            
            <tr>
                <td>4月</td>
                <td>
                    <ul>
                        
                    </ul>
                </td>
            </tr>
            
            <tr>
                <td>5月</td>
                <td>
                    <ul>
                        
                        <li>TAKARA & COMPANY</li>
                        
                    </ul>
                </td>
            </tr>
            
            <tr>
                <td>6月</td>
                <td>
                    <ul>
                        
                        <li>CDS</li>
                        
                        <li>日本たばこ産業</li>
                        
                        <li>あい ホールディングス</li>
                        
                        <li>ブリヂストン</li>
                        
                        <li>ナブテスコ</li>
                        
                    </ul>
                </td>
            </tr>
            
            <tr>
                <td>7月</td>
                <td>
                    <ul>
                        
                    </ul>
                </td>
            </tr>
            
            <tr>
                <td>8月</td>
                <td>
                    <ul>
                        
                    </ul>
                </td>
            </tr>
            
            <tr>
                <td>9月</td>
                <td>
                    <ul>
                        
                        <li>ヤクルト本社</li>
                        
                        <li>日本たばこ産業</li>
                        
                        <li>SRAホールディングス</li>
                        
                        <li>住友精化</li>
                        
                        <li>ノエビアホールディングス</li>
                        
                        <li>ENEOSホールディングス</li>
                        
                        <li>三ツ星ベルト</li>
                        
                        <li>日本特殊陶業</li>
                        
                        <li>クニミネ工業</li>
                        
                        <li>日本製鉄</li>
                        
                        <li>モリ工業</li>
                        
                        <li>アマダ</li>
                        
                        <li>日阪製作所</li>
                        
                        <li>ナブテスコ</li>
                        
                        <li>小松製作所</li>
                        
                        <li>ミクニ</li>
                        
                        <li>ニホンフラッシュ</li>
                        
                        <li>オカムラ</li>
                        
                        <li>バルカー</li>
                        
                        <li>丸紅</li>
                        
                        <li>住友商事</li>
                        
                        <li>三菱商事</li>
                        
                        <li>三井住友フィナンシャルグループ</li>
                        
                        <li>みずほフィナンシャルグループ</li>
                        
                        <li>芙蓉総合リース</li>
                        
                        <li>みずほリース</li>
                        
                        <li>東京センチュリー</li>
                        
                        <li>ジャックス</li>
                        
                        <li>三菱HCキャピタル</li>
                        
                        <li>センチュリー21・ジャパン</li>
                        
                        <li>日本電信電話</li>
                        
                        <li>KDDI</li>
                        
                        <li>電源開発</li>
                        
                        <li>ステップ</li>
                        
                        <li>旭情報サービス</li>
                        
                        <li>蔵王産業</li>
                        
                    </ul>
                </td>
            </tr>
            
            <tr>
                <td>10月</td>
                <td>
                    <ul>
                        
                    </ul>
                </td>
            </tr>
            
            <tr>
                <td>11月</td>
                <td>
                    <ul>
                        
                        <li>TAKARA & COMPANY</li>
                        
                    </ul>
                </td>
            </tr>
            
            <tr>
                <td>12月</td>
                <td>
                    <ul>
                        
                        <li>CDS</li>
                        
                        <li>日本たばこ産業</li>
                        
                        <li>あい ホールディングス</li>
                        
                        <li>ブリヂストン</li>
                        
                        <li>オートサーバー</li>
                        
                        <li>ナブテスコ</li>
                        
                    </ul>
                </td>
            </tr>
            
        </tbody>
    </table>
</body>
</html>