記事の更新日:2021年8月29日
Pythonでデイトレードの自動売買システムを構築するには、並列処理[スレッド]の知識があった方が良いでしょう。
例えば、リアルタイム株価を取得するプログラムを走らせながら、発注や反対売買の処理を行うケースなどです。
※留意事項
このブログ記事はPython初心者向けに作成しています。
初心者が理解しやすいように、Pythonコードは美しさや推奨されている記述ルールよりも単純であることを優先しました。
新しく覚えることも出来るだけ少なくするため、今回の記事ではプリント文を多く用いています。
Python上級者にとっては、冗長(長たらしい)なコード記述に感じるかも知れませんが、ご容赦願います。
逐次処理と並列処理
Pythonコードは、記述した順番に上から処理されます。
◇逐次処理のイメージ
Pythonでは、スレッドを使うと並列処理を実行する事も出来ます。
◇並列処理のイメージ
Pythonコードを見ながらの方が理解しやすいと思いますので、サンプルコーをご覧に入れながら解説します。
ライブラリーのインポートと関数作成
並列処理[スレッド]を行うために必要なライブラリーをインポートします。
並列処理されていることが分かるように、sleepを使うのでtimeもインポートします。
関数は3つ作成しました。
○processing1()
最初に実行される関数
実行されると、 「関数1 : 開始」と出力して、1秒待機した後「関数1 : 終了」と出力します。
○parallel_processing1()
並列処理される関数
実行されると、 「並列処理1 : 開始」と出力して、10秒待機した後「並列処理1 : 終了」と出力します。
○parallel_processing2()
並列処理される関数
実行されると、 「並列処理2 : 開始」と出力して、5秒待機した後「並列処理2 : 終了」と出力します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# スレッドをインポート import threading # スリープを使ってプログラムを待機させるので、timeをインポート import time def processing1(): # 関数の名前をプリント print('関数1 : 開始') #待機 1秒 time.sleep(1) #関数が終了したことをプリント print('関数1 : 終了') def parallel_processing1(): # 現在のスレッド(並列処理)が開始したことをプリント print('並列処理1 : 開始') # 待機 10秒 time.sleep(10) # 現在のスレッド(並列処理)が終了したことをプリント print('並列処理1 : 終了') def parallel_processing2(): # 現在のスレッド(並列処理)が開始したことをプリント print('並列処理2 : 開始') # 待機 5秒 time.sleep(5) # 現在のスレッド(並列処理)が終了したことをプリント print('並列処理2 : 終了') |
並列処理[スレッド]を実行する
並列処理[スレッド]を実行させましょう。
今回のサンプルコードでは、並列処理[スレッド]させる関数は2つです。
- parallel_processing1()
- parallel_processing2()
taget=で走らせる関数を渡します。
t1 = threading.Thread(target=parallel_processing1)
t2 = threading.Thread(target=parallel_processing2)
スレッド t1 をスタートさせます。
t1.start()
1秒待機後
スレッド t2 をスタートさせます。
t2.start()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
if __name__ == '__main__': # 1つ目の関数を実行させる processing1() # スレッドを2つ走らせる # tagetで走らせる関数を渡す。 t1 = threading.Thread(target=parallel_processing1) t2 = threading.Thread(target=parallel_processing2) # t1とt2を平行で走らせる # スレッド1を走らせる t1.start() # 1秒待機 time.sleep(1) # スレッド2を走らせる t2.start() |
実行結果
実行結果は次のようになります。
このサンプルコードを実行すると、
最初に関数processing1()が実行され、
関数1 : 開始 が出力。 1秒待機後 関数1 : 終了 が出力される。
t1.start()で スレッド1が実行され、
並列処理1 : 開始 が出力される。
t1.start()実行の1秒後に t2.start()が実行され、
並列処理2 : 開始 が出力される。
スレッドとして並列処理されている関数parallel_processing1内で10秒待機
スレッドとして並列処理されている関数parallel_processing2内で5秒待機
それぞれの関数内で待機している秒数が異なるので、
並列処理2 : 終了 が出力され、その後に
並列処理1 : 終了 が出力されて、全体のプロセスが終了。
引数を渡す
並列実行されている関数に引数を渡すことも出来ます。
引数を渡す関数を作ります。
1 2 3 4 5 6 7 8 9 |
def parallel_processing3(x, y=1): # 現在のスレッド(並列処理)が開始したことをプリント print('並列処理3_引数有り : 開始') print('引数x:', x) print('引数y:', y) # 待機 6秒 time.sleep(7) # 現在のスレッド(並列処理)が終了したことをプリント print('並列処理3_引数有り : 終了') |
下のサンプルコードでは、引数をタプル型と辞書型で渡しています。
1 2 3 4 5 6 |
if __name__ == '__main__': # 引数を渡す # x引数をタプルで渡すためにargs=(100,)カンマを入れている # y引数を辞書型渡すためにkwargs={'y': 200} t3 = threading.Thread(target=parallel_processing3, args=(100,), kwargs={'y': 200}) t3.start() |
すべてのサンプルコードを実行する
すべてのサンプルコードを1つにまとめて実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# スレッドをインポート import threading # スリープを使ってプログラムを待機させるので、timeをインポート import time def processing1(): # 関数の名前をプリント print('関数1 : 開始') #待機 1秒 time.sleep(1) #関数が終了したことをプリント print('関数1 : 終了') def parallel_processing1(): # 現在のスレッド(並列処理)が開始したことをプリント print('並列処理1 : 開始') # 待機 10秒 time.sleep(10) # 現在のスレッド(並列処理)が終了したことをプリント print('並列処理1 : 終了') def parallel_processing2(): # 現在のスレッド(並列処理)が開始したことをプリント print('並列処理2 : 開始') # 待機 5秒 time.sleep(5) # 現在のスレッド(並列処理)が終了したことをプリント print('並列処理2 : 終了') def parallel_processing3(x, y=1): # 現在のスレッド(並列処理)が開始したことをプリント print('並列処理3_引数有り : 開始') print('引数x:', x) print('引数y:', y) # 待機 6秒 time.sleep(7) # 現在のスレッド(並列処理)が終了したことをプリント print('並列処理3_引数有り : 終了') if __name__ == '__main__': # 1つ目の関数を実行させる processing1() # スレッドを2つ走らせる # tagetで走らせる関数を渡す。 t1 = threading.Thread(target=parallel_processing1) t2 = threading.Thread(target=parallel_processing2) # t1とt2を平行で走らせる # スレッド1を走らせる t1.start() # 1秒待機 time.sleep(1) # スレッド2を走らせる t2.start() # 引数を渡す # x引数をタプルで渡すためにargs=(100,)カンマを入れている # y引数を辞書型渡すためにkwargs={'y': 200} t3 = threading.Thread(target=parallel_processing3, args=(100,), kwargs={'y': 200}) t3.start() |
実行結果はこちら
まとめ
今回はPythonでデイトレードの自動売買システムを構築する際に必要と思われる、並列処理[スレッド]の解説をしました。
時間差で複数の関数が実行されるので、文字よりも動画で見た方がわかりやすいかも知れません。
追って動画も作成するつもりですので、動画でも見たいと思う方はブックマークをしてお待ちいただけると幸いです。
このブログでは、株価分析・システムトレード開発で楽しく学ぶためのPythonプログラミングの小ネタをシリーズで紹介する予定です。
- 株価分析や・システムトレード開発にご興味のある方。
- Pythonを学びはじめたけれど、何に応用したら良いのか分からない。
- Pythonプログラミングのコツを気軽に知りたい。
そんなあなたにピッタリだと思います。
この記事を書いた人
あしおゆたか
投資歴21年の個人投資家
机上の理論ではなく、実体験に基づいた記事作りをモットーにしています。
スポーツクラブに毎週2日~3日通い、サウナ後の暴飲暴食が趣味。(現在自粛中)
◇主な投資対象
日本株式
株式ETF(上場投資信託)
日経225先物
日経225先物オプション
◇運営者情報はこちら