3
3

More than 1 year has passed since last update.

株価シュミレーター(?)を作る(1)

Last updated at Posted at 2021-11-05

今回から数回に分けて、Pythonを使った「なんちゃって株価データ作成ツール」の解説をさせて頂きます。

本来であれば、前回のデータ生成ツールの公開・共有をさせて頂く予定でしたが、別件でEqualumが自動的に即時掻き集めてくるデータを、SingleStore上で瞬時に(10数億件を3秒以内にSQL処理した国内実績・・)処理して、機械学習経由のAI予測・・という話が飛び込んできましたので、急遽の方針変更で株価(的な)データ生成ツールを作ってみました。

出来上がるとこんな感じ・・・・

今回は、デモ等で使い易くするためにGUIベースのツールとして作成します。基本的には、計算に必要なパラメータを設定して、ボタンの選択イベントで計算・処理等を制御する仕組みになります。

スクリーンショット 2021-11-05 8.45.21.png

Pythonコードの立ち上がりの部分

今回も、NDA(ノン・ダメ出し・アグリーメント)を条件に、相変わらず癖の強い書き方で「ひたすら動けば良い!」系の力技で行きます。
最初のブロックは、お約束の事前設定等を行っている部分になります。

使用を想定するデータベースは、Equalum用にCDC設定したMySQLと、ノーマルのMySQL(ターゲット側)、あとインメモリ性能検証用にSingleStoreを選択出来る様にしました。(データベース周りの設定は適宜現場合わせでお願い致します・・・)

#
#  株価シュミレータ  V1.0
#
import tkinter as tk
from tkinter import ttk
import numpy as np
import random
import matplotlib.pyplot as plt
import time
import datetime
import pymysql.cursors
#
# 日本語フォントの設定
from matplotlib import rcParams
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Hiragino Maru Gothic Pro', 'Yu Gothic', 'Meirio', 'Takao', 'IPAexGothic', 'IPAPGothic', 'VL PGothic', 'Noto Sans CJK JP']
#
# ソース側のMySQL情報
CDC_Host = "xxx.xxx.xxx.xxx"
CDC_Port = 3306
CDC_User = "xxxxx"
CDC_Pass = "xxxxx"
CDC_DB = "xxxxx"
CDC_Char = "utf8mb4"
#
# ターゲット側のMySQL情報
TGT_Host = "yyy.yyy.yyy.yyy"
TGT_Port = 3306
TGT_User = "yyyyy"
TGT_Pass = "yyyyy"
TGT_DB = "yyyyy"
TGT_Char = "utf8mb4"
#
# SigleStoreへ出力
SS_Host = "zzz.zzz.zzz.zzz"
SS_Port = 3306
SS_User = "zzzzz"
SS_Pass = "zzzzz"
SS_DB = "zzzzz"
SS_Char = "utf8"
#
T_Name = "Stock_Demo"
#
# 使用する共通SQL定義
DB_Insert = "INSERT INTO "
DB_Init = "DROP TABLE IF EXISTS "
DB_Create = "CREATE TABLE IF NOT EXISTS "
DB_VALUE = "VALUES"
#
# MySQL_CDCで使用するテーブル定義
CDC_DC0 = "id_CDC INT AUTO_INCREMENT, ts_CDC DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6), "
CDC_DC1 = "Demo_ts DATETIME(6), Stock1 DECIMAL(9,4), Stock2 DECIMAL(9,4), Stock3 DECIMAL(9,4), "
CDC_DC2 = "PRIMARY KEY(id_CDC,  ts_CDC)"
#
CDC_DL1 = "Demo_ts, Stock1, Stock2, Stock3"
#
# MySQL_TGTで使用するテーブル定義
TGT_DC0 = "id_TGT INT AUTO_INCREMENT, ts_TGT DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6), "
TGT_DC1 = "Demo_ts DATETIME(6), Stock1 DECIMAL(9,4), Stock2 DECIMAL(9,4), Stock3 DECIMAL(9,4), "
TGT_DC2 = "id_CDC INT, ts_CDC DATETIME(6), PRIMARY KEY(id_TGT,  ts_TGT)"
#
# SingleStoreで使用するテーブル定義
SS_DC0 = "id_SS BIGINT AUTO_INCREMENT, ts_SS TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6), "
SS_DC1 = "Demo_ts DATETIME(6), Stock1 DECIMAL(9,4), Stock2 DECIMAL(9,4), Stock3 DECIMAL(9,4), "
SS_DC2 = "SHARD KEY (ts_SS), PRIMARY KEY(id_SS,  ts_SS)"
#
SS_DL1 = "Demo_ts, Stock1, Stock2, Stock3"
#
# 処理の過程で使うメッセージ
CT_Message1 = "作業に必要なテーブルを作成します。"
CT_Message2 = "作業に必要なテーブルを作成しました。"
TGT_Message1 = "Equalum用のTGTテーブルを作成します。"
TGT_Message2 = "Equalum用のTGTテーブルが作成されました。"
GEN_Message1 = "データの生成・挿入処理を開始します。"
GEN_Message2 = "データの生成・挿入処理が終了しました。"
RUN_Message = "株価シュミレーション・ツールを起動します。"
EXT_Message = "全ての処理が終了しました。"
#
ON = 1
OFF = 0
#
SingleStore = 0
MySQL_CDC = 1
MySQL_TGT = 2
#
Delay = 500 # プログレスバーの更新遅延(この設定では約0.5秒)
#

実際の処理部分について・・・・

此処からは、実際にPythonのロジックで処理を行う流れが記述されています。
各種の初期設定の後に、データベース接続、テーブル生成、処理過程をアニメ表示するプログレスバー、GUI全体を終了する関数等があります。

print("------------------------------------------------")
print("******************* 処理開始 *******************")
print(datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + " : " + RUN_Message)
print("------------------------------------------------")
#
# Fakerの初期化
from faker import Faker
fakegen = Faker('ja_JP')    
Faker.seed(fakegen.random_digit())
#
# GUI部分の作成
root = tk.Tk()
root.title("株価シュミレーター")
root.geometry("600x500")
#
# GUIスタイルの設定(この設定の場合、プログレスバーが太く表示される)
style = ttk.Style()
style.theme_use('default')
#
# SQL処理の状況表示
style.configure("Orange.Horizontal.TProgressbar", foreground='orange', background='orange')
#
# アプリの終了とウインドウの消去
def Exit_Tool(): root.destroy()
#
# SQL処理プログレスバーの更新
def var_start1(value_bar): progressbar1.configure(value=value_bar)
#
# データベースとの接続とテーブルの作成
def Open_DB(DB_Type):

    if DB_Type == SingleStore:

        Host_Info = SS_Host
        Port_Info = SS_Port
        User_Info = SS_User
        Pass_Info = SS_Pass
        DB_Info   = SS_DB
        Char_Info = SS_Char

    elif DB_Type == MySQL_CDC:

        Host_Info = CDC_Host
        Port_Info = CDC_Port
        User_Info = CDC_User
        Pass_Info = CDC_Pass
        DB_Info   = CDC_DB
        Char_Info = CDC_Char

    elif DB_Type == MySQL_TGT:

        Host_Info = TGT_Host
        Port_Info = TGT_Port
        User_Info = TGT_User
        Pass_Info = TGT_Pass
        DB_Info   = TGT_DB
        Char_Info = TGT_Char

    # ターゲットのデータベースに接続してポインタを取得
    db = pymysql.connect(host = Host_Info, port = Port_Info, user = User_Info, password = Pass_Info, db = DB_Info, charset = Char_Info, cursorclass = pymysql.cursors.DictCursor)     

    # データベース処理に必要なポインタを戻す
    return(db)
#
# テーブルの作成
def Create_Table(DB_Type):

    # 初期化SQL(共通)
    Init_SQL = DB_Init + T_Name

    # テーブル作成SQL(個別)
    if DB_Type == SingleStore: Create_SQL = DB_Create + T_Name + " (" + SS_DC0 + SS_DC1 + SS_DC2 + ")" 
    elif DB_Type == MySQL_CDC: Create_SQL = DB_Create + T_Name + " (" + CDC_DC0 + CDC_DC1 + CDC_DC2 + ")" 
    elif DB_Type == MySQL_TGT: Create_SQL = DB_Create + T_Name + " (" + TGT_DC0 + TGT_DC1 + TGT_DC2 + ")"

    # 指定されたデータベースと接続
    db = Open_DB(DB_Type)

    # 指定されたDB上に所定のテーブルを作成
    with db.cursor() as cursor:

        # 既存テーブルの初期化
        cursor.execute(Init_SQL)
        db.commit()

        # 新規にテーブルを作成
        cursor.execute(Create_SQL)
        db.commit()

    # 接続を解放して終了
    db.close()

今回のまとめ

今回は、急遽飛び込んできた検証用ツール紹介の第1回目として、出来上がりのイメージとPythonの前半部分を紹介させて頂き増した。
因みに今回のツールを動かして、別途作成した専用の「生成データ確認用可視化ツール」を使うと、下記の様なデータの可視化を行う事が可能です。

この例では、地味に安定する銘柄と、堅調に値上がりする銘柄、あと劇的に仕手戦?的な動きの銘柄が可視化されています。
想定通りの良い感じの「なんちゃって株価データ」が出来上がっているようですね・・・・

スクリーンショット 2021-11-05 9.01.18.png

次回は、引き続きメインの中盤部分のコード共有と紹介をさせて頂ければと思います。

株価シュミレーター(?)を作る(2)はこちら
株価シュミレーター(?)を作る(3)はこちら
株価シュミレーターの計算結果確認ツール作成はこちら

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3