We have created a BOT that notifies you on LINE of stocks whose 75-day and 200-day moving averages, which are often used in stocks, have a golden cross. The reason why "75 days" and "200 days" are described in note, so please have a look.
Here I will write how I implemented it. The source code is GitHub Is published. The difference from other people is that the source code is very simple because it focuses on the message sending function from the bot side.
The golden crossed stocks are published on Stock Tech. The stock market business days are updated every day, but I just forget to go see it, so I thought it would be convenient if there was a bot that would automatically notify me.
The flow is
The code was implemented in Python. It is roughly divided into "scraping" and "sending messages via LINE". Scraping is based on the fact that the stock market is closed on Saturdays, Sundays, and holidays.
import os
import datetime
import re
from bs4 import BeautifulSoup
import jpholiday
from linebot import LineBotApi
from linebot.exceptions import LineBotApiError
from linebot.models import TextSendMessage
import requests
KABUTEC_GC_URL = "https://www.kabutec.jp/contents/compare/com.php?col1=8&scol1=0&col2=26&scol2=0&col3=27&scol3=0&market=0"
def get_today_list():
"""
Acquire GC stock from stock tech.
"""
res = requests.get(KABUTEC_GC_URL)
soup = BeautifulSoup(res.text, "html.parser")
li = soup.find_all(href=re.compile("kabutec.jp/company/fs_"))
company_list = list(map(lambda item: item.contents[0], li))
return company_list
def get_weekday():
"""
Make a weekday judgment.
Returns
-------
ret : boolean
True :Weekdays
False :holiday
"""
dt_jst = datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=9)))
if dt_jst.weekday() == 5 or dt_jst.weekday() == 6:
ret = False
else:
if jpholiday.is_holiday(dt_jst.date()):
ret = False
else:
ret = True
return ret
if __name__ == "__main__":
if get_weekday():
li = get_today_list()
line_bot_api = LineBotApi(os.environ["LINE_CHANNEL_ACCESS_TOKEN"])
msg = "Today's GC brand{num}It is a brand.\n{li}".format(num=len(li), li="\n".join(li))
print(msg)
messages = TextSendMessage(text=msg)
try:
line_bot_api.broadcast(messages=messages)
except LineBotApiError:
pass
else:
print("I am out of duty today.")
The LINE Bot part was very simple to write using LINE's Messaging API. Get the "Channel Access Token (Long Term)" from LINE Developers and set "LINE_CHANNEL_ACCESS_TOKEN" as an environment variable.
Others use Flask to receive messages sent by LINE, but if you just send it from the bot side, you don't need Flask either.
I'm using line_bot_api.broadcast
to broadcast to all users who are friends with the bot.
line_bot_api = LineBotApi(os.environ["LINE_CHANNEL_ACCESS_TOKEN"])
msg = "Today's GC brand{num}It is a brand.\n{li}".format(num=len(li), li="\n".join(li))
print(msg)
messages = TextSendMessage(text=msg)
try:
line_bot_api.broadcast(messages=messages)
except LineBotApiError:
pass
When using broadcast, you have to be careful about the number of messages sent. The LINE API itself can be used for free, but the number of messages that can be sent for free is up to 1000 messages / month. Given that the stock market is open on the 20th of the month, if you have more than 50 bot friends, you will not be able to send at the end of the month.
It's operated on Heroku. If you have a bot that works at a fixed time every day like this time, Heroku only needs two settings.
Set LINE_CHANNEL_ACCESS_TOKEN
to Config Vars
in Heroku's Settings.
You can get the channel access token from "Channel Access Token (Long Term)" in LINE Developers.
Add Heroku Scheduler from Installed add-ons.
Heroku Scheduler itself is free to use, but you'll need to register a credit card.
For example, in the case of this program, if you register the command python main.py
as a schedule, it will move at the desired time and a message will be sent from the bot. The schedule itself seems to have an error of several minutes, so be careful with programs that require strict time definition.
Recommended Posts