リビジョン | 2ec087034349def7169d4a604073e79e98b86229 (tree) |
---|---|
日時 | 2023-03-19 10:39:33 |
作者 | kazuhiro_kondow <simauma.circus@gmai...> |
コミッター | kazuhiro_kondow |
mt5.TIMEFRAME_M3に変更
indicatorの再評価を追加
@@ -22,6 +22,9 @@ Magic = 1 | ||
22 | 22 | # Tick Volumeを出来高の代用とし売買の活発度の指標とする |
23 | 23 | # 過去6分間の下限を下回ると新規注文を控える |
24 | 24 | TickVolumeLimit = 200 |
25 | +# TimeFrame | |
26 | +# 分単位の時間足設定(1-60) | |
27 | +TimeFrame = 3 | |
25 | 28 | |
26 | 29 | # 口座設定 |
27 | 30 | [Account] |
@@ -34,31 +37,31 @@ LossCut = 1.0 | ||
34 | 37 | [Strategy] |
35 | 38 | # 許容スプリット(円) |
36 | 39 | # 0.3~1.7銭がoandaの配信範囲94% |
37 | -Allowablespread = 0.01 | |
40 | +Allowablespread = 0.05 | |
38 | 41 | # 取得した価格から注文を実行するトリガー値(円) |
39 | 42 | # 1銭は0.01円 |
40 | 43 | OpenMergin = 0.007 |
41 | 44 | # 利益確定(円) |
42 | 45 | ProfitTaking = 0.05 |
43 | 46 | # FXコアタイムの利益確定(円) |
44 | -CoreTimeProfitTaking = 0.275 | |
47 | +CoreTimeProfitTaking = 0.5 | |
45 | 48 | # FXアイドルタイムの利益確定(円) |
46 | -IdleTimeProfitTaking = 0.05 | |
49 | +IdleTimeProfitTaking = 0.1 | |
47 | 50 | # 損切(円) |
48 | -LossCut = 0.5 | |
51 | +LossCut = 1.85 | |
49 | 52 | |
50 | 53 | # テクニカル分析 |
51 | 54 | [Technical] |
52 | 55 | # 短期EMAの期間 |
53 | -FastEMAperiod = 16 | |
56 | +FastEMAperiod = 12 | |
54 | 57 | # 長期EMAの期間 |
55 | -SlowEMAperiod = 66 | |
58 | +SlowEMAperiod = 25 | |
56 | 59 | # シグナルの期間 |
57 | -Signalperiod = 27 | |
60 | +Signalperiod = 16 | |
58 | 61 | # 交差角度閾値 |
59 | -CrossingAngleThreshold = 0.925 | |
62 | +CrossingAngleThreshold = 0.375 | |
60 | 63 | |
61 | -; MACDCross(n1=16,n2=66,ns=27,angle=37,take=2,cut=20) | |
62 | -; crossover_angle = 0.925 | |
63 | -; ProfitTaking = 0.05 | |
64 | -; LossCut = 0.5 | |
\ No newline at end of file | ||
64 | +; MACDCross(n1=12,n2=25,ns=16,angle=15,take=60,cut=74) | |
65 | +; crossover_angle = 0.375 | |
66 | +; ProfitTaking = 1.5 | |
67 | +; LossCut = 1.85 | |
\ No newline at end of file |
@@ -40,6 +40,10 @@ class ExchangeRateInfo(): | ||
40 | 40 | self.__ns = int(s['Technical']['Signalperiod']) |
41 | 41 | # 交差角度閾値 |
42 | 42 | self.__angle = float(s['Technical']['CrossingAngleThreshold']) |
43 | + # 時間足設定値 | |
44 | + self.__time_frame = int( | |
45 | + s['Trade']['TimeFrame'] | |
46 | + ) | |
43 | 47 | except Exception as e: |
44 | 48 | logger.error(e) |
45 | 49 | raise |
@@ -49,6 +53,7 @@ class ExchangeRateInfo(): | ||
49 | 53 | def __get_latest_rate(self) -> tuple: |
50 | 54 | """最新レート取得 |
51 | 55 | """ |
56 | + # mt5.TIMEFRAME_M1は固定 | |
52 | 57 | rate = mt5.copy_rates_from_pos( |
53 | 58 | self.__cp, |
54 | 59 | mt5.TIMEFRAME_M1, |
@@ -66,7 +71,7 @@ class ExchangeRateInfo(): | ||
66 | 71 | """ |
67 | 72 | rates = mt5.copy_rates_from_pos( |
68 | 73 | self.__cp, |
69 | - mt5.TIMEFRAME_M1, | |
74 | + self.__time_frame, | |
70 | 75 | 0, |
71 | 76 | count |
72 | 77 | ) |
@@ -286,7 +291,7 @@ class ExchangeRateInfo(): | ||
286 | 291 | msg = msg + ' Already judged loss cut.' |
287 | 292 | s.technical_indicator = DEF.TECHNICAL_UPTREND |
288 | 293 | s.turning_point = None |
289 | - s.close_position = False | |
294 | + s.close_position = True | |
290 | 295 | |
291 | 296 | elif self.__crossover([0.0, 0.0], macdsignal[-2:]) and \ |
292 | 297 | s.turning_point is True: |
@@ -298,18 +303,70 @@ class ExchangeRateInfo(): | ||
298 | 303 | msg = msg + ' Already judged loss cut.' |
299 | 304 | s.technical_indicator = DEF.TECHNICAL_DOWNTREND |
300 | 305 | s.turning_point = None |
301 | - s.close_position = True | |
306 | + s.close_position = False | |
302 | 307 | |
308 | + # 2023-03-17 05:53:50 num[-3]: MACD: 0.0601, MACDSignal: 0.0504 | |
309 | + # 2023-03-17 05:53:50 num[-2]: MACD: 0.0557, MACDSignal: 0.051 | |
310 | + # 2023-03-17 05:53:50 num[-1]: MACD: 0.0518, MACDSignal: 0.0511 | |
311 | + # 2023-03-17 05:53:50 befor turning point:True | |
312 | + # 2023-03-17 05:53:50 Technical Indicator: Uptrend. | |
313 | + # 2023-03-17 05:59:50 num[-3]: MACD: 0.0525, MACDSignal: 0.0512 | |
314 | + # 2023-03-17 05:59:50 num[-2]: MACD: 0.0494, MACDSignal: 0.051 | |
315 | + # 2023-03-17 05:59:50 num[-1]: MACD: 0.0447, MACDSignal: 0.0501 | |
316 | + # 2023-03-17 05:59:50 befor turning point:True | |
317 | + # 2023-03-17 05:59:50 Technical Indicator: Downtrand. | |
318 | + # turning pointとindicatorの状態が飛ぶ場合があるので対策を講じる | |
319 | + # 状態不一致はひとつ前のmacd再評価を行う | |
303 | 320 | elif macd[-1] > macdsignal[-1]: |
304 | - # 上昇トレンド | |
305 | - msg = 'Technical Indicator: Uptrend.' | |
306 | - s.technical_indicator = DEF.TECHNICAL_UPTREND | |
307 | - | |
321 | + if s.turning_point is False: | |
322 | + # ひとつ前のmacd再評価 | |
323 | + # 交差角度算出 | |
324 | + re_v_angle = self.__vector_angle( | |
325 | + macd[-3:-1], | |
326 | + macdsignal[-3:-1] | |
327 | + ) | |
328 | + if self.__crossover(macd[-3:-1], macdsignal[-3:-1]): | |
329 | + msg = ( | |
330 | + 'Revaluation CrossOver up.' | |
331 | + f' vector angle:{re_v_angle}' | |
332 | + ) | |
333 | + if re_v_angle > self.__angle: | |
334 | + # GoldenCross 上昇転換サイン | |
335 | + s.technical_indicator = DEF.TECHNICAL_GOLDEN_CROSS | |
336 | + s.turning_point = True | |
337 | + msg = msg + ' Technical Indicator: GoldenCross.' | |
338 | + else: | |
339 | + msg = msg + ' Already judged goldencross.' | |
340 | + s.technical_indicator = DEF.TECHNICAL_UPTREND | |
341 | + else: | |
342 | + # 上昇トレンド | |
343 | + msg = 'Technical Indicator: Uptrend.' | |
344 | + s.technical_indicator = DEF.TECHNICAL_UPTREND | |
308 | 345 | elif macd[-1] < macdsignal[-1]: |
309 | - # 降下トレンド | |
310 | - s.technical_indicator = DEF.TECHNICAL_DOWNTREND | |
311 | - msg = 'Technical Indicator: Downtrand.' | |
312 | - | |
346 | + if s.turning_point is True: | |
347 | + # ひとつ前のmacd再評価 | |
348 | + # 交差角度算出 | |
349 | + re_v_angle = self.__vector_angle( | |
350 | + macd[-3:-1], | |
351 | + macdsignal[-3:-1] | |
352 | + ) | |
353 | + if self.__crossover(macdsignal[-3:-1], macd[-3:-1]): | |
354 | + msg = ( | |
355 | + 'Revaluation CrossOver down.' | |
356 | + f' vector angle:{v_angle}' | |
357 | + ) | |
358 | + if re_v_angle > self.__angle: | |
359 | + # DeadCross 降下転換サイン | |
360 | + s.technical_indicator = DEF.TECHNICAL_DEAD_CROSS | |
361 | + s.turning_point = False | |
362 | + msg = msg + ' Technical Indicator: DeadCross.' | |
363 | + else: | |
364 | + msg = msg + ' Already judged deadcross.' | |
365 | + s.technical_indicator = DEF.TECHNICAL_DOWNTREND | |
366 | + else: | |
367 | + # 降下トレンド | |
368 | + s.technical_indicator = DEF.TECHNICAL_DOWNTREND | |
369 | + msg = 'Technical Indicator: Downtrand.' | |
313 | 370 | else: |
314 | 371 | # いずれにも該当しない |
315 | 372 | s.technical_indicator = DEF.TECHNICAL_UNCHANGED |
@@ -335,6 +392,13 @@ class ExchangeRateInfo(): | ||
335 | 392 | def execute(self): |
336 | 393 | """処理実行 |
337 | 394 | """ |
395 | + # 時間足に合わせて動作チェック | |
396 | + # 時間足より1分早く動作 | |
397 | + if self.__time_frame > 1: | |
398 | + if (datetime.now().minute % self.__time_frame) != \ | |
399 | + (self.__time_frame - 1): | |
400 | + return | |
401 | + | |
338 | 402 | s = Setting() |
339 | 403 | |
340 | 404 | # 市場チェック |
@@ -81,12 +81,14 @@ def main(): | ||
81 | 81 | # Trade成績の改善を目指す |
82 | 82 | # EventMngは経済指標の対応を実装する |
83 | 83 | # PositionMngは長期ポジションに対応する |
84 | + # mt5.TIMEFRAME_M3に変更 | |
84 | 85 | logger.debug("set schedule.") |
85 | 86 | schedule.every().minute.at(":00").do(em.execute) |
86 | 87 | schedule.every().minute.at(":02").do(ac.execute) |
87 | - schedule.every().minute.at(":04").do(rt.execute) | |
88 | 88 | schedule.every().minute.at(":06").do(pm.execute) |
89 | - schedule.every().minute.at(":08").do(tm.execute) | |
89 | + # 動作タイミングをmt5.TIMEFRAME_M3に合わせて調整 | |
90 | + schedule.every().minute.at(":10").do(tm.execute) | |
91 | + schedule.every().minute.at(":50").do(rt.execute) | |
90 | 92 | |
91 | 93 | logger.debug("start loop.") |
92 | 94 | while True: |
@@ -56,6 +56,9 @@ class TradeMng: | ||
56 | 56 | self.__tick_limit = int( |
57 | 57 | s['Trade']['TickVolumeLimit'] |
58 | 58 | ) |
59 | + self.__time_frame = int( | |
60 | + s['Trade']['TimeFrame'] | |
61 | + ) | |
59 | 62 | except Exception as e: |
60 | 63 | logger.error(e) |
61 | 64 | raise |
@@ -197,7 +200,7 @@ class TradeMng: | ||
197 | 200 | """ |
198 | 201 | rates = mt5.copy_rates_from_pos( |
199 | 202 | self.__cp, |
200 | - mt5.TIMEFRAME_M1, | |
203 | + self.__time_frame, | |
201 | 204 | 0, |
202 | 205 | count |
203 | 206 | ) |
@@ -323,6 +326,11 @@ class TradeMng: | ||
323 | 326 | """ |
324 | 327 | |
325 | 328 | try: |
329 | + # 時間足に合わせて動作チェック | |
330 | + # 時間足で割って割り切れるなら動作 | |
331 | + if (datetime.now().minute % self.__time_frame) != 0: | |
332 | + return | |
333 | + | |
326 | 334 | s = Setting() |
327 | 335 | |
328 | 336 | # 未決注文の全解除 |
@@ -352,7 +360,7 @@ class TradeMng: | ||
352 | 360 | return |
353 | 361 | |
354 | 362 | # 直近のTick Volumeが基準以下ならorderしない |
355 | - tick_vol = self.__get_recent_ticks_volume() | |
363 | + tick_vol = self.__get_recent_ticks_volume(2) | |
356 | 364 | if tick_vol < self.__tick_limit: |
357 | 365 | msg = ( |
358 | 366 | "Out of tick volume. " |