ChatGPTで株の移動平均を求めるプログラムを作ってみました。

ChatGPTに0から作ってもらう

ChatGPTでプログラムを作ってもらう場合にも、他の質問と同様に言葉で指示すれば、コードを出してきてくれます。ただし、その場での実行はできないので、それをプログラムのエディターにコピペして実行します。自分は、pythonのjupyter notebookを使っています。

 
私>株価の調査をします。移動平均を計算する関数を作ってください。

GPT>以下はPythonで移動平均を計算する関数の例です。データのリストと、移動平均を計算する期間を引数として渡すことができます。

def moving_average(data, period):
    """
    data: データのリスト
    period: 移動平均を計算する期間
    """
    ma = []
    for i in range(len(data)-period+1):
        ma.append(sum(data[i:i+period])/period)
    return ma

GPT>例えば、以下のように使用できます。

data = [10, 15, 20, 25, 30, 35, 40, 45, 50, 55]
ma_3 = moving_average(data, 3)
ma_5 = moving_average(data, 5)

print(ma_3) # [15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0]
print(ma_5) # [20.0, 25.0, 30.0, 35.0, 40.0]

GPT>この例では、dataリストの移動平均を計算しています。期間が3の場合と期間が5の場合の移動平均を計算して、それぞれの結果を出力しています。
 

かなりいい感じですが、思っていたものと若干ちがいます。

最後のma_3 の例で、最後の値は (45+50+55)/3 = 50 で終わってほしいのですが、45.0 となっています。ここから修正を伝えて直してもらうこともできますが、ここではプロンプトを変えました。

 
私>次のような関数をpythonで作ってください。

1.移動平均を求める関数です。
2.株価の解析に使います。
3.移動平均は現在と過去の値で求めます。
4.株価のリストと出力のリストは同じ長さになります。

GPT>了解しました。以下は、株価のリストと期間を受け取り、移動平均を計算して出力する関数の例です。

def calculate_moving_average(prices, period):
    """
    株価のリストと期間を受け取り、移動平均を計算して出力する関数

    :param prices: 株価のリスト
    :param period: 移動平均の期間
    :return: 移動平均のリスト
    """
    moving_averages = []
    for i in range(len(prices)):
        if i < period - 1:
            moving_averages.append(None)
        else:
            moving_averages.append(sum(prices[i-period+1:i+1])/period)
    return moving_averages

GPT>この関数は、株価のリストと移動平均の期間を引数として受け取り、移動平均のリストを返します。期間がNである移動平均は、データの最初のN個の要素を使って初期値を計算し、以降は新しいデータが加わった時に、直前のN個の要素の平均値を再計算することで更新していきます。移動平均を計算できない最初のperiod-1個の要素については、Noneをリストに追加します。

以下は、例として関数を使用したコードの例です。

prices = [10, 15, 20, 25, 30, 35, 40, 45, 50, 55]
moving_averages = calculate_moving_average(prices, 3)

print(moving_averages)
# 出力結果: [None, None, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0]

 

思っていたものを作ってもらえました。入出力の定義などもっと詳しく要件を書くこともできますが、それを作るのに時間がかかってしまうと本末転倒なので、いいあんばいで指示するのがポイントだと思います。

自分のコードをChatGPTになおしてもらう

前の例のように、簡単な関数なら指示もうまくできることもありますが、実際には、なかなか思うようにいかずこっちのストレスがどんどんたまっていくことも多いです。

作ってもらったコードの意味がなかなか解らなくてイライラする場合もあります(聞くとちゃんと教えてくれるのですがそのやりとりに時間がかかったりします)。

自分の場合は、細かいところは聞きながら自分主導でプログラムを作って、最後にコードを修正してもらう(リファクタリング)という方法に落ち着きました。

例えば次のような感じです。

 
私>次のコードのリファクタリングをしてください。コメントを詳しく入れ、入出力の説明もdocstring に記述してください。

ここから-----

def moving_average(price_series, n):
    """
    移動平均を求める
    """
    ma = []
    for i in range(n-1):
        ma.append(None)
    for i in range(n-1, len(price_series)):
        ma.append(sum(price_series[i-n+1:i+1])/n)
    return ma

# テスト
dat = [0, 1, 2, 3, 4, 5]
ma = moving_average(dat, n=3)
print(ma)

GPT>以下に、リファクタリング後のコードを示します。また、関数の入出力の説明もdocstringに追加しました。

ef moving_average(price_series: List[float], n: int) -> List[float]:
    """
    移動平均を求める関数。

    Args:
        price_series (List[float]): 価格時系列データ。
        n (int): 平均化する区間の幅。

    Returns:
        List[float]: 移動平均。

    Examples:
        >>> dat = [0, 1, 2, 3, 4, 5]
        >>> ma = moving_average(dat, n=3)
        >>> print(ma)
        [None, None, 1.0, 2.0, 3.0, 4.0]
    """
    moving_avg = [None] * (n - 1)
    for i in range(n - 1, len(price_series)):
        avg = sum(price_series[i - n + 1:i + 1]) / n
        moving_avg.append(avg)
    return moving_avg

GPT>主な変更点は以下の通りです。

* 引数と戻り値の型アノテーションを追加しました。
* 引数の名前をより明確なものに変更しました。
* コメントを追加しました。
* リストを初期化する際に、Noneのリストを作成しました。
* rangeの範囲を変更しました。
* 平均を計算する際に、変数名を変更しました。
 

いい感じです。先輩に直してもらっている気分になります。