PythonとCoinGecko APIで学ぶ仮想通貨価格監視プロジェクト

目次

プロジェクト概要

前提条件

  • Pythonプログラミングの基本的な知識(変数、関数、クラスの概念)
  • VSCodeエディタの基本操作ができること
  • ターミナル(コマンドライン)の基本的な使用経験
  • Gitとバージョン管理の基礎知識
  • JSONデータ形式に関する基本的な理解

開発環境

  • Python 3.7以上
  • VSCode(Visual Studio Code)
  • Git(バージョン管理システム)
  • GitHubアカウント
  • インターネット接続(API通信のため)
  • requests 2.32.3

プロジェクト内容

このプロジェクトでは、PythonのrequestsライブラリとCoinGecko APIを使用して、仮想通貨の価格をリアルタイムで監視するシステムを構築します。初心者でも段階的に学習できるよう、基本的な環境設定から高度な統計分析機能まで、5つのステップに分けて実装していきます。

プロジェクトの核となるのは、HTTP通信技術を使用したAPI連携です。CoinGecko APIから取得したJSONデータを解析し、複数の仮想通貨価格を効率的に監視できるシステムを開発します。これにより、実際の金融データを扱う経験を積むことができます。

データ処理においては、取得した価格情報を辞書構造で管理し、価格変動の検知や統計情報の計算を行います。単純なデータ取得にとどまらず、カラー表示による視覚化や履歴管理機能も実装し、ユーザビリティの高いシステムを作成します。

プロジェクトの特徴として、API制限への対応やネットワークエラーハンドリングを重視した安定性の高いシステム設計を採用しています。実際のAPI連携では、レート制限や接続エラーなど、様々な予期しない事態が発生する可能性があります。そのため、適切な例外処理を実装し、エラーが発生しても処理が継続できるよう設計されています。

また、リアルタイム監視機能では、価格変動があった場合のみ表示を更新する効率的な仕組みを実装します。これにより、不要な通信を削減し、API制限内での安定した動作を実現します。同時に、監視データのログ出力機能も提供し、後から分析できる形でデータを保存します。

開発プロセスでは、オブジェクト指向プログラミングの概念を活用し、CryptoPriceTrackerクラスを中心とした構造化されたコード設計を採用します。各機能を独立したメソッドとして実装することで、コードの可読性と保守性を向上させ、将来的な機能拡張も容易に行えるようになります。

実装内容

  • CoinGecko APIとの連携設定とHTTPリクエスト処理
  • 仮想環境の構築と依存関係管理(requirements.txt)
  • CryptoPriceTrackerクラスの設計と実装
  • JSONデータの解析と価格情報抽出ロジック
  • 複数通貨の同時監視システム
  • 価格変動検知とリアルタイム表示機能
  • カラー表示による視覚化システム
  • 統計情報計算機能(平均価格、最高価格、最低価格)
  • エラーハンドリングとAPI制限対応
  • GitHubでのバージョン管理とポートフォリオ公開

得られるスキル

  • HTTP通信とAPI連携(requestsライブラリの活用)
  • JSONデータ処理(辞書とリストを使った構造化データの操作)
  • リアルタイム処理(継続的なデータ監視システムの構築)
  • エラーハンドリング(例外処理とシステム安定性の向上)
  • データ可視化(ANSIカラーコードを使った表示制御)

得られる経験

  • 外部APIを使用したデータ取得経験
  • 金融データの処理と分析手法の習得
  • リアルタイムシステムの開発経験
  • プロジェクト管理の基本的な流れの理解
  • GitHubを使用したバージョン管理の実践的経験

得られる成果物

  • 完全に動作する仮想通貨価格監視システム
  • GitHubでのポートフォリオとして活用可能なプロジェクト
  • 再利用可能なPythonソースコード
  • 詳細なドキュメント(README.md)
  • API連携の実践的な知識

Step1:開発環境の準備とプロジェクト構造の作成

このステップでは、仮想通貨価格リアルタイム監視プロジェクトを始めるための開発環境を整備し、必要なファイル構造を作成していきます。プログラミングを始める前の準備段階として、とても重要な作業になります。

GitHubとVSCodeの連携についてわからない際は、下記記事をご参照ください。

GitHubリポジトリの作成

まず最初に、プロジェクト専用のGitHubリポジトリを作成しましょう。

  1. GitHubの公式サイトにアクセスし、自分のアカウントでログインします
  2. 画面右上の「+」アイコンをクリックし、ドロップダウンメニューから「New repository」を選択します
  3. 新しいリポジトリの作成ページで、以下の情報を入力します

リポジトリの設定

  • Repository namecrypto_price_monitor」と入力
  • DescriptionCoinGecko APIを使用した仮想通貨価格リアルタイム監視システム」と入力
  • VisibilityPublic」を選択(ポートフォリオとして公開するため)
  • Initialize this repository with
    • Add a README file」にチェックを入れる
    • Add .gitignore」で「Python」を選択
    • Choose a license」は「None」のままにする
  1. Create repository」ボタンをクリックしてリポジトリを作成します

プロジェクトフォルダの作成

次に、プロジェクトを管理するための共通フォルダを作成しましょう。

Windows・macOS共通

  1. デスクトップや任意の場所に新しいフォルダを作成します
  2. フォルダ名を「PythonPortfolio」に設定します

このPythonPortfolioフォルダが、今後のプロジェクト全体を管理する親ディレクトリとなります。

VSCodeでプロジェクトを開く

作成したGitHubリポジトリをローカルにクローンして開きましょう。

  1. VSCodeを起動します
  2. 左側のアクティビティバーからソース管理アイコン(分岐のようなアイコン)をクリックします
  3. リポジトリの複製」ボタンをクリックします
  4. GitHubから複製」を選択します
  5. 先ほど作成した「crypto_price_monitor」リポジトリを選択します
  6. リポジトリ宛先として「PythonPortfolio」フォルダを選択します
  7. クローンしたリポジトリを開きますか」というウィンドウが表示されたら「開く」をクリックします

VSCodeの左側にエクスプローラーパネルが表示され、現在のプロジェクトフォルダの中身が確認できるようになります。

仮想環境の作成とアクティベート

Python開発において仮想環境は非常に重要です。仮想環境とは、プロジェクトごとに独立したPython実行環境を作成する仕組みのことです。これにより、プロジェクト間でのライブラリの競合を防ぎ、クリーンな開発環境を維持できます。

Windows環境での仮想環境作成

  1. VSCodeの上部メニューから「ターミナル」→「新しいターミナル」を選択
  2. 以下のコマンドで仮想環境を作成します
python -m venv myenv
  1. 仮想環境をアクティベートします
myenv\Scripts\activate

macOS環境での仮想環境作成

  1. VSCodeの上部メニューから「ターミナル」→「新しいターミナル」を選択
  2. 以下のコマンドで仮想環境を作成します
python3 -m venv myenv
  1. 仮想環境をアクティベートします
source myenv/bin/activate

重要なポイント

  • 仮想環境名は「myenv」として作成
  • ターミナルの行頭に「(myenv)」と表示されることを確認
  • この表示があることで、仮想環境が正常にアクティベートされていることがわかります

プロジェクトファイル構造の作成

次に、今回の仮想通貨価格監視プロジェクトに必要なファイルを作成していきます。VSCodeのエクスプローラーパネルを使用してファイルを作成しましょう。

メインプログラムファイルの作成

  1. VSCodeの左側エクスプローラーパネルで「新しいファイル」アイコン(ファイルの絵とプラスのマークがあるアイコン)をクリック
  2. ファイル名を「price_tracker.py」として作成

この「price_tracker.py」ファイルが、今回の仮想通貨価格監視機能を実装するメインプログラムとなります。.py拡張子Pythonスクリプトファイルであることを示しており、実行可能なプログラムコードを記述するために使用します。

依存関係管理ファイルの作成

続いて、プロジェクトで使用するライブラリを管理するためのファイルを作成します。

  1. 同じくエクスプローラーパネルで「新しいファイル」アイコンをクリック
  2. ファイル名を「requirements.txt」として作成

requirements.txtファイルは、Pythonプロジェクトで使用する外部ライブラリとそのバージョンを記録するための重要なファイルです。これにより、他の開発者や本番環境でも同じライブラリ環境を再現できます。

requirements.txtの内容設定

作成した「requirements.txt」ファイルをVSCodeで開き、以下の内容を記述してください。

requests==2.32.3

今回のプロジェクトでは、requestsというライブラリを使用します。

  • requests HTTPリクエストを簡単に送信するためのライブラリです。仮想通貨取引所のAPIから価格データを取得する際に使用します。WebサイトやAPIとの通信を行う際の標準的なツールとして広く使われています

プロジェクト構造の確認

この時点で、VSCodeのエクスプローラーパネルには以下のような構造が表示されているはずです。

crypto_price_monitor/
├── myenv/                 # 仮想環境フォルダ
├── price_tracker.py       # メインプログラムファイル
├── requirements.txt       # 依存関係管理ファイル
├── README.md              # プロジェクト説明ファイル(GitHub作成時に自動生成)
└── .gitignore             # Git除外設定ファイル(GitHub作成時に自動生成)

この基本構造が、今回の仮想通貨価格監視プロジェクトの基盤となります。GitHubで作成したリポジトリをクローンしたため、必要なファイルが最初から含まれています。

仮想環境が正常にアクティベートされていることを再度確認し(ターミナルに「(myenv)」が表示されている状態)、次のステップに進む準備を整えましょう。

ライブラリのインストール

仮想環境がアクティベートされている状態で、VSCodeのターミナルから以下のコマンドを実行します。

pip install -r requirements.txt

このコマンドにより、requirements.txtに記載されたrequestsライブラリがインストールされます。インストール処理には数十秒程度かかる場合がありますので、しばらくお待ちください。

インストールが完了すると、ターミナルに「Successfully installed requests-2.32.3」のようなメッセージが表示され、プロジェクトの環境準備が完了します。

Step2:API接続とデータ取得機能の実装

このステップでは、CoinGecko APIを使用して仮想通貨の価格データを取得する機能を実装します。HTTP通信JSON処理の基本的な仕組みを学習しながら、リアルタイムデータ取得の基盤を構築していきます。

CryptoPriceTrackerクラスの作成

まず、価格監視機能をまとめて管理するクラスを作成します。このクラスの中に、今後必要な機能をすべてdef文(関数)として実装していきます。

price_tracker.pyファイルをVSCodeで開き、以下のコードを記述してください。

import requests
import sys
import time


class CryptoPriceTracker:
    def __init__(self, crypto_id='bitcoin'):
        self.crypto_id = crypto_id
        self.api_url = "https://api.coingecko.com/api/v3/simple/price"
        self.headers = {
            "Accept": "application/json",
            "User-Agent": "CryptoPriceTracker/1.0"
        }

__init__メソッドはクラスの初期化を行う特別な関数です。ここで監視したい仮想通貨のIDを受け取り、API URLとHTTPヘッダーの初期設定を行います。

API接続設定機能

次に、クラス内にsetup_api_paramsメソッドを実装します。

def setup_api_params(self):
        params = {
            'ids': self.crypto_id,
            'vs_currencies': 'jpy',
            'include_24hr_change': 'true'
        }
        return params

このメソッドはクラス内で定義されているため、selfキーワードを使用してクラスの属性にアクセスできます。

CoinGecko APIについて

CoinGecko APIは、仮想通貨の価格情報を無料で提供する公開APIです。リアルタイムの価格データや24時間の変動率など、豊富な情報を取得できます。

価格データ取得機能の実装

まず、CryptoPriceTrackerクラス内のfetch_price_dataメソッドを実装して、APIからデータを取得できるようにします。

def fetch_price_data(self):
        try:
            params = self.setup_api_params()
            response = requests.get(self.api_url, params=params, headers=self.headers)
            response.raise_for_status()
            
            data = response.json()
            
            if self.crypto_id in data:
                return data[self.crypto_id]
            else:
                return None
                
        except requests.exceptions.RequestException as e:
            print(f"API接続エラー: {e}")
            return None

この実装により、APIからのレスポンスを辞書構造で管理できるようになります。requests.get()関数でHTTPリクエストを送信し、response.json()メソッドでJSONデータを辞書型に変換しています。

エラーハンドリング機能の実装

CryptoPriceTrackerクラス内に、API通信のエラーを適切に処理するメソッドを追加します。

def validate_response(self, data):
        if data is None:
            return False, "データの取得に失敗しました"
        
        required_keys = ['jpy']
        for key in required_keys:
            if key not in data:
                return False, f"必要なデータ項目が見つかりません: {key}"
        
        return True, "データは正常です"

このメソッドは、取得したデータの妥当性をチェックし、エラーの詳細情報を提供します。in演算子を使用して辞書内のキーの存在を確認しています。

価格データ解析機能の実装

取得したJSONデータから必要な情報を抽出するメソッドをクラス内に追加します。

def parse_price_info(self, data):
        if not data:
            return None
        
        price_info = {
            'current_price': data.get('jpy', 0),
            'change_24h': data.get('jpy_24h_change', 0),
            'timestamp': time.time()
        }
        
        return price_info

このメソッドでは、APIレスポンスから価格と変動率を抽出し、タイムスタンプを追加して構造化データとして返します。get()メソッドを使用してキーが存在しない場合のデフォルト値を設定しています。

データフォーマット機能の実装

価格情報を見やすい形式で整理する機能をクラス内に追加します。

def format_price_display(self, price_info):
        if not price_info:
            return "価格データが利用できません"
        
        current_price = price_info['current_price']
        change_24h = price_info['change_24h']
        
        change_symbol = "+" if change_24h >= 0 else ""
        formatted_price = f"¥{current_price:,.0f}"
        formatted_change = f"({change_symbol}{change_24h:.2f}%)"
        
        return f"{formatted_price} {formatted_change}"

f文字列フォーマットを使用して数値を読みやすい形式に変換し、変動率には適切な符号を付加しています。

基本表示機能の実装

display_priceメソッドを実装して、価格情報をコンソールに表示できるようにします。

def display_price(self, price_info):
        if price_info:
            formatted_display = self.format_price_display(price_info)
            crypto_name = self.crypto_id.capitalize()
            print(f"{crypto_name}: {formatted_display}")
        else:
            print("価格情報の表示に失敗しました")

メソッドの引数としてprice_infoを受け取り、整形された価格情報をコンソールに出力します。

メイン実行部分の実装

main関数を実装して、各機能を組み合わせたテスト実行を行います。

def main():
    tracker = CryptoPriceTracker('bitcoin')
    
    print("仮想通貨価格取得テストを開始します...")
    
    price_data = tracker.fetch_price_data()
    is_valid, message = tracker.validate_response(price_data)
    
    if is_valid:
        price_info = tracker.parse_price_info(price_data)
        tracker.display_price(price_info)
    else:
        print(f"エラー: {message}")


if __name__ == "__main__":
    main()

動作テスト実行

VSCodeのターミナルでプログラムを実行してテストします。

python price_tracker.py

正常に動作する場合、以下のような出力が表示されます。

仮想通貨価格取得テストを開始します...
Bitcoin: ¥4,234,567 (+2.35%)

この時点で、CoinGecko APIからビットコインの現在価格と24時間変動率を取得し、日本円で表示する基本機能が完成しました。

Step3:リアルタイム監視システムとエラーハンドリングの実装

このステップでは、継続的な価格監視機能堅牢なエラーハンドリングを実装します。ループ処理状態管理システム制御の仕組みを学習しながら、実用的なリアルタイム監視システムを構築していきます。

監視状態管理機能の追加

CryptoPriceTrackerクラスに監視状態を管理する機能を追加します。price_tracker.pyファイルの__init__メソッドに以下のコードを追加してください。

class CryptoPriceTracker:
    def __init__(self, crypto_id='bitcoin'):
        self.crypto_id = crypto_id
        self.api_url = "https://api.coingecko.com/api/v3/simple/price"
        self.headers = {
            "Accept": "application/json",
            "User-Agent": "CryptoPriceTracker/1.0"
        }
        # 以下を追加
        self.previous_price = None
        self.monitoring_active = False
        self.request_interval = 60

previous_priceで前回の価格を記録し、monitoring_activeで監視状態を管理します。request_intervalはAPI制限を考慮して60秒間隔に設定しています。

価格変動検知機能の実装

CryptoPriceTrackerクラス内に、価格変動を検知するメソッドを追加します。

def detect_price_change(self, current_price_info):
        if not current_price_info:
            return False, "データが無効です"
        
        current_price = current_price_info['current_price']
        
        if self.previous_price is None:
            self.previous_price = current_price
            return True, "初回価格設定"
        
        if current_price != self.previous_price:
            price_diff = current_price - self.previous_price
            change_percent = (price_diff / self.previous_price) * 100
            self.previous_price = current_price
            return True, f"変動検知: {price_diff:+,.0f}円 ({change_percent:+.2f}%)"
        
        return False, "価格変動なし"

このメソッドでは、現在価格と前回価格を比較し、変動があった場合の詳細情報を計算します。+フォーマット指定子を使用して符号付きの数値表示を実現しています。

リアルタイム表示制御機能の実装

同一行での価格表示更新を行うメソッドをクラス内に追加します。

def update_display_line(self, message, force_newline=False):
        if force_newline:
            print(f"\n{message}")
        else:
            sys.stdout.write(f"\r{message}")
            sys.stdout.flush()

sys.stdout.write()メソッドと**\r(キャリッジリターン)**を使用して、ターミナルの同一行で表示を更新します。flush()メソッドでバッファを強制的に出力しています。

監視ループ制御機能の実装

継続的な価格監視を行うメソッドをクラス内に追加します。

def start_monitoring(self):
        self.monitoring_active = True
        print(f"{self.crypto_id.capitalize()}の価格監視を開始します...")
        print("価格変動があった場合のみ表示されます")
        print("停止するには Ctrl+C を押してください\n")
        
        try:
            while self.monitoring_active:
                price_data = self.fetch_price_data()
                
                if price_data:
                    price_info = self.parse_price_info(price_data)
                    has_changed, change_message = self.detect_price_change(price_info)
                    
                    if has_changed:
                        formatted_display = self.format_price_display(price_info)
                        crypto_name = self.crypto_id.capitalize()
                        display_message = f"{crypto_name}: {formatted_display} | {change_message}"
                        self.update_display_line(display_message)
                
                time.sleep(self.request_interval)
                
        except KeyboardInterrupt:
            self.stop_monitoring()

while self.monitoring_activeでループを制御し、KeyboardInterrupt例外でCtrl+Cによる停止を処理します。time.sleep()関数で60秒間隔の実行を制御しています。

監視停止機能の実装

監視を安全に停止するメソッドをクラス内に追加します。

def stop_monitoring(self):
        self.monitoring_active = False
        self.update_display_line("\n監視を停止しました。", force_newline=True)
        print("プログラムを終了します。")

monitoring_activeフラグをFalseに設定してループを終了し、適切な終了メッセージを表示します。

接続エラー対応機能の強化

既存のfetch_price_dataメソッドを更新して、より詳細なエラーハンドリングを追加します。

def fetch_price_data(self):
        try:
            params = self.setup_api_params()
            response = requests.get(
                self.api_url, 
                params=params, 
                headers=self.headers,
                timeout=10
            )
            response.raise_for_status()
            
            data = response.json()
            
            if self.crypto_id in data:
                return data[self.crypto_id]
            else:
                print(f"\n警告: {self.crypto_id}のデータが見つかりません")
                return None
                
        except requests.exceptions.Timeout:
            print("\nエラー: API接続がタイムアウトしました")
            return None
        except requests.exceptions.ConnectionError:
            print("\nエラー: インターネット接続を確認してください")
            return None
        except requests.exceptions.HTTPError as e:
            if "429" in str(e):
                print("\nAPI制限: 次回更新まで待機中...")
            else:
                print(f"\nHTTPエラー: {e}")
            return None
        except requests.exceptions.RequestException as e:
            print(f"\nAPI接続エラー: {e}")
            return None

timeout引数を追加し、特に429エラー(レート制限)への対応を含む例外処理を実装しています。

監視設定カスタマイズ機能の実装

監視間隔や対象通貨を変更できるメソッドをクラス内に追加します。

def configure_monitoring(self, interval=60, crypto_id=None):
        if interval >= 30:
            self.request_interval = interval
            print(f"監視間隔を{interval}秒に設定しました")
        else:
            print("API制限のため、最小間隔は30秒です")
        
        if crypto_id:
            self.crypto_id = crypto_id
            self.previous_price = None
            print(f"監視対象を{crypto_id}に変更しました")

引数のデフォルト値を使用して、必要な設定のみを変更できる柔軟性を提供しています。最小間隔も制限しています。

詳細ログ表示機能の実装

監視状況の詳細情報を表示するメソッドをクラス内に追加します。

def display_monitoring_stats(self):
        stats_info = {
            '監視対象': self.crypto_id.capitalize(),
            '更新間隔': f"{self.request_interval}秒",
            '現在価格': f"¥{self.previous_price:,.0f}" if self.previous_price else "未取得",
            '監視状態': "アクティブ" if self.monitoring_active else "停止中"
        }
        
        print("\n=== 監視システム状況 ===")
        for key, value in stats_info.items():
            print(f"{key}: {value}")
        print("=" * 25)

辞書のitems()メソッドを使用してキーと値のペアを反復処理し、整理された情報を表示します。

メイン実行部分の更新

main関数を更新して、新しいリアルタイム監視機能を活用します。

def main():
    tracker = CryptoPriceTracker('bitcoin')
    
    # 初期設定の表示
    tracker.display_monitoring_stats()
    
    # 設定のカスタマイズ例
    tracker.configure_monitoring(interval=60, crypto_id='bitcoin')
    
    # リアルタイム監視の開始
    tracker.start_monitoring()


if __name__ == "__main__":
    main()

動作テスト実行

VSCodeのターミナルでプログラムを実行してテストします。

python price_tracker.py

正常に動作する場合、以下のような出力が表示されます。

=== 監視システム状況 ===
監視対象: Bitcoin
更新間隔: 60秒
現在価格: 未取得
監視状態: 停止中
=========================

監視間隔を60秒に設定しました
監視対象をbitcoinに変更しました
Bitcoinの価格監視を開始します...
価格変動があった場合のみ表示されます
停止するには Ctrl+C を押してください

Bitcoin: ¥4,234,567 (+2.35%) | 初回価格設定
Bitcoin: ¥4,245,123 (+1.87%) | 変動検知: +10,556円 (+0.25%)

この時点で、API制限を考慮した価格変動の継続監視システムが完成しました。60秒間隔での更新により、無料APIの制限内で安定した動作を実現しています。

Step4:表示機能の改良と最終的な動作確認

このステップでは、複数通貨監視機能カラー表示統計情報管理など、より実用的で見やすい表示機能を実装します。データ集約視覚的表現ユーザビリティ向上の技術を学習しながら、完成度の高い監視システムを構築していきます。

複数通貨管理機能の追加

CryptoPriceTrackerクラスに複数の仮想通貨を同時監視する機能を追加します。price_tracker.pyファイルの__init__メソッドを以下のように更新してください。

class CryptoPriceTracker:
    def __init__(self, crypto_list=['bitcoin']):
        self.crypto_list = crypto_list if isinstance(crypto_list, list) else [crypto_list]
        self.api_url = "https://api.coingecko.com/api/v3/simple/price"
        self.headers = {
            "Accept": "application/json",
            "User-Agent": "CryptoPriceTracker/1.0"
        }
        self.previous_prices = {}
        self.monitoring_active = False
        self.request_interval = 60
        self.price_history = {}

crypto_listで複数通貨を管理し、previous_prices辞書で各通貨の前回価格を記録します。price_historyで価格履歴を保存できるようになりました。

API設定機能の更新

setup_api_paramsメソッドを複数通貨対応に更新します。

def setup_api_params(self):
        crypto_ids = ','.join(self.crypto_list)
        params = {
            'ids': crypto_ids,
            'vs_currencies': 'jpy',
            'include_24hr_change': 'true'
        }
        return params

join()メソッドを使用して複数の通貨IDをカンマ区切りの文字列に変換し、一度のAPIコールで複数通貨のデータを取得できます。

カラー表示機能の実装

価格変動を色で表現するメソッドをクラス内に追加します。

def get_color_code(self, change_value):
        if change_value > 0:
            return '\033[92m'
        elif change_value < 0:
            return '\033[91m'
        else:
            return '\033[93m'
    
    def reset_color(self):
        return '\033[0m'

ANSI エスケープシーケンスを使用してターミナルでのカラー表示を実現します。上昇は緑、下降は赤、変動なしは黄色で表示されます。

統計情報計算機能の実装

価格履歴から統計情報を計算するメソッドをクラス内に追加します。

def calculate_price_stats(self, crypto_id):
        if crypto_id not in self.price_history or len(self.price_history[crypto_id]) < 2:
            return None
        
        prices = self.price_history[crypto_id]
        current_price = prices[-1]
        start_price = prices[0]
        
        total_change = current_price - start_price
        change_percent = (total_change / start_price) * 100
        
        max_price = max(prices)
        min_price = min(prices)
        avg_price = sum(prices) / len(prices)
        
        return {
            'total_change': total_change,
            'change_percent': change_percent,
            'max_price': max_price,
            'min_price': min_price,
            'avg_price': avg_price,
            'data_points': len(prices)
        }

max()、min()、sum()関数を使用して価格の最大値、最小値、平均値を計算し、監視開始からの総変動率も算出します。

履歴管理機能の実装

価格データの履歴を記録するメソッドをクラス内に追加します。

def update_price_history(self, crypto_id, price):
        if crypto_id not in self.price_history:
            self.price_history[crypto_id] = []
        
        self.price_history[crypto_id].append(price)
        
        if len(self.price_history[crypto_id]) > 100:
            self.price_history[crypto_id] = self.price_history[crypto_id][-100:]

リストのスライス機能を使用して最新100件のデータのみを保持し、メモリ使用量を制限しています。

高度な表示フォーマット機能の実装

より詳細で見やすい表示を行うメソッドをクラス内に追加します。

def format_detailed_display(self, crypto_id, price_info, stats=None):
        current_price = price_info['current_price']
        change_24h = price_info['change_24h']
        
        color_code = self.get_color_code(change_24h)
        reset_code = self.reset_color()
        
        change_symbol = "+" if change_24h >= 0 else ""
        formatted_price = f"¥{current_price:,.0f}"
        formatted_change = f"({change_symbol}{change_24h:.2f}%)"
        
        display_line = f"{crypto_id.upper()}: {formatted_price} {color_code}{formatted_change}{reset_code}"
        
        if stats:
            total_change_color = self.get_color_code(stats['total_change'])
            session_change = f"{total_change_color}総変動: {stats['total_change']:+,.0f}円 ({stats['change_percent']:+.2f}%){reset_code}"
            display_line += f" | {session_change} | データ: {stats['data_points']}件"
        
        return display_line

f文字列フォーマットとANSIカラーコードを組み合わせて、情報量豊富で視認性の高い表示を実現しています。

複数通貨対応の変動検知機能

detect_price_changeメソッドを複数通貨対応に更新します。

def detect_price_change(self, crypto_id, current_price_info):
        if not current_price_info:
            return False, "データが無効です"
        
        current_price = current_price_info['current_price']
        
        if crypto_id not in self.previous_prices:
            self.previous_prices[crypto_id] = current_price
            self.update_price_history(crypto_id, current_price)
            return True, "初回価格設定"
        
        if current_price != self.previous_prices[crypto_id]:
            price_diff = current_price - self.previous_prices[crypto_id]
            change_percent = (price_diff / self.previous_prices[crypto_id]) * 100
            self.previous_prices[crypto_id] = current_price
            self.update_price_history(crypto_id, current_price)
            return True, f"変動検知: {price_diff:+,.0f}円 ({change_percent:+.2f}%)"
        
        return False, "価格変動なし"

各通貨個別の価格変動検知と履歴更新を行います。

データ出力機能の実装

監視データをファイルに保存するメソッドをクラス内に追加します。

def save_monitoring_data(self, filename="crypto_monitoring_log.txt"):
        try:
            with open(filename, 'w', encoding='utf-8') as f:
                f.write("=== 仮想通貨監視ログ ===\n")
                f.write(f"監視日時: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
                f.write(f"監視間隔: {self.request_interval}秒\n\n")
                
                for crypto_id in self.crypto_list:
                    f.write(f"--- {crypto_id.upper()} ---\n")
                    if crypto_id in self.previous_prices:
                        f.write(f"最終価格: ¥{self.previous_prices[crypto_id]:,.0f}\n")
                    
                    stats = self.calculate_price_stats(crypto_id)
                    if stats:
                        f.write(f"総変動: {stats['total_change']:+,.0f}円 ({stats['change_percent']:+.2f}%)\n")
                        f.write(f"最高価格: ¥{stats['max_price']:,.0f}\n")
                        f.write(f"最低価格: ¥{stats['min_price']:,.0f}\n")
                        f.write(f"平均価格: ¥{stats['avg_price']:,.0f}\n")
                        f.write(f"データ件数: {stats['data_points']}件\n")
                    f.write("\n")
            
            print(f"監視データを {filename} に保存しました")
            
        except IOError as e:
            print(f"ファイル保存エラー: {e}")

with文を使用したファイル操作で、監視セッションの詳細データをテキストファイルに記録します。

監視ループの更新

start_monitoringメソッドを複数通貨対応に更新します。

def start_monitoring(self):
        self.monitoring_active = True
        crypto_names = ', '.join([crypto.capitalize() for crypto in self.crypto_list])
        print(f"{crypto_names}の価格監視を開始します...")
        print("価格変動があった場合のみ表示されます")
        print("停止するには Ctrl+C を押してください")
        print("=" * 50)
        
        try:
            while self.monitoring_active:
                price_data = self.fetch_price_data()
                
                if price_data:
                    for crypto_id in self.crypto_list:
                        if crypto_id in price_data:
                            price_info = self.parse_price_info(price_data[crypto_id])
                            has_changed, change_message = self.detect_price_change(crypto_id, price_info)
                            
                            if has_changed:
                                stats = self.calculate_price_stats(crypto_id)
                                display_message = self.format_detailed_display(crypto_id, price_info, stats)
                                self.update_display_line(display_message, force_newline=True)
                
                time.sleep(self.request_interval)
                
        except KeyboardInterrupt:
            self.stop_monitoring()

for文で各通貨を順次処理し、詳細な統計情報付きで表示します。

監視停止機能の更新

stop_monitoringメソッドを更新して、停止時の表示を明確に分離します。

def stop_monitoring(self):
        self.monitoring_active = False
        print("\n" + "=" * 50)
        print("監視を停止しました")
        print("プログラムを終了します")
        print("=" * 50)

区切り線を追加して停止時の表示を視覚的に分離しています。

設定機能の更新

configure_monitoringメソッドを更新して、通貨リストの変更も対応します。

def configure_monitoring(self, interval=60, crypto_list=None):
        if interval >= 30:
            self.request_interval = interval
            print(f"監視間隔を{interval}秒に設定しました")
        else:
            print("API制限のため、最小間隔は30秒です")
        
        if crypto_list:
            self.crypto_list = crypto_list if isinstance(crypto_list, list) else [crypto_list]
            self.previous_prices.clear()
            self.price_history.clear()
            crypto_names = ', '.join([crypto.capitalize() for crypto in self.crypto_list])
            print(f"監視対象を{crypto_names}に変更しました")

表示状況機能の更新

display_monitoring_statsメソッドを複数通貨対応に更新します。

def display_monitoring_stats(self):
        crypto_names = ', '.join([crypto.capitalize() for crypto in self.crypto_list])
        current_prices = []
        for crypto in self.crypto_list:
            if crypto in self.previous_prices:
                current_prices.append(f"¥{self.previous_prices[crypto]:,.0f}")
            else:
                current_prices.append("未取得")
        
        stats_info = {
            '監視対象': crypto_names,
            '更新間隔': f"{self.request_interval}秒",
            '現在価格': ', '.join(current_prices),
            '監視状態': "アクティブ" if self.monitoring_active else "停止中"
        }
        
        print("=== 監視システム状況 ===")
        for key, value in stats_info.items():
            print(f"{key}: {value}")
        print("=" * 25)

メイン実行部分の最終更新

main関数を更新して、複数通貨監視と新機能を活用します。

def main():
    crypto_currencies = ['bitcoin', 'ethereum', 'ripple']
    tracker = CryptoPriceTracker(crypto_currencies)
    
    tracker.display_monitoring_stats()
    
    tracker.configure_monitoring(interval=60, crypto_list=crypto_currencies)
    
    try:
        tracker.start_monitoring()
    except Exception as e:
        print(f"予期しないエラー: {e}")
    finally:
        tracker.save_monitoring_data()


if __name__ == "__main__":
    main()

動作テスト実行

VSCodeのターミナルでプログラムを実行してテストします。

python price_tracker.py

正常に動作する場合、以下のような出力が表示されます。

=== 監視システム状況 ===
監視対象: Bitcoin, Ethereum, Ripple
更新間隔: 60秒
現在価格: 未取得, 未取得, 未取得
監視状態: 停止中
=========================
監視間隔を60秒に設定しました
監視対象をBitcoin, Ethereum, Rippleに変更しました
Bitcoin, Ethereum, Rippleの価格監視を開始します...
価格変動があった場合のみ表示されます
停止するには Ctrl+C を押してください
==================================================

BITCOIN: ¥14,914,726 (-1.70%) | 総変動: +0円 (+0.00%) | データ: 1件

ETHEREUM: ¥363,232 (-3.41%) | 総変動: +0円 (+0.00%) | データ: 1件

RIPPLE: ¥308 (-2.28%) | 総変動: +0円 (+0.00%) | データ: 1件

Ctrl+Cで停止した場合の出力は以下のようになります。

==================================================
監視を停止しました
プログラムを終了します
==================================================
監視データを crypto_monitoring_log.txt に保存しました

この時点で、複数通貨の同時監視、カラー表示、統計情報管理、明確な区切り表示を備えた本格的な仮想通貨価格監視システムが完成しました。

Step5:プロジェクトをGitHubにアップロード

このステップでは、完成した仮想通貨価格監視プロジェクトをGitHubにアップロードし、ポートフォリオとして活用できる形にします。最終的なファイル整理とコードの公開を行っていきます。

.gitignoreファイルの更新

既存の.gitignoreファイルに、プロジェクト固有の除外設定を追加します。

VSCodeで「.gitignore」ファイルを開き、以下の内容を末尾に追加してください。

# Virtual environment
myenv/

# Monitoring data files
*.txt
*.log
crypto_monitoring_log.txt

これらを追加する理由について説明します。

  • myenv/ 仮想環境フォルダはプロジェクト固有のため、リポジトリに含める必要がありません
  • *.txt 監視実行時に生成される価格ログファイルを除外
  • *.log システム実行時に生成されるログファイルを除外
  • crypto_monitoring_log.txt プログラム実行時に自動生成される監視ログファイルを除外

README.mdファイルの作成

既存の「README.md」ファイルを開き、内容を以下のように全て置き換えしてください。

# 仮想通貨価格リアルタイム監視システム

## プロジェクト内容
CoinGecko APIを使用して仮想通貨の価格をリアルタイムで監視するシステムです。複数の仮想通貨の価格変動を継続的に追跡し、変動があった場合のみ表示する効率的な監視機能を備えています。Pythonを使ったAPI連携とリアルタイム処理技術を学習することを目的として実装しました。

## プロジェクト構成
```
crypto_price_monitor/
├── price_tracker.py        # メインプログラム
├── requirements.txt         # 依存関係管理
├── README.md               # プロジェクト説明書
└── .gitignore              # Git除外ファイル設定
```

## 必要要件/開発環境
- **Python 3.7以上**
- **インターネット接続** (API通信のため)
- **VSCode** (開発環境)
- **Git** (バージョン管理)

### 使用ライブラリ
- **requests 2.32.3** HTTPリクエスト処理

## 機能
- **リアルタイム価格監視** 複数通貨の同時監視機能
- **価格変動検知** 変動があった場合のみ表示
- **カラー表示** 上昇・下降を色で視覚化
- **統計情報管理** 価格履歴の統計分析
- **データ保存機能** 監視結果のログ出力
- **エラーハンドリング** API制限や接続エラーへの対応
- **設定カスタマイズ** 監視間隔や対象通貨の変更

## 実行方法

### 1. リポジトリのクローン
```bash
git clone https://github.com/yourusername/crypto_price_monitor.git
cd crypto_price_monitor
```

### 2. 仮想環境の作成・アクティベート
**Windows**
```bash
python -m venv myenv
myenv\Scripts\activate
```

**macOS**
```bash
python3 -m venv myenv
source myenv/bin/activate
```

### 3. 依存関係のインストール
```bash
pip install -r requirements.txt
```

### 4. プログラムの実行
```bash
python price_tracker.py
```

実行後、ビットコイン、イーサリアム、リップルの価格監視が開始されます。
停止するには Ctrl+C を押してください。

## API制限について
無料プランでは10-30回/分のAPI制限があるため、監視間隔は60秒に設定されています。

## 開発者
初心者向けAPI連携・リアルタイム処理学習プロジェクト

プロジェクトのコミット・プッシュ

プロジェクトの全ての変更をGitHubに反映させましょう。

変更のステージングとコミット

  1. VSCodeの左側のアクティビティバーからソース管理アイコンをクリックします
  2. 変更内容セクションで、すべての変更ファイルを確認します
  3. 各ファイルの横にある「+」アイコンをクリックしてステージングします
  4. コミットメッセージ入力欄に「Add crypto price monitoring system」と入力します
  5. コミット」ボタンをクリックします

GitHubへのプッシュ

  1. コミット完了後、「変更の同期」または「プッシュ」ボタンをクリックします
  2. 初回の場合、GitHub認証が求められる場合があります
  3. 認証完了後、ローカルの変更がGitHubリポジトリに反映されます

GitHubでの確認

プロジェクトが正常にアップロードされたか確認しましょう。

  1. ブラウザでGitHubリポジトリページを開きます
  2. 以下のファイルが正しくアップロードされていることを確認します
  • price_tracker.py (メインプログラムファイル)
  • requirements.txt (依存関係管理ファイル)
  • README.md (更新されたプロジェクト説明書)
  • .gitignore (更新された除外設定ファイル)
  1. README.mdが適切に表示され、プロジェクトの説明が読みやすく表示されていることを確認します
  2. ファイル一覧にmyenv/フォルダや*.txtファイルが含まれていないことを確認します(.gitignoreで除外されているため)

これで本格的な仮想通貨価格監視システムが完成し、GitHubでのポートフォリオ公開も完了しました。作成したプロジェクトは、就職活動や案件獲得時の実績として活用できる実用的なシステムとなっています。


まとめ

このプロジェクトを通じて、Pythonを使用したAPI連携とリアルタイムデータ処理の基礎から実践的な応用まで幅広く学習することができました。

得られたスキル

  • HTTP通信とAPI連携 requestsライブラリを使った外部サービスとの連携技術
  • JSONデータ処理 辞書とリストを活用した構造化データの操作手法
  • リアルタイム処理 継続的なデータ監視とイベント駆動型プログラミング
  • エラーハンドリング 例外処理を使った安定性の高いシステム設計
  • データ可視化 ANSIカラーコードを使った表示制御技術
  • オブジェクト指向プログラミング クラス設計とメソッドの実装

得られた経験

  • 外部APIを使用したリアルタイムデータ取得経験
  • 金融データの処理と統計分析手法の習得
  • API制限への対応を含むシステム設計経験
  • プロジェクト管理の基本的な流れの理解
  • GitHubを使用したバージョン管理の実践的経験

得られた成果物

  • 完全に動作する仮想通貨価格監視システム
  • GitHubでのポートフォリオとして活用可能なプロジェクト
  • 再利用可能なコードベース
  • 詳細なドキュメント(README.md)

次に学ぶべきこと

  • pandasを使用したCSV出力とデータ分析機能の追加
  • matplotlibによる価格グラフの可視化機能
  • SQLiteを使った価格履歴データベースの構築
  • スケジューリングによる自動実行機能の実装
  • Slackボットとの連携による通知機能の開発

このプロジェクトから応用することでできること

  • 株価監視ツールの開発による個人投資支援サービス
  • 暗号資産取引所の価格比較システムの構築
  • 為替レート監視サービスの提供
  • 商品価格追跡ツールの開発による価格調査代行
  • APIデータ収集代行サービスの事業化
  • アラート機能付き監視システムの受託開発

このAPI連携技術を基盤として、様々な業界でのデータ監視や自動化ニーズに対応できるサービスを開発することが可能です。特に、定期的なデータ収集や価格監視が必要な業務では、高い価値を提供できる技術として活用できます。

この記事が気に入ったら
フォローしてね!

この記事が参考になった方はシェアしてね!
  • URLをコピーしました!

本コンテンツへの意見や質問

コメントする

目次