• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revision779c588998898345a1895b59ad2e6817ff2d43ee (tree)
Zeit2023-02-15 06:37:05
Autorkazuhiro_kondow <simauma.circus@gmai...>
Commiterkazuhiro_kondow

Log Message

loggerのLogファイルがローテーションしない事象を修正

macd判定が誤る事象について
毎分計算し直すと前回結果が異なると判明
内部に前回結果を退避して改善を試みる

転換点判定を何度も判定しないようにフラグ設定

Ändern Zusammenfassung

Diff

--- a/.gitignore
+++ b/.gitignore
@@ -20,4 +20,5 @@ __pycache__/
2020 *.json
2121 *.log*
2222 Docs/.~lock.memo.ods#
23-*.spec
\ No newline at end of file
23+*.spec
24+*.csv
\ No newline at end of file
--- /dev/null
+++ b/investigation_study/check_exchange_rate_info.py
@@ -0,0 +1,75 @@
1+import numpy as np
2+from numpy import linalg as LA
3+
4+
5+# テクニカル分析
6+TECHNICAL_UNCHANGED = 0
7+TECHNICAL_GOLDEN_CROSS = 1
8+TECHNICAL_DEAD_CROSS = 2
9+TECHNICAL_UPTREND = 3
10+TECHNICAL_DOWNTREND = 4
11+
12+
13+def crossover(series1: np.ndarray, series2: np.ndarray) -> bool:
14+ return series1[-2] < series2[-2] and series1[-1] > series2[-1]
15+
16+
17+def vector_angle(u: np.ndarray, v: np.ndarray):
18+ i = np.inner(u, v)
19+ n = LA.norm(u) * LA.norm(v)
20+ c = i / n
21+ return np.rad2deg(np.arccos(np.clip(c, -1.0, 1.0)))
22+
23+
24+# 確認したい動作
25+# 2023-02-14 06:14:02,857 13268 MainThread exchange_rate_info.py:197 set_technical_indicators [DEBUG]: num[-2]: MACD: -0.018727, MACDSignal: -0.017417 <
26+# 2023-02-14 06:14:02,858 13268 MainThread exchange_rate_info.py:197 set_technical_indicators [DEBUG]: num[-1]: MACD: -0.018409, MACDSignal: -0.017507 <
27+# 2023-02-14 06:14:02,860 13268 MainThread exchange_rate_info.py:202 set_technical_indicators [DEBUG]: vector angle:0.6382709010386011
28+# 2023-02-14 06:15:02,500 13268 MainThread exchange_rate_info.py:197 set_technical_indicators [DEBUG]: num[-2]: MACD: -0.01741, MACDSignal: -0.017416 >
29+# 2023-02-14 06:15:02,502 13268 MainThread exchange_rate_info.py:197 set_technical_indicators [DEBUG]: num[-1]: MACD: -0.016186, MACDSignal: -0.017305 >
30+# 2023-02-14 06:15:02,504 13268 MainThread exchange_rate_info.py:202 set_technical_indicators [DEBUG]: vector angle:1.9033600682385448
31+# 2023-02-14 06:15:02,505 13268 MainThread exchange_rate_info.py:239 set_technical_indicators [INFO]: Technical Indicator: Downtrand.
32+# 結果としてはmacd_value_verification.pyで確認した通り、判定時に使用したmacdの値の扱いを考え直す必要がわかった
33+
34+macd = [-0.016186, -0.01741]
35+macdsignal = [-0.017305, -0.017416]
36+
37+v_angle = vector_angle(macd[-2:], macdsignal[-2:])
38+angle = 1.54
39+turning_point: bool | None = None
40+
41+if crossover(macd, macdsignal) and \
42+ v_angle > angle and \
43+ macd[-1] < 0.0:
44+ print('Cross up.')
45+ if turning_point is not True:
46+ # GoldenCross 上昇転換サイン
47+ technical_indicator = TECHNICAL_GOLDEN_CROSS
48+ turning_point = True
49+ msg = 'Technical Indicator: GoldenCros'
50+ else:
51+ print('Already judged goldencros')
52+elif crossover(macdsignal, macd) and \
53+ v_angle > angle and \
54+ macd[-1] > 0.0:
55+ print('Cross down.')
56+ if turning_point is not False:
57+ # DeadCross 降下転換サイン
58+ technical_indicator = TECHNICAL_DEAD_CROSS
59+ turning_point = False
60+ msg = 'Technical Indicator: DeadCros'
61+ else:
62+ print('Already judged deadcros')
63+elif macd[-1] > 0.0:
64+ # 上昇トレンド
65+ technical_indicator = TECHNICAL_UPTREND
66+ msg = 'Technical Indicator: Uptrend.'
67+elif macd[-1] < 0.0:
68+ # 降下トレンド
69+ technical_indicator = TECHNICAL_DOWNTREND
70+ msg = 'Technical Indicator: Downtrand.'
71+else:
72+ # いずれにも該当しない
73+ technical_indicator = TECHNICAL_UNCHANGED
74+ msg = 'Technical Indicator: Unchanged.'
75+print(msg)
--- /dev/null
+++ b/investigation_study/macd_value_verification.py
@@ -0,0 +1,97 @@
1+# 毎回算出するMACDの値は直近の値の影響を強く受ける設計なので
2+# 再計算のたびに値が変わる
3+
4+# 2023 - 02 - 14 06: 10: 02, 406 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-2]: MACD: -0.020016, MACDSignal: -0.016616
5+# 2023 - 02 - 14 06: 10: 02, 407 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-1]: MACD: -0.020261, MACDSignal: -0.016947
6+# 2023 - 02 - 14 06: 11: 02, 049 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-2]: MACD: -0.01968, MACDSignal: -0.016894
7+# 2023 - 02 - 14 06: 11: 02, 050 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-1]: MACD: -0.019248, MACDSignal: -0.017108
8+# 2023 - 02 - 14 06: 12: 02, 583 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-2]: MACD: -0.019278, MACDSignal: -0.017111
9+# 2023 - 02 - 14 06: 12: 02, 583 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-1]: MACD: -0.01886, MACDSignal: -0.01727
10+# 2023 - 02 - 14 06: 13: 02, 208 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-2]: MACD: -0.019039, MACDSignal: -0.017286
11+# 2023 - 02 - 14 06: 13: 02, 210 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-1]: MACD: -0.018787, MACDSignal: -0.017423
12+
13+# 2023 - 02 - 14 06: 14: 02, 857 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-2]: MACD: -0.018727, MACDSignal: -0.017417 >
14+# 2023 - 02 - 14 06: 14: 02, 858 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-1]: MACD: -0.018409, MACDSignal: -0.017507 >
15+# mt5上ではグラフが交差した部分は直近2データが変わっている、本来なら前回最新が次回2個目のデータと近似するはず・・・
16+# 2023 - 02 - 14 06: 15: 02, 500 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-2]: MACD: -0.01741, MACDSignal: -0.017416 <
17+# 2023 - 02 - 14 06: 15: 02, 502 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-1]: MACD: -0.016186, MACDSignal: -0.017305 <
18+
19+# 2023 - 02 - 14 06: 16: 02, 159 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-2]: MACD: -0.016171, MACDSignal: -0.017303
20+# 2023 - 02 - 14 06: 16: 02, 161 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-1]: MACD: -0.015187, MACDSignal: -0.017111
21+# 2023 - 02 - 14 06: 17: 02, 856 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-2]: MACD: -0.015545, MACDSignal: -0.017143
22+# 2023 - 02 - 14 06: 17: 02, 858 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-1]: MACD: -0.014928, MACDSignal: -0.016942
23+# 2023 - 02 - 14 06: 18: 02, 545 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-2]: MACD: -0.014794, MACDSignal: -0.01693
24+# 2023 - 02 - 14 06: 18: 02, 546 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-1]: MACD: -0.01408, MACDSignal: -0.016671
25+# 2023 - 02 - 14 06: 19: 02, 168 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-2]: MACD: -0.013811, MACDSignal: -0.016646
26+# 2023 - 02 - 14 06: 19: 02, 169 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-1]: MACD: -0.012886, MACDSignal: -0.016304
27+# 2023 - 02 - 14 06: 20: 02, 712 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-2]: MACD: -0.013065, MACDSignal: -0.016321
28+# 2023 - 02 - 14 06: 20: 02, 713 13268 MainThread exchange_rate_info.py: 197 set_technical_indicators[DEBUG]: num[-1]: MACD: -0.012373, MACDSignal: -0.015962
29+import MetaTrader5 as mt5
30+import talib as ta
31+import datetime as dt
32+import pytz
33+import pandas as pd
34+
35+
36+# 短期EMAの期間
37+n1 = 39
38+# 長期EMAの期間
39+n2 = 56
40+# シグナル(MACDのSMA)の期間
41+ns = 21
42+
43+# 日本のtimezone
44+tz_local = pytz.timezone('Etc/GMT-9')
45+# OANDAサーバのtimezone
46+tz_oanda = pytz.timezone('Etc/GMT-2')
47+
48+cp = 'USDJPY'
49+mt5.initialize()
50+
51+# 終値履歴を取得
52+rates = mt5.copy_rates_from_pos(
53+ cp,
54+ mt5.TIMEFRAME_M1,
55+ 0,
56+ 100000
57+)
58+
59+df = pd.DataFrame(rates)
60+
61+# timeカラムをdatetime型に変換
62+df.time = pd.to_datetime(df['time'], unit='s')
63+# timeカラムをindexに時系列インデックスとして割り当て
64+df.index = pd.DatetimeIndex(df.time, name='Date')
65+# インデックスのTimeZoneをUTCに設定
66+df.index = df.index.tz_localize(dt.timezone.utc)
67+# インデックスのTimeZoneをLovalに変換
68+df.index = df.index.tz_convert(tz_local)
69+
70+# >>> df[-2:]
71+# time open high low close tick_volume spread real_volume
72+# Date
73+# 2023-02-15 00:41:00+09:00 2023-02-14 15:41:00 132.383 132.404 132.242 132.249 709 3 0
74+# 2023-02-15 00:42:00+09:00 2023-02-14 15:42:00 132.253 132.344 132.215 132.296 672 3 0
75+#
76+# mt5のmacd表示
77+# 15:41:00 15:42:00
78+# macd : -0.0049 -0.0019
79+# signal : -0.0107 -0.0102
80+#
81+# この値に近似するデータ数を探索する
82+
83+closes = df['close']
84+
85+# MACDを算出
86+macd, macdsignal, _ = ta.MACD(
87+ closes,
88+ fastperiod=n1,
89+ slowperiod=n2,
90+ signalperiod=ns
91+)
92+print(macd[-2:])
93+print(macdsignal[-2:])
94+
95+# 100 macd:0.012177 signal:-0.011877
96+# 150 macd:0.012937 signal:-0.010785
97+# 200 macd:0.013341 signal:-0.010236
\ No newline at end of file
--- a/src/config/logging.conf
+++ b/src/config/logging.conf
@@ -18,7 +18,7 @@ args=(sys.stdout,)
1818 class=logging.handlers.TimedRotatingFileHandler
1919 level=DEBUG
2020 formatter=simple
21-args=('./mt5-operator.log', 'D', 10, 10, 'utf-8')
21+args=('./mt5-operator.log', 'MIDNIGHT', 10, 10, 'utf-8')
2222
2323 [formatters]
2424 keys=simple
--- a/src/config/setting.ini
+++ b/src/config/setting.ini
@@ -11,7 +11,7 @@ TradeContractSize = 100000.0
1111 # 約定の最小ボリューム
1212 VolumeMin = 0.1
1313 # 約定の最大ボリューム
14-VolumeMax = 10.0
14+VolumeMax = 0.1
1515 # 約定実行のための最小限のボリューム変化のステップ
1616 VolumeStep = 0.01
1717
@@ -38,15 +38,15 @@ OpenMergin = 0.007
3838 # 利益確定(円)
3939 ProfitTaking = 1.5
4040 # 損切(円)
41-LossCut = 0.2
41+LossCut = 0.25
4242
4343 # テクニカル分析
4444 [Technical]
4545 # 短期EMAの期間
46-FastEMAperiod = 39
46+FastEMAperiod = 35
4747 # 長期EMAの期間
48-SlowEMAperiod = 56
48+SlowEMAperiod = 53
4949 # シグナルの期間
50-Signalperiod = 21
50+Signalperiod = 18
5151 # 交差角度閾値
52-CrossingAngleThreshold = 0.684
52+CrossingAngleThreshold = 1.54
--- a/src/configuration.py
+++ b/src/configuration.py
@@ -46,6 +46,8 @@ class Setting(object):
4646 self.__orderable_lot: float = 0.0
4747 # テクニカル指標
4848 self.__technical_indicator: int = 0
49+ # テクニカル転換点
50+ self.__turning_point: bool | None = None
4951
5052 @property
5153 def get_instance(self):
@@ -136,3 +138,16 @@ class Setting(object):
136138 @technical_indicator.setter
137139 def technical_indicator(self, value: int):
138140 self.__technical_indicator = value
141+
142+ @property
143+ def turning_point(self) -> bool | None:
144+ """テクニカル転換点
145+ True: GoldenCross
146+ False: DeadCross
147+ None: Unset
148+ """
149+ return self.__turning_point
150+
151+ @turning_point.setter
152+ def turning_point(self, value: bool):
153+ self.__turning_point = value
--- a/src/exchange_rate_info.py
+++ b/src/exchange_rate_info.py
@@ -41,6 +41,8 @@ class ExchangeRateInfo():
4141 except Exception as e:
4242 logger.error(e)
4343 raise
44+ self.__previous_macd: float | None = None
45+ self.__previous_signal: float | None = None
4446
4547 def __get_latest_rate(self) -> tuple:
4648 """最新レート取得
@@ -79,7 +81,10 @@ class ExchangeRateInfo():
7981 return series1[-2] < series2[-2] and series1[-1] > series2[-1]
8082
8183 def __vector_angle(self, u: np.ndarray, v: np.ndarray):
82- if np.isnan(u) or np.isnan(v):
84+ if np.isnan(u[-1]) or \
85+ np.isnan(u[-2]) or \
86+ np.isnan(v[-1]) or \
87+ np.isnan(v[-2]):
8388 raise ValueError('Nan is included in the value.')
8489 i = np.inner(u, v)
8590 n = LA.norm(u) * LA.norm(v)
@@ -167,7 +172,8 @@ class ExchangeRateInfo():
167172
168173 # MACDテクニカル分析に必要なデータ件数
169174 # mt5アプリの表示と数値の乖離があるので件数を増やしてみる
170- count = (self.__n2 + self.__ns) * 20
175+ # count = (self.__n2 + self.__n1) * 20
176+ count = self.__ns * 10
171177
172178 # 終値履歴を取得
173179 closes = self.__get_history_closes(
@@ -186,6 +192,18 @@ class ExchangeRateInfo():
186192 macd = np.around(macd, 6)
187193 macdsignal = np.around(macdsignal, 6)
188194
195+ # 前回結果が未設定なら判定しない
196+ if self.__previous_macd is None:
197+ self.__previous_macd = macd[-1]
198+ self.__previous_signal = macdsignal[-1]
199+ s.technical_indicator = DEF.TECHNICAL_UNCHANGED
200+ msg = 'Previous MACD result not set.'
201+ logger.info(msg)
202+ return
203+ else:
204+ macd[-2] = self.__previous_macd
205+ macdsignal[-2] = self.__previous_signal
206+
189207 # for debug
190208 for i in range(-2, 0, 1):
191209 msg = (
@@ -195,24 +213,50 @@ class ExchangeRateInfo():
195213
196214 # 指標判定
197215 v_angle = self.__vector_angle(macd[-2:], macdsignal[-2:])
216+ msg = f'vector angle:{v_angle}'
217+ logger.debug(msg)
198218 msg = f'macd vector angle:{v_angle}'
219+
199220 if self.__crossover(macd, macdsignal) and \
200- v_angle > self.__angle:
201- # GoldenCross 上昇転換サイン
202- s.technical_indicator = DEF.TECHNICAL_GOLDEN_CROSS
203- msg = 'Technical Indicator: GoldenCross.'
221+ v_angle > self.__angle and \
222+ macd[-1] < 0.0:
223+ logger.debug('Cross up.')
224+ if s.turning_point is not True:
225+ # GoldenCross 上昇転換サイン
226+ s.technical_indicator = DEF.TECHNICAL_GOLDEN_CROSS
227+ s.turning_point = True
228+ msg = 'Technical Indicator: GoldenCross.'
229+ else:
230+ logger.debug('Already judged goldencross.')
204231 elif self.__crossover(macdsignal, macd) and \
205- self.__vector_angle(macd[-2:], macdsignal[-2:]) > \
206- self.__angle:
207- # DeadCross 降下転換サイン
208- s.technical_indicator = DEF.TECHNICAL_DEAD_CROSS
209- msg = 'Technical Indicator: DeadCross.'
232+ v_angle > self.__angle and \
233+ macd[-1] > 0.0:
234+ logger.debug('Cross down.')
235+ if s.turning_point is not False:
236+ # DeadCross 降下転換サイン
237+ s.technical_indicator = DEF.TECHNICAL_DEAD_CROSS
238+ s.turning_point = False
239+ msg = 'Technical Indicator: DeadCross.'
240+ else:
241+ logger.debug('Already judged deadcross.')
242+ elif macd[-1] > 0.0:
243+ # 上昇トレンド
244+ s.technical_indicator = DEF.TECHNICAL_UPTREND
245+ msg = 'Technical Indicator: Uptrend.'
246+ elif macd[-1] < 0.0:
247+ # 降下トレンド
248+ s.technical_indicator = DEF.TECHNICAL_DOWNTREND
249+ msg = 'Technical Indicator: Downtrand.'
210250 else:
211251 # いずれにも該当しない
212252 s.technical_indicator = DEF.TECHNICAL_UNCHANGED
213253 msg = 'Technical Indicator: Unchanged.'
214254 logger.info(msg)
215255
256+ # 今回MACD結果を退避
257+ self.__previous_macd = macd[-1]
258+ self.__previous_signal = macdsignal[-1]
259+
216260 except Exception as e:
217261 logger.error(e)
218262 raise