ヾ(´・ω・`)ノ゙

In [1]:
%matplotlib inline
import itertools

import numpy as np
import pandas as pd
from pandas import DataFrame, Series
import matplotlib.pyplot as plt
import seaborn as sns
import tqdm # ←これいい感じですな(´・ω・`)

from IPython.core.display import display
In [2]:
%load_ext autoreload
%autoreload 2
In [3]:
print(np.__version__)
print(pd.__version__)
1.10.4
0.18.1

↓ 少しコード量が多めなのでモジュールとして読み込みます

In [4]:
import test20170421.tester as tester
import test20170421.util as u
In [ ]:
 

このデータを使ってみます

In [5]:
df = u.read_hst('data/USDJPY60.hst')
print('data len', len(df))
df.head(5)
data len 63718
Out[5]:
Open High Low Close Volume
Time
2007-01-02 07:00:00 119.01 119.03 118.91 118.96 240
2007-01-02 08:00:00 118.96 118.98 118.87 118.89 240
2007-01-02 09:00:00 118.89 118.92 118.54 118.58 240
2007-01-02 10:00:00 118.58 118.73 118.55 118.72 240
2007-01-02 11:00:00 118.72 118.75 118.66 118.74 240

超簡単なテストストラテジー

In [6]:
class TestStrategy(tester.Tester):
    
    def __init__(self, df):
        super(TestStrategy, self).__init__(df)
    
    def set_signal(self, period_a=50, period_b=100):
        ma_a = u.EMA(self.Close, period_a)
        ma_b = u.EMA(self.Close, period_b)
        self.ob = ma_a>ma_b
        self.os = ma_a<ma_b
        self.cb = self.os
        self.cs = self.ob

bt = TestStrategy(df)
bt.set_signal()
res = bt.run(rettype_df=True)
res[['pl']].set_index(res['ct']).cumsum().plot(figsize=(15,3))
Out[6]:
<matplotlib.axes._subplots.AxesSubplot at 0xc05f400>
In [7]:
param_a = u.ma_params(5, 200, 30)
param_b = u.ma_params(10, 400, 30)
print('A', param_a)
print('B', param_b)
A [  5   6   6   7   8   9  11  12  14  16  18  20  23  26  30  34  38  43
  49  56  64  72  82  93 106 120 137 155 176 200]
B [ 10  11  13  15  17  19  21  24  28  31  36  41  46  52  59  67  77  87
  99 112 127 145 164 186 212 240 273 310 352 400]

とりあえず ↑ の組み合わせをテストしてみます

In [8]:
%%time
res_df = DataFrame(index=param_a, columns=param_b, dtype=float)
bt = TestStrategy(df)
bt.set_testbar('20080101')

best_param = None
best_score = 0

for p in itertools.product(param_a, param_b):
    bt.set_signal(*p)
    res = bt.run(rettype_df=False)
    res -= 0.01 # 1トレード当たり1pipsをスプレッドとして引いとく
    a, b = p
    score = res.sum()
    res_df.loc[a][b] = score
    if score>best_score:
        best_score = score
        best_param = p

print('best', best_param, best_score)
bt.set_signal(*best_param)
res = bt.run(rettype_df=True)
(res[['pl']]-0.01).set_index(res['ct']).cumsum().plot(figsize=(15,3))
best (11, 17) 64.229
Wall time: 908 ms

↑ まぁさすがにこれだけじゃ微妙な結果になりますな(´・ω・`)

ma2本使って単に損益の大きいものを選択しただけなので

In [9]:
sns.heatmap(res_df[::-1], annot=True, fmt='.1f', figure=plt.figure(figsize=(15, 8)))
plt.ylabel('ma param a')
plt.xlabel('ma param b')
Out[9]:
<matplotlib.text.Text at 0xbfb81d0>