간단한 주가 모니터링 프로그램을 만들어 보려고 합니다. 매매는 타이밍 이라는데 주가를 계속 지켜보고 있을 수는 없는 노릇이니 프로그램을 통해 주가를 지켜보다가 필요할 때 메신저로 알림을 받을 수 있도록 하는 방식입니다. 우선 Don’t reinvent the wheel의 조언에 따라 비슷한 서비스가 있는지 검색해봅니다. 자몽그램 이라는 서비스가 있는데 이것과 비슷한 것이 될 것 같습니다.
주가 모니터링을 하려면 주기적으로 스크래핑을 실행해야 합니다. 전에 썼던 재입고 관련 스크래핑 글에서는 무한 루프와 sleep 함수를 이용해 프로그램의 주기를 조정했습니다.이 경우 좀 반복되는 코드의 시간만큼 실행시간이 늦어지는 현상이 나타납니다. 언제 실행할지를 정확히 조절하기는 어려워 집니다. 이럴 때 필요한 것이 스케줄러 입니다.
java에서는 quartz 라는 스케줄러가 대표적으로 있습니다. Spring 등 이런저런 프레임워크에도 포함되어 있습니다. 사용하기도 어렵지 않은 편입니다.
운영체제의 스케줄러를 사용하는 것도 방법입니다. 윈도우의 경우 작업 스케줄러가 있고 유닉스나 리눅스의 경우 cron 이 있습니다. 다만 이러한 정보들이 운영체제에 남게 되는 것이 프로그램의 이식성을 낮게 만드는 원인이 됩니다.
파이썬으로 만드는 프로그램이라 파이썬 쪽 스케줄러들을 찾아봤습니다. 기본적으로는 내장된 sched가 있고 apscheduler, Celery Periodic Task 등이 대표적인 것 같습니다. 그 중 apscheduler가 적용하기 적당해 보여 선택해봤습니다.
예제 코드
현재 우리나라 증시의 영업일은 월 ~ 금요일 이고 개장시간과 패장시간은 9시, 15시 반 입니다. 이 시간 동안만 모니터링을 한다고 하면 2가지 스케줄링이 필요합니다.
- 모니터링 시작/종료 주기 : 월~금요일 9시 모니터링 시작, 15시 30분 모니터링 종료.
- 모니터링 체크 주기 : 1분마다/5분마다/10분마다 등등
1번 스케줄에서는 2번 스케줄을 시작하거나 종료하게 됩니다. 일종의 중첩(nested) 스케줄링이라고 할 수 있겠습니다.
테스트를 위해 이런 코드를 만들어 봤습니다. 실제로 월요일~금요일을 테스트하기는 어려우므로 주기를 짧게 만들었습니다.
- 6라인 : 메인 코드가 될 부분입니다. 테스트를 위해 시각만 표시하도록 했습니다.
- 10라인 : 스케줄러 인스턴스를 만듭니다. 하나의 프로세스(process)로 돌아가므로 BlockingScheduler를 사용했습니다.
- 13라인 : 메인 코드를 스케줄러에 추가해 줍니다. 모니터링 체크 주기에 해당하는 작업입니다. 여기서는 테스트를 위해 10초마다 돌아가도록 해봤습니다.
- 16라인/21라인 : 각각 메인 코드의 스케줄을 멈추고(pause) 다시 시작하는(resume) 함수입니다.
- 29라인/30라인 : 위의 16라인/21라인 코드를 실행하는 스케줄을 등록합니다.
처음에는 2개의 스케줄러를 만들었는데 뭔가 정상 작동하지 않았습니다. 하나의 프로세스에서 스케줄러는 하나만 사용해야 하는 것 같았습니다. 여러 주기를 섞어서 사용할 때는 스케줄러를 여러 개 만들어서 사용하는게 아니고 하나의 스케줄러에 각각의 작업 주기를 다르게 등록하는게 맞는 것 같습니다.
참조
- apscheduler 소스 : https://github.com/agronholm/apscheduler
- 파이썬 스크립트 스케줄링하기 : https://medium.com/wasd/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81%ED%95%98%EA%B8%B0-720dcc47b7e7
- sched 예제 : https://pymotw.com/2/sched/
- sched 예제 : https://www.programcreek.com/python/example/91056/sched.scheduler