リリース!Bitmex用 データ保存/CSV出力プログラム vol.2 python3 仮想通貨
前回のnoteに書かせてもらいましたが、Bitmexからデータを取得して、データベースへの保存、CSV出力まで行えるプログラムをサクッと作成しました。
使用用途としては、分析用?とかExcelでのバックテストを目的としておきます!笑
まぁ1つのツールとして「ふ~ん」くらいで読んで頂けると幸いです。
一応、一切プログラムを変更していただかなくても、いろんなデータの登録と出力ができるようになっています。
今回、作成したプログラムを実際の使用手順に沿ってご紹介していきます。
1.データ保存の設定
まずはBitmexのローソク足のデータを取得し、データベースへデータを保存します。
まずデータの取得期間と何分足かを設定ファイルにて設定します。
設定ファイルの使用方法についてはコチラ
[SETTING]セクションにはデータベース名とテーブル名を設定します。あと、cloud9で動作させる場合、デフォルトではタイムゾーンがUTC時間(国際標準時間)となっています。UTC時間のままにしておきたい方は「tzone」に9を設定すると、日本時刻でデータベースに保存します。もちろん0にすればUTC時刻で登録します。
cloud9の環境を日本時間に変更したい!って方はコチラを参考にして下さい。
[INSERT]セクションにはデータ取得の開始時間、終了時間、分足の設定をします。今回は、あんまりデータが多すぎても説明しづらいので1日分の1時間足のデータを保存します。
設定内容:2018/05/22~2018/05/23の1時間足
2.モード選択
データ保存用の設定が終了したら、動作させるプログラムを起動していきます。起動後、モード選択を聞かれます。
ちなみにモードは以下の通りです。
1:データ保存モード
2:CSV出力モード
データ保存を行うので「1」を入力し、Enterキーを押してください。
入力後の結果がこんな感じです。
ここに表示されているデータが保存できています。
ちなみにデータベースのテーブルの構造は以下の通りです。
3.CSV出力するデータの設定
それではどのデータをCSV出力するか設定していきましょう。
今回は価格が上昇した足のデータのみ出力してみます。
価格が上昇した場合ですので以下の2項目のみ設定を行います。
①chgp
②chgp_s
「chgp」に1、「chgp_s」に3を設定することで価格の変化量が1以上の時、という条件設定になります。
日付は細かい指定がなければ多めにしておきます。
他の項目は「_s」が付くほうに1~3以外を設定することで条件設定なしにすることができます。
4.CSV出力
それでは再度、「bot.py」を起動します。今回はモード選択で「2」を入力してください。実行結果がこんな感じです。
ファイル名がデータ種類_出力時間.csvで出力します。
今回の場合、「60_20180524212538.csv」
「bot.py」と同じ階層に「data」フォルダを作成し、そこにCSVファイル出力します。
CSVファイルをExcelで開いた結果がこんな感じです。
価格が上昇した足のデータのみ出力できています。
まぁでもとりあえず全部データ出力して、Excelでフィルターかけるほうが使用しやすいですね(笑)
まとめ
少ない時間で作成したにしては頑張ったと思います・・・
エラー発生時にもログを残すようにしているので、設定ファイルの設定ミスとかがあれば分かるとは思います!
でも今回作成してみて、改良の余地はまだまだあると思います。とりあえず、現在取得できる足が少ないので、5分足とかいろんな足でも取得できるようにしたいです。
あと、全く別の機能でも思いつけば何かしら加えていきます。
設定ファイルは公開しますが、ソースに関しては、これまでに有料で公開している内容(600円分)の内容が含まれているので有料とさせてください・・・
ただ、高くするつもりもないのでとりあえず600円にします。
もし使用してみたいという方がいれば、購入していただけるとこれからも頑張れます・・・!
もし購入して頂いた方でバグとか見つけて頂いた場合は、もちろん修正させていただきます!
設定ファイル
動作させるプログラム(bot.py)と同じ階層に「bot.conf」というファイルを作成し、以下の内容をコピペして下さい。
#*********************************************************************
#
# Bitmex用データ保存/CSV出力プログラム
#
# [SETTING]
#
# database : データベースファイルパス
# table : テーブル名
# tzone : 時間調整(例.9=UTC時間の場合、日本時刻に合わせる)
#
#*********************************************************************
[SETTING]
database = ./trade.db
table = t_data
tzone = 0
#*********************************************************************
#
# [INSERT] : データ登録用設定項目
#
# from_date : 登録開始日時 yyyy-MM-dd HH:mm:ssを指定
# to_date : 登録終了日時 yyyy-MM-dd HH:mm:ssを指定
# kind : 登録データ種類(1=1分足 60=1時間足 1440=1日足)
#
#*********************************************************************
[INSERT]
from_date = 2018-05-22 00:00:00
to_date = 2018-05-23 00:00:00
kind = 60
#*********************************************************************
#
# [WHERE] : データ条件設定用項目
#
# from_date : 選択開始日時 yyyy-MM-dd HH:mm:ssを指定
# to_date : 選択終了日時 yyyy-MM-dd HH:mm:ssを指定
# kind : 選択データ種類(0=指定なし 1=1分足 60=1時間足 1440=1日足)
# open : 始値
# high : 高値
# low : 安値
# close : 終値
# vol : 取引量
# chgr : 変化率(%)
# chgp : 変化価格(ドル)
# ****_s : 各項目の範囲(1=等しい 2=以下 3=以上)※左記以外で条件に指定しない
#
#*********************************************************************
[WHERE]
kind = 60
from_date = 2017-01-01 00:00:00
to_date = 2018-05-25 00:00:00
open = 0
high = 0
low = 0
close = 0
vol = 0
chgr = 0
chgp = 0
open_s = 0
high_s = 0
low_s = 0
close_s = 0
vol_s = 0
chgr_s = 0
chgp_s = 0
プログラムファイル
動作させるプログラムファイルの内容です。「bot.py」というファイルを作成してください。その中に以下の内容をコピペして下さい。
※このファイルは動作させるために「chmod」で動作権限を付与する必要があります。
#!/usr/bin/python3
import time
import datetime
import requests
import clsConfig
import clsLogFile
import clsSqlite
clscon = clsConfig.Config() #設定ファイルクラスインスタンス
clslog = clsLogFile.LogFile() #ログファイルクラスインスタンス
clssql = clsSqlite.Sqlite() #SQLite3クラスインスタンス
#==データ種類==
M1 = 1
H1 = 60
D1 = 1440
#ローソク足取得最大数
MAX = 10080
#登録モード
def InsertMode():
stop = False
try:
clslog.add('Mode:InsertMode!')
fm_dt = clscon.getInsertFromDt() #開始日時
to_dt = clscon.getInsertToDt() #終了日時
now = int(time.time()) #現在時間
kind = clscon.getInsertKind() #データ種類
fm_temp = fm_dt + (kind * 60)
tzone = clscon.getTzone()
to_temp = 0
to_old = 0
if fm_dt != 0 and to_dt != 0 and fm_dt < to_dt:
if kind == M1 or kind == H1 or kind == D1:
if clssql.makeTable():
clslog.add('Insert Start!' + ' from(UNIX)=' + str(fm_dt) + ' to(UNIX)=' + str(to_dt) + ' now(UNIX)=' + str(now))
while not stop:
#ローソクデータの取得
to_temp = getToDate(kind, fm_temp, now)
#データ取得用のURL作成
url = 'https://www.bitmex.com/api/udf/history?symbol=XBTUSD&resolution='
url += str(kind) +'&from=' + str(fm_temp) + '&to=' + str(to_temp)
candles = requests.get(url)
tohlcv = candles.json()
length = len(tohlcv['t']) #データの個数を取得
t_val = tohlcv['t'] #日時
o_val = tohlcv['o'] #始値
h_val = tohlcv['h'] #高値
l_val = tohlcv['l'] #安値
c_val = tohlcv['c'] #終値
v_val = tohlcv['v'] #取引量
for i in range(length):
#データ登録
clssql.Insert(kind, t_val[i], o_val[i], h_val[i], l_val[i], c_val[i], v_val[i])
fm_temp = int(t_val[i])
if t_val[i] > now or t_val[i] >= to_dt or to_temp == to_old:
stop = True
break
to_old = to_temp
time.sleep(1)
clslog.add('Insert End!')
else:
clslog.add('[Insert Mode] Table Make error')
else:
clslog.add('[Insert Mode] setting NG! kind=' + str(kind))
else:
clslog.add('[Insert Mode] setting NG! from_date(UNIX)=' +str(fm_dt) + ' to_date(UNIX)=' + str(to_dt))
except Exception as e:
clslog.add('[Insert Mode] error ' + str(e))
#CSVモード
def CsvMode():
try:
clslog.add('Mode:CsvMode!')
kind = clscon.getWhereKind()
now = datetime.datetime.now()
#ファイル名を設定
filename = str(kind) + '_' + '{0:%Y%m%d%H%M%S}'.format(now) + '.csv'
print('filename=' + filename)
ret = []
ret = clssql.Select()
csv = ''
header = 'kind,u_time,d_time,open,high,low,close,vol,chgr,chgp' + '\n'
csv = header
count = 0
for val in ret:
length = len(val)
for i in range(length):
if i != 0:
csv += ','
csv += str(val[i])
csv += '\n'
count += 1
#メモリリークを防ぐため1000行につきデータを出力しておく
if count > 1000:
clslog.add_name(csv, filename)
csv = ''
count = 0
if csv != '':
clslog.add_name(csv, filename)
clslog.add('Csv Out End!')
except Exception as e:
clslog.add('[CSV Mode] error ' + str(e))
#終了日時計算
def getToDate(kind, fm_dt, now):
ret = 0
if kind == M1:
ret = fm_dt + (MAX * 60)
elif kind == H1:
ret = fm_dt + (MAX * 60 * 60)
elif kind == D1:
ret = fm_dt + (MAX * 60 * 60 * 24)
#現在時刻を越えていた場合・・・
if ret > now:
ret = now
return ret
#メイン処理
def main():
try:
mode = 0
print("モードを選択して下さい '1:Insert' or '2:CSV'")
choice = input('>> ')
if choice == '1': #登録モード
InsertMode()
elif choice == '2': #CSV出力モード
CsvMode()
else:
print('Select Mode Nothing!')
except Exception as e:
clslog.add('[main] error ' + str(e))
main()
設定ファイル用クラス
設定ファイル(bot.conf)から設定を取得するためのクラスです。
「bot.py」と同じ階層に「clsConfig.py」というファイルを作成してください。
その中に以下の内容をコピペして下さい
#!/usr/bin/python3
import time
import configparser
import clsLogFile
class Config:
def __init__(self):
self.file = configparser.ConfigParser()
self.fileName = './bot.conf'
self.clslog = clsLogFile.LogFile() #ログファイルクラスインスタンス
self.Setting = 'SETTING'
self.Insert = 'INSERT'
self.Where = 'WHERE'
#読み取り
def getConfigValue(self, Section, Key, Def = ''):
ret = ''
try:
self.file.read(self.fileName, 'UTF-8')
ret = self.file.get(Section, Key)
except Exception as e:
ret = str(Def)
print('[getConfigValue] error ' + str(e))
return ret
#書き込み
def setConfigValue(self, Section, Key, Value):
ret = True
try:
self.file.set(Section, Key, str(Value))
self.file.write(open(self.fileName, 'w'))
except Exception as e:
ret = False
print('[setConfigValue] error ' + str(e))
return ret
#****SETTING*****
#データベースファイルパス
def getDB(self):
ret = ''
try:
ret = self.getConfigValue(self.Setting, 'database', './trade.db')
except Exception as e:
ret = ''
self.clslog.add('[getDB] error ' + str(e))
return ret
#テーブル名
def getTable(self):
ret = ''
try:
ret = self.getConfigValue(self.Setting, 'table', 't_data')
except Exception as e:
ret = ''
self.clslog.add('[getTable] error ' + str(e))
return ret
#時間調整
def getTzone(self):
ret = 0
try:
ret = int(self.getConfigValue(self.Setting, 'tzone', 0)) * 60 * 60
except Exception as e:
ret = ''
self.clslog.add('[getTzone] error ' + str(e))
return ret
#****INSERT*****
#開始日時
def getInsertFromDt(self):
ret = 0
try:
date = self.getConfigValue(self.Insert, 'from_date', '1999-01-01 00:00:00')
date = time.strptime(date, "%Y-%m-%d %H:%M:%S")
ret = int(time.mktime(date))
except Exception as e:
ret = 0
self.clslog.add('[getInsertFromDt] error ' + str(e))
return ret
#終了日時
def getInsertToDt(self):
ret = 0
try:
date = self.getConfigValue(self.Insert, 'to_date', '2099-12-31 00:00:00')
date = time.strptime(date, "%Y-%m-%d %H:%M:%S")
ret = int(time.mktime(date))
except Exception as e:
ret = 0
self.clslog.add('[getInsertToDt] error ' + str(e))
return ret
#データ種類
def getInsertKind(self):
ret = 0
try:
ret = int(self.getConfigValue(self.Insert, 'kind', 0))
except Exception as e:
ret = 0
self.clslog.add('[getInsertKind] error ' + str(e))
return ret
#****WHERE*****
#データ種類
def getWhereKind(self):
ret = 0
try:
ret = int(self.getConfigValue(self.Where, 'kind', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereKind] error ' + str(e))
return ret
#開始日時
def getWhereFromDt(self):
ret = 0
try:
date = self.getConfigValue(self.Where, 'from_date', '1999-01-01 00:00:00')
date = time.strptime(date, "%Y-%m-%d %H:%M:%S")
ret = int(time.mktime(date))
except Exception as e:
ret = 0
self.clslog.add('[getWhereFromDt] error ' + str(e))
return ret
#終了日時
def getWhereToDt(self):
ret = 0
try:
date = self.getConfigValue(self.Where, 'to_date', '2099-12-31 00:00:00')
date = time.strptime(date, "%Y-%m-%d %H:%M:%S")
ret = int(time.mktime(date))
except Exception as e:
ret = 0
self.clslog.add('[getWhereToDt] error ' + str(e))
return ret
#始値
def getWhereOpen(self):
ret = 0
try:
ret = float(self.getConfigValue(self.Where, 'open', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereOpen] error ' + str(e))
return ret
#高値
def getWhereHigh(self):
ret = 0
try:
ret = float(self.getConfigValue(self.Where, 'high', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereHigh] error ' + str(e))
return ret
#安値
def getWhereLow(self):
ret = 0
try:
ret = float(self.getConfigValue(self.Where, 'low', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereLow] error ' + str(e))
return ret
#終値
def getWhereClose(self):
ret = 0
try:
ret = float(self.getConfigValue(self.Where, 'close', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereClose] error ' + str(e))
return ret
#取引量
def getWhereVol(self):
ret = 0
try:
ret = float(self.getConfigValue(self.Where, 'vol', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereVol] error ' + str(e))
return ret
#変化率
def getWhereChgr(self):
ret = 0
try:
ret = float(self.getConfigValue(self.Where, 'chgr', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereChgr] error ' + str(e))
return ret
#変化価格
def getWhereChgp(self):
ret = 0
try:
ret = float(self.getConfigValue(self.Where, 'chgp', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereChgp] error ' + str(e))
return ret
#始値 符号
def getWhereOpenSign(self):
ret = 0
try:
ret = int(self.getConfigValue(self.Where, 'open_s', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereOpenSign] error ' + str(e))
return ret
#高値 符号
def getWhereHighSign(self):
ret = 0
try:
ret = int(self.getConfigValue(self.Where, 'high_s', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereHighSign] error ' + str(e))
return ret
#安値 符号
def getWhereLowSign(self):
ret = 0
try:
ret = int(self.getConfigValue(self.Where, 'low_s', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereLowSign] error ' + str(e))
return ret
#終値 符号
def getWhereCloseSign(self):
ret = 0
try:
ret = int(self.getConfigValue(self.Where, 'close_s', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereCloseSign] error ' + str(e))
return ret
#取引量 符号
def getWhereVolSign(self):
ret = 0
try:
ret = int(self.getConfigValue(self.Where, 'vol_s', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereVolSign] error ' + str(e))
return ret
#変化率 符号
def getWhereChgrSign(self):
ret = 0
try:
ret = int(self.getConfigValue(self.Where, 'chgr_s', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereChgrSign] error ' + str(e))
return ret
#変化価格 符号
def getWhereChgpSign(self):
ret = 0
try:
ret = int(self.getConfigValue(self.Where, 'chgp_s', 0))
except Exception as e:
ret = 0
self.clslog.add('[getWhereChgpSign] error ' + str(e))
return ret
ログファイル・CSV出力用クラス
ログファイル、CSV出力を行うためのクラスです。
「bot.py」と同じ階層に「clsLogFile.py」というファイルを作成してください。
その中に以下の内容をコピペして下さい。
#!/usr/bin/python3
import datetime
import os
#ログ書き込みクラス
class LogFile:
def __init__(self):
init = 0
#ログ書き込み
def add(self, value):
try:
now = datetime.datetime.now() #現在時刻取得
#フォルダが無ければ作成
path = './log'
if not os.path.exists(path):
os.mkdir(path)
filepath = path + '/' + '{0:%Y%m%d}.log'.format(now)
msg = '{0:%Y/%m/%d %H:%M:%S}'.format(now) + ' ' + str(value) + '\n'
file = open(filepath,'a')
file.write(msg)
file.close()
print(msg)
except Exception as e:
print('[add] error ' + str(e))
#ファイル名を指定してのログ書き込み
def add_name(self, value, filename):
try:
#フォルダが無ければ作成
path = './data'
if not os.path.exists(path):
os.mkdir(path)
filepath = path + '/' + filename
msg = str(value) + '\n'
file = open(filepath,'a')
file.write(msg)
file.close()
print(msg)
except Exception as e:
print('[add_name] error ' + str(e))
データベース用クラス
データベース操作のためのクラスです。
「bot.py」と同じ階層に「clsSqlite.py」というファイルを作成してください。
その中に以下の内容をコピペして下さい。
#!/usr/bin/python3
import datetime
import sqlite3
import clsLogFile
import clsConfig
#SQLite3クラス
class Sqlite:
def __init__(self):
self.clscon = clsConfig.Config() #設定ファイルクラスインスタンス
self.clslog = clsLogFile.LogFile() #ログファイルクラスインスタンス
self.database = self.clscon.getDB() #データベースファイルパス
self.table = self.clscon.getTable() #テーブル名
#データ取得
def ReadSql(self, sql):
ret = []
try:
#DB接続とカーソル生成
connection = sqlite3.connect(self.database)
#自動コミットON
connection.isolation_level = None
cursor = connection.cursor()
cursor.execute(sql)
ret = cursor.fetchall()
# 接続を閉じる
connection.close()
except Exception as e:
ret = []
self.clslog.add('[ReadSql] error ' + str(e) + ' sql=' + str(sql))
return ret
#データ書込
def WriteSql(self, sql):
ret = True
try:
#DB接続とカーソル生成
connection = sqlite3.connect(self.database)
#自動コミットON
connection.isolation_level = None
cursor = connection.cursor()
cursor.execute(sql)
# 接続を閉じる
connection.close()
except Exception as e:
ret = False
self.clslog.add('[WriteSql] error ' + str(e) + 'sql=' + str(sql))
return ret
#テーブル作成
def makeTable(self):
ret = True
sql = ''
try:
#テーブルがなければ作成
if not self.tExist():
#テーブルの作成
sql += 'CREATE TABLE ' + self.table
sql += '('
sql += 'kind integer,' #データ種類(1=1分足, 60=1時間足)
sql += 'u_time integer,' #日時(UNIX時間)
sql += 'd_time text,' #日時
sql += 'open real,' #始値
sql += 'high real,' #高値
sql += 'low real,' #安値
sql += 'close real,' #終値
sql += 'vol integer,' #取引量
sql += 'chgr real,' #変化率
sql += 'chgp real,' #変化価格
sql += 'primary key(kind, u_time)' #主キーの設定(種類,日時)
sql += ')'
ret = self.WriteSql(sql)
except Exception as e:
ret = False
self.clslog.add('[makeTabel] error ' + str(e))
return ret
#テーブル存在有無
def tExist(self):
ret = True
#DB接続とカーソル生成
connection = sqlite3.connect(self.database)
try:
#自動コミットON
connection.isolation_level = None
cursor = connection.cursor()
cursor.execute('SELECT * FROM ' + self.table)
res = cursor.fetchall()
except:
ret = False
self.clslog.add(self.table + ' not exist!')
finally:
# 接続を閉じる
connection.close()
return ret
#データ登録
def Insert(self, kind, date, open, high, low, close, vol):
ret = True
sql = ''
try:
select = self.mSelect('where kind=' + str(kind) + ' and u_time=' + str(date))
if len(select) == 0:
d_time = datetime.datetime.fromtimestamp(date)
sql += 'INSERT INTO ' + self.table + ' VALUES'
sql += '('
sql += str(kind) + ',' #データ種類(1=1分足, 60=1時間足)
sql += str(date) + ',' #日時(UNIX時間)
sql += "'" + str(d_time) + "'," #日付(yyyy-MM-dd HH:mm:ss)
sql += str(open) + ',' #始値
sql += str(high) + ',' #高値
sql += str(low) + ',' #安値
sql += str(close) + ',' #終値
sql += str(vol) + ',' #取引量
sql += str((close-open)/open*100) + ',' #変化率
sql += str(close-open) #変化価格
sql += ')'
ret = self.WriteSql(sql)
#登録データの表示
msg_data = str(kind) + ',' + str(date) + ',' + str(d_time) + ',' + str(open) + ','
msg_data += str(high) + ',' + str(low) + ',' + str(close) + ',' + str(vol) + ','
msg_data += str(round((close-open)/open*100, 1)) + ',' + str(round(close - open, 1))
print(msg_data)
except Exception as e:
ret = False
self.clslog.add('[Insert] error ' + str(e) + ' sql=' + sql)
return ret
#データ取得用
def Select(self):
ret = []
sql = ''
where = ''
try:
sql += 'SELECT * '
sql += 'FROM ' + self.table
#条件を設定
where += self.makeWhere(where, 'kind', self.clscon.getWhereKind(), 1)
where += self.makeWhere(where, 'u_time', self.clscon.getWhereFromDt(), 3)
where += self.makeWhere(where, 'u_time', self.clscon.getWhereToDt(), 2)
where += self.makeWhere(where, 'open', self.clscon.getWhereOpen(), self.clscon.getWhereOpenSign())
where += self.makeWhere(where, 'high', self.clscon.getWhereHigh(), self.clscon.getWhereHighSign())
where += self.makeWhere(where, 'low', self.clscon.getWhereLow(), self.clscon.getWhereLowSign())
where += self.makeWhere(where, 'close', self.clscon.getWhereClose(), self.clscon.getWhereCloseSign())
where += self.makeWhere(where, 'vol', self.clscon.getWhereVol(), self.clscon.getWhereVolSign())
where += self.makeWhere(where, 'chgr', self.clscon.getWhereChgr(), self.clscon.getWhereChgrSign())
where += self.makeWhere(where, 'chgp', self.clscon.getWhereChgp(), self.clscon.getWhereChgpSign())
sql += where
ret = self.ReadSql(sql)
print(sql)
except Exception as e:
ret = []
self.clslog.add('[Select] error ' + str(e))
return ret
#条件作成
def makeWhere(self, where, col, val, sign):
sql = ''
try:
#1~3以外は無効とみなす
if 1 <= sign and sign <= 3:
if where == '':
sql += ' WHERE '
else:
sql += 'AND '
sql += col + ' '
if sign == 1: #等しい
sql += '='
elif sign == 2: #以下
sql += '<='
elif sign == 3: #以上
sql += '>='
sql += str(val) + ' '
except Exception as e:
self.clslog.add('[makeWhere] error ' + str(e))
return sql
#一致データ取得用
def mSelect(self, option = ''):
ret = []
sql = ''
where = ''
try:
sql += 'SELECT * '
sql += 'FROM ' + self.table
if option != '':
sql += ' ' + option
ret = self.ReadSql(sql)
except Exception as e:
ret = []
self.clslog.add('[mSelect] error ' + str(e) + ' sql=' + str(sql))
return ret
一応フォルダ構成をもう一度貼っておきます。基本的に「bot.py」と同じ階層にすべてのファイルを作成するだけです。「data」「log」フォルダは勝手にできます。「trade.db」も勝手にできます。
これまでにないくらいの長文のプログラムになったのでバグがある可能性はあります。自分でも発見しだい修正を行っていきます。なにかお気付きの点があれば教えていただけると幸いです。
以上、ありがとうございました。