💹

Python&Lambda(+ServerlessFramework)で指定した企業の株価データとチャート図を定期的にSlack通知する

2021/05/04に公開

背景

下記記事に触発されて同様のことを試してみました!という話。

https://zenn.dev/t_fukumoto/articles/e5e0fe753d5726

先人たちの知恵をお借りするなどして解決できたことを、この場をお借りして感謝するとともに、大変恐縮ですが 自分のメモ として、こちらへまとめておきます。

環境

(本番)
AWS (Amazon Web Sevices)

  • Lambda (Runtime = Python 3.8)
  • S3 (Simple Strage Service)
  • Event Bridge
  • SNS (Simple Notification Service)
  • Cloud Watch Logs
  • Cloud Formation

(開発)

  • Python 3.9.5
  • VS Code
  • Serverless Framework v2
  • Node.js 14.16.1

1.株価取得・チャート化

データはみなさんも一度は耳にしたことのある「日経平均株価」です。
https://finance.yahoo.com/quote/^N225/history?p=^N225

日経平均株価とは

日本経済新聞社が東証1部に上場する企業の中から業種等のバランスを考慮して選んだ、日本を代表する225社の平均株価です。「日経平均」「日経225」などと呼ばれることもあります。
「日経平均が上がっていれば多くの企業の株価が値上りしている」、「日経平均が下がっていれば多くの企業の株価が値下りしている」という見方ができ、株式市場全体の大まかな値動きを把握することができます。
このため注目度が高く、テレビのニュースなどで「今日の日経平均は○○○円でした」というように紹介されることも多々あります。
※上記サイト(アメリカのyahoofinenceのページ)では、「^N225」という銘柄コードで検索できます。

  • 株価取得・チャート化の参考記事はこちら👇

https://myfrankblog.com/stock_price_with_yahoo_finance_api2/

https://myfrankblog.com/stock_price_chart_with_python_mpl_finance/
※上記記事の執筆当時と、ライブラリ名称が変更となっています。ご注意ください。
 mpl_finance → (変更後) mplfinance

https://dev.classmethod.jp/articles/pandas_datareader-python/

https://vucavucalife.com/python-mplfinance-candle-stick-style/

2.Slackアプリ作成

  • アプリの作成手順はこちら👇が分かり易いです。

https://qiita.com/seratch/items/a001985ee1dccaf95727

https://qiita.com/kou_pg_0131/items/56dd81f2f4716ca292ef

  • 今回、Slackへの通知には slack_sdk というライブラリを使いました。
  • requests でも出来るようなのですが、私は何度試してもダメでした💦

https://pypi.org/project/slack-sdk/

3.Lambda関数作成

  • Lambda関数の基本的な設定に関する参考記事はこちら👇

https://zenn.dev/whitecat_22/articles/9681ab7c85519c

  • 今回は、numpyというライブラリがLambda上でimportエラーとなったため、Serverless Framework を使うこととしました。
  • Serverless Framework についての参考記事はこちら👇

https://zenn.dev/ryo_kawamata/articles/python-exclude-package-on-serverless-framework

https://dev.classmethod.jp/articles/managing-external-modules-with-serverless-framework-plugin/

https://dev.classmethod.jp/articles/serverless-framework-lambda-numpy-scipy/

https://serverless.co.jp/blog/25/


【注意】

  • serverless.yaml で slim: true とすると、以下のメッセージが発生。Pillow==8.1.0 でないと Runtime が壊れるという事象のため、やむなくPillowのみver.指定でインストールしています。
{
    "errorMessage": "Unable to import module 'handler': /tmp/sls-py-req/PIL/_imaging.cpython-38-x86_64-linux-gnu.so: ELF load command address/offset not properly aligned",
    "errorType": "Runtime.ImportModuleError",
    "stackTrace": []
}

4.実行結果

  • ^N225 の直近6ヶ月間の株価と出来高の推移をチャートにしたものです👇

  • そして、Slackへ通知した結果👇 (予定)
    ※ローカルから直接.pyファイルを実行すれば通知される…
    ※ServerlessFrameworkをまだ良く使えていないものの、ちゃんと使えればできるはず🙇

★ Serverless Framework を利用して Lambda へのデプロイ、稼働もできました!🙌 (2021/05/22更新)

…単価は小数2桁までの表示にしたい…

  • twitterにも投稿した結果👇 (2021/05/23更新)


(2021/05/22追記)

  • デプロイ
(venv) C:\Users\xxxxxxxx\Documents\python\serverless\stock-price-chart\venv>sls deploy -v
Serverless: DOTENV: Loading environment variables from .env:
Serverless:      - STOCK_CODE
Serverless:      - SLACK_API_TOKEN
Serverless:      - SLACK_CHANNEL_ID
Serverless:      - SLACK_SIGNING_SECRET
Serverless:      - SLACK_BOT_TOKEN
Serverless: Deprecation warning: Support for "package.include" and "package.exclude" will be removed with next major release. Please use "package.patterns" instead
            More Info: https://www.serverless.com/framework/docs/deprecations/#NEW_PACKAGE_PATTERNS
Serverless: Adding Python requirements helper...
Serverless: Generated requirements from C:\Users\xxxxxxxx\Documents\python\serverless\stock-price-chart\venv\requirements.txt in C:\Users\xxxxxxxx\Documents\python\serverless\stock-price-chart\venv\.serverless\requirements.txt...
Serverless: Using static cache of requirements found at C:\Users\xxxxxxxx\AppData\Local\UnitedIncome\serverless-python-requirements\Cache\221be91c8d8a3e949d364963421f0899c89d05a3a404e980116712311d9cda69_slspyc ...
Serverless: Zipping required Python packages...
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Removing Python requirements helper...
Serverless: Packaging Python Requirements Lambda Layer...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service stock-price-chart.zip file to S3 (64.2 MB)...
Serverless: Uploading service pythonRequirements.zip file to S3 (65.51 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - stock-price-chart-dev
CloudFormation - UPDATE_IN_PROGRESS - AWS::Lambda::Function - LambdahandlerLambdaFunction
CloudFormation - UPDATE_IN_PROGRESS - AWS::Lambda::LayerVersion - PythonRequirementsLambdaLayer
CloudFormation - UPDATE_COMPLETE - AWS::Lambda::Function - LambdahandlerLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - LambdahandlerLambdaVersionHlWegwGoh8l6SqLI0ma5b33tTeOpgJGMj9vmUzi1og
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - LambdahandlerLambdaVersionHlWegwGoh8l6SqLI0ma5b33tTeOpgJGMj9vmUzi1og
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Version - LambdahandlerLambdaVersionHlWegwGoh8l6SqLI0ma5b33tTeOpgJGMj9vmUzi1og
CloudFormation - UPDATE_IN_PROGRESS - AWS::Lambda::LayerVersion - PythonRequirementsLambdaLayer
CloudFormation - UPDATE_COMPLETE - AWS::Lambda::LayerVersion - PythonRequirementsLambdaLayer
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - stock-price-chart-dev
CloudFormation - DELETE_IN_PROGRESS - AWS::Lambda::LayerVersion - PythonRequirementsLambdaLayer
CloudFormation - DELETE_SKIPPED - AWS::Lambda::Version - LambdahandlerLambdaVersionNtu640uqwHdB6THpMAKeD3FhNPdDrssod396ARgwx0k
CloudFormation - DELETE_COMPLETE - AWS::Lambda::LayerVersion - PythonRequirementsLambdaLayer
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - stock-price-chart-dev
Serverless: Stack update finished...
Service Information
service: stock-price-chart
stage: dev
region: ap-northeast-1
stack: stock-price-chart-dev
resources: 7
api keys:
  None
endpoints:
  None
functions:
  lambdahandler: stock-price-chart-dev-lambdahandler
layers:
  pythonRequirements: arn:aws:lambda:ap-northeast-1:012345678901:layer:dev-requirementLayer:22

Stack Outputs
PythonRequirementsLambdaLayerS3Key: serverless/stock-price-chart/dev/1621669786802-2021-05-22T07:49:46.802Z/pythonRequirements.zip
LambdahandlerLambdaFunctionQualifiedArn: arn:aws:lambda:ap-northeast-1:041603970553:function:stock-price-chart-dev-lambdahandler:5
PythonRequirementsLambdaLayerQualifiedArn: arn:aws:lambda:ap-northeast-1:012345678901:layer:dev-requirementLayer:22
PythonRequirementsLambdaLayerHash: 5f43743e1110a352a7d39195e7b133337c6c394c
ServerlessDeploymentBucketName: stock-price-chart-lambda-s3

Serverless: Removing old service artifacts from S3...

  • serverless framework コマンドからLambda関数を実行したログ
(venv) C:\Users\xxxxxxxx\Documents\python\serverless\stock-price-chart\venv>sls invoke -f lambdahandler --log
Serverless: DOTENV: Loading environment variables from .env:
Serverless:      - STOCK_CODE
Serverless:      - SLACK_API_TOKEN
Serverless:      - SLACK_CHANNEL_ID
Serverless:      - SLACK_SIGNING_SECRET
Serverless:      - SLACK_BOT_TOKEN
Serverless: Deprecation warning: Support for "package.include" and "package.exclude" will be removed with next major release. Please use "package.patterns" instead
            More Info: https://www.serverless.com/framework/docs/deprecations/#NEW_PACKAGE_PATTERNS
{
    "statusCode": 200,
    "body": "ok"
}
--------------------------------------------------------------------
START RequestId: 6c21a788-88a3-46a3-80f0-dfe7df87f451 Version: $LATEST
2021-05-22 16:52:37.029 (+09:00)        6c21a788-88a3-46a3-80f0-dfe7df87f451    [INFO]  {}
event: {}
context: <__main__.LambdaContext object at 0x7fe993a519d0>
END RequestId: 6c21a788-88a3-46a3-80f0-dfe7df87f451
REPORT RequestId: 6c21a788-88a3-46a3-80f0-dfe7df87f451  Duration: 3720.99 ms    Billed Duration: 3721 ms        Memory Size: 1024 MB  Max Memory Used: 519 MB Init Duration: 8694.59 ms

5.ソースコード等

コチラ👇で公開しています。(2021/05/22追記)
https://github.com/whitecat-22/stock_price_chart


参考

  • 上述のほか、以下の記事を参考にしました。

https://www.delftstack.com/ja/howto/python-pandas/how-to-change-the-order-of-dataframe-columns/


(編集後記)

日経平均株価はもちろんのこと、お客様企業の株価や、自社の株価、自己の保有株式の株価など、日々調べるのは大変な労力がかかります。
これらの作業を自動化して、結果をSlackへ通知しておくと、お客様との会話のネタにも困りません。(もちろん株価だけでなく、決算短信・決算報告書や日々のニュースリリースなども確認しましょう!)

FXや暗号資産の取引に興味のある方は、調査対象のデータソースを該当のものに変えることで、ご自身の資産状況や取引結果と照合してみるのも良いと思います。

今後は、機械学習を通した将来の価格予測まで行なった上での通知を考えています。

(2021/05/22追記)
今回、初めて serverless framework を使いましたが、設定をはじめデプロイ、Lambda関数の実行まで、何度も躓き悩み考え、その度にTry&Errorも繰り返し、ようやく完成に漕ぎ着けました。
serverless framework は便利なものですので、しっかりと設定方法を覚えて、どんどんと使っていきます。

Discussion