妻は金融業界に従事しており、最近私が Python を学んでいると聞いて、バックテスト用のコードを書くのを手伝ってほしいと言われました。
データセットは 2 つの Excel ファイルがあります。
最初の Excel ファイルには、過去 1000 日間の毎日の始値、最高値、最低値、終値が含まれており、妻が設定したパラメータ値 f1、f2、f3 があります。
2 つ目の Excel ファイルには、特定の日の 24 時間または部分的な時間の始値、最高値、最低値、終値が含まれています。
構造は以下の図の通りです:
data_day.xlsx
data_hour.xlsx
要求は、2 つの表の日付が同じ日を見つけたときに、
最初の表の前日の 4 つのポイントと 3 つのパラメータを使用して、その日の必要な Bbreak と Sbreak を求めることです。
次に、その日のすべての時間のデータを比較し、最高値が Bbreak を超えた場合、買いポイントの数を 1 増やします。最低値が Sbreak を下回った場合、売りポイントの数を 1 増やします。
最初にオプションを追加し、ベースラインを設定するかどうかを尋ねます。
ベースラインを設定した場合、その日の最高値から Bbreak を引いた値がベースラインの値を超えた場合、ベースラインの買いポイントを 1 増やします。Sbreak から最低値を引いた値がベースラインの値を超えた場合、ベースラインの売りポイントを 1 増やします。
最後に、合計 4 つの売買ポイントをヒストグラムで表示します。
もちろん、妻は私のこれが実際には厳密ではないと言っています。常に改善が必要です。
さて、コードは以下の通りです:
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Tue Jun 13 10:24:50 2017
@author: hans
"""
import matplotlib.pyplot as plt
import xlrd
currency = str(raw_input("通貨の種類を入力してください: "))
if currency == "eur":
cur_index = 0
elif currency == "xau":
cur_index = 1
elif currency == "GBP":
cur_index = 2
elif currency == "jpy":
cur_index = 3
elif currency == "cad":
cur_index = 4
else:
print "エラー、間違ったタイプを入力しました"
exit()
opt = str(raw_input("ベースラインを設定しますか? (はい/いいえ)\n"))
if opt == 'はい':
bl = float(raw_input("ベースラインを入力してください: "))
bp_day = []
blbp_day = []
sp_day = []
blsp_day = []
date = []
index = []
data_day = xlrd.open_workbook('./data/data_day.xlsx')
table_day = data_day.sheets()[cur_index]
nrows_day = table_day.nrows
data_hour = xlrd.open_workbook('./data/data_hour.xlsx')
table_hour = data_hour.sheets()[cur_index]
nrows_hour = table_hour.nrows
def getdate(table, row):
date = xlrd.xldate_as_tuple(table.cell(row, 2).value, 0)
short_date = date[0:3]
return short_date
def getbenchmark(row):
Close = table_day.cell(row, 6).value
Low = table_day.cell(row, 5).value
High = table_day.cell(row, 4).value
f1 = table_day.cell(row, 7).value
f3 = table_day.cell(row, 9).value
Bsetup = Low - f1 * (High - Close)
Ssetup = High + f1 * (Close - Low)
Bbreak = Ssetup + f3 * (Ssetup - Bsetup)
Sbreak = Bsetup - f3 * (Ssetup - Bsetup)
return Bbreak, Sbreak
def autolabel(hists, local):
for hist in hists:
num = hist.get_height()
if local == 1:
plt.text(hist.get_x() + hist.get_width()/10., num + 0.1, '%s' %int(num))
elif local == -1:
plt.text(hist.get_x() + hist.get_width()/10., -(num + 1.3), '%s' %int(num))
i = 0
for r_day in range(nrows_day-1, 1, -1):
bp = 0
blbp = 0
sp = 0
blsp = 0
short_date_day = getdate(table_day,r_day)
for r_hour in range(nrows_hour-1-i, 1, -1):
short_date_hour = getdate(table_hour, r_hour)
if (short_date_day[0] > short_date_hour[0]):
continue
elif (short_date_day[0] == short_date_hour[0]) and \
(short_date_day[1] > short_date_hour[1]):
continue
elif (short_date_day[0] == short_date_hour[0]) and \
(short_date_day[1] == short_date_hour[1]) and \
(short_date_day[2] > short_date_hour[2]):
continue
elif (short_date_day[0] == short_date_hour[0]) and \
(short_date_day[1] == short_date_hour[1]) and \
(short_date_day[2] == short_date_hour[2]):
i += 1
if r_day+1 >= nrows_day:
continue
else:
Bbreak, Sbreak = getbenchmark(r_day+1)
cur_high = table_hour.cell(r_hour, 4).value
if (cur_high > Bbreak):
bp += 1
if 'bl' in dir() and (cur_high - Bbreak > bl):
blbp += 1
cur_low = table_hour.cell(r_hour, 5).value
if (cur_low < Sbreak):
sp += 1
if 'bl' in dir() and (Sbreak - cur_low > bl):
blsp += 1
else:
break
if bp != 0 or sp != 0:
bp_day.append(bp)
sp_day.append(sp)
date.append('%s/%s' %(short_date_day[1], short_date_day[2]))
if 'bl' in dir():
blbp_day.append(-blbp)
blsp_day.append(-blsp)
for i in range(len(bp_day)):
index.append(i)
bp_hist = plt.bar(tuple(index), tuple(bp_day), color = ('red'), \
label = ('bp'), width = 0.3)
sp_hist = plt.bar(tuple(index), tuple(sp_day), color = ('green'), \
label = ('sp'), width = -0.3)
autolabel(bp_hist, 1)
autolabel(sp_hist, 1)
if 'bl' in dir():
blbp_hist = plt.bar(tuple(index), tuple(blbp_day), color = ('blue'), \
label = ('blbp'), width = 0.3)
blsp_hist = plt.bar(tuple(index), tuple(blsp_day), color = ('yellow'), \
label = ('blsp'), width = -0.3)
autolabel(blbp_hist, -1)
autolabel(blsp_hist, -1)
plt.xticks(tuple(index), tuple(date))
plt.title('アービトラージポイント')
plt.legend()
plt.show()