「あの時、なんでここで買ったんだっけ……?」、「あそこで売っていれば、利益が残ったのに……」
トレードを終えた後、こんな風に後悔したことはありませんか?
トレードの振り返りは、勝つために不可欠なステップです。
そこで今回、私は自作の株価分析ツールを改修し、チャート上に売買したポイント(緑の▲が買い、赤の▼が売り)を表示する機能を実装しました。
これにより、自分のトレードを「視覚的」に振り返り、課題を浮き彫りにすることが可能になりました。
本記事では、この「売買ポイント表示機能」の実装内容をまとめていきます。

この記事で作るもの
今回追加した機能はこちらです。
実装後のイメージは[緑▲:買い注文] [赤▼:売り注文]をテクニカルチャート上に表示しました。
さらに[RSI]、[移動平均線]、[ボリンジャーバンド]と合わせて確認できるようにしました。
※図内の売買タイミングは実際に売買したものではなくサンプルになります。
図1:完成したテクニカルチャート

なぜこの機能を作ったのか
今までは売買履歴とチャート分析は別画面で確認していました。
そのため、「どのテクニカル状況で入ったのか」、「どこで判断ミスしたのか」が非常に分かりづらかったです。
特に負けトレードほど[高値掴み]、[RSI過熱圏でのエントリー]、[損切り遅れ]などの傾向が見えてきます。
そこで「売買履歴をチャートへ直接表示したら分析しやすいのでは?」と思い、今回の機能追加を行いました。
今回の実装内容
今回、改修した内容は既に存在する[売買履歴]テーブルを利用して売買ポイントを表示するようにしました。



売買履歴テーブルの項目
売買履歴テーブルの主となる項目になります。
| テーブル名 | カラム名 | 型 | 説明 |
|---|---|---|---|
| TradeHistory (売買履歴) | trade_id | Integer | 外部キー(trade.id) |
| trade_date | Date | 売買が実行された日付 | |
| trade_type | String | [buy]:買い / [sell]:売り | |
| price | Float | 売買価格 | |
| quantity | Integer | 株数 |
改修したソースコード
実際に追加したコードを見ながら解説していきます。
※本記事では改修したコードのみを載せています。
サーバー側
監視銘柄一覧の「詳細」ボタン押下時に動く処理を改修しました。
(監視銘柄詳細画面に表示するためのデータを取得する処理)
- 売買履歴テーブルから該当銘柄の全ての売買履歴を取得
- マッピング用の辞書を作成
- グラフのX軸(dates)に合わせた売買価格リストを作成
- テンプレートに引き渡すデータを追加
@app.route('/detail/<symbol>/<int:serial_num>')
def detail(symbol, serial_num):
# 監視銘柄テーブルからデータ取得
stock = Watchlist.query.filter_by(symbol=symbol, serial_num=serial_num).first()
# 監視銘柄詳細テーブルからデータ取得
scores_data = WatchlistDetail.query.filter_by(symbol=symbol, serial_num=serial_num).order_by(WatchlistDetail.date.asc()).all()
# --- 移動平均線 RSI ボリンジャーバンドの取得・設定 既存処理
# ・・・割愛 ・・・
# ==========================================
# ▼ 今回追加:売買履歴データの取得とグラフ用マッピング ▼
# ==========================================
# ① 売買履歴テーブルから該当銘柄の全ての売買履歴を取得
trade_histories = TradeHistory.query.join(Trade).filter(Trade.symbol == symbol).all()
# ② マッピング用の辞書を作成 { 'YYYY-MM-DD': {'buy': price, 'sell': price, 'memo': '...'} }
trade_map = {}
for h in trade_histories:
d_str = h.trade_date.strftime('%Y-%m-%d')
if d_str not in trade_map:
trade_map[d_str] = {'buy': None, 'sell': None, 'memo': ''}
trade_map[d_str][h.trade_type] = h.price
if h.memo:
trade_map[d_str]['memo'] += f"[{h.trade_type.upper()}] {h.memo} "
# ③ グラフのX軸(dates)に合わせた売買価格リストを作成
buy_prices = []
sell_prices = []
buy_texts = []
sell_texts = []
for d in dates:
if d in trade_map:
buy_prices.append(trade_map[d]['buy']) # ない場合は None が入る
sell_prices.append(trade_map[d]['sell'])
buy_texts.append(trade_map[d]['memo'] if trade_map[d]['buy'] else '')
sell_texts.append(trade_map[d]['memo'] if trade_map[d]['sell'] else '')
else:
buy_prices.append(None)
sell_prices.append(None)
buy_texts.append('')
sell_texts.append('')
# ================▲ 今回追加 ▲========================
return render_template('detail.html',
stock=stock, scores=scores_data,
dates=dates, prices=prices, sma5=sma5, sma25=sma25, rsi=rsi,
bb_up2=bb_up2, bb_up1=bb_up1, bb_low1=bb_low1, bb_low2=bb_low2,
buy_prices=buy_prices, sell_prices=sell_prices,
buy_texts=buy_texts, sell_texts=sell_texts) # ④ 今回追加テンプレート側(スクリプト)
テンプレート側のテクニカルチャート作成処理に売買ポイントの印を表示する処理を追加しました。
// ==========================================
// 追加:売買の印
// ==========================================
const traceBuy = { x: dates, y: {{ buy_prices|tojson }}, name: '買い注文', type: 'scatter', mode: 'markers', text: {{ buy_texts|tojson }},
marker: { symbol: 'triangle-up', size: 15, color: '#2ca02c', line: { color: '#ffffff', width: 1 }}};
const traceSell = { x: dates, y: {{ sell_prices|tojson }}, name: '売り注文', type: 'scatter', mode: 'markers', text: {{ sell_texts|tojson }},
marker: { symbol: 'triangle-down', size: 15, color: '#d62728', line: { color: '#ffffff', width: 1 }}};
// ==========================================実際に使ってみた感想
実際に表示してみると、かなり分析しやすくなりました!
自分が設定した売買ルールに合ったタイミングでエントリーまたはエグジットしているのかが一目で分かるようになりました。
特に「負けた理由」が視覚的に分かるのが大きいです。
まとめ
今回は、Flask × Plotly で作成している株価分析ツールへ、「売買ポイント表示機能」を追加しました。
単にチャートを見るだけでなく「なぜそこで買ったのか」、「なぜ負けたのか」、「どの判断が悪かったのか」などを振り返りやすくなり、かなり分析しやすくなりました。
今後は「記録するだけ」ではなく「改善につながる分析ツール」としてさらに強化していきたいと思います。
【投資に関する免責事項】
本ブログで紹介している株価解析ツールによるスコアリングおよび銘柄分析は、あくまで個人の学習・研究および技術検証を目的としたものであり、特定の銘柄の売買を推奨するものではありません。
ツールの算出結果や掲載情報の正確性については万全を期しておりますが、その内容を保証するものではありません。投資の最終決定は、必ずご自身の判断と責任において行っていただきますようお願いいたします。
万一、本ブログの情報に基づいて被ったいかなる損害についても、当サイトおよび運営者は一切の責任を負いかねますのであらかじめご了承ください。








