Arilnilhaq12

TVM5

Jul 5th, 2025 (edited)
15
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.67 KB | None | 0 0
  1. # File: signal_strategy_tv_mt5.py
  2. import MetaTrader5 as mt5
  3. import pandas as pd
  4. from tradingview_scraper.symbols.technicals import Indicators
  5. import mplfinance as mpf
  6. import matplotlib.pyplot as plt
  7. from matplotlib.patches import Rectangle
  8.  
  9. # === Kelas Deteksi Sinyal ===
  10. class SignalStrategyTvMt5:
  11. def __init__(self, symbol="BTCUSD", timeframe=mt5.TIMEFRAME_D1, bars=100):
  12. self.symbol = symbol
  13. self.timeframe = timeframe
  14. self.bars = bars
  15. self.df = None
  16. self.signal_df = None
  17.  
  18. def connect_mt5(self):
  19. if not mt5.initialize():
  20. raise Exception("MT5 gagal di-inisialisasi")
  21. print("[✓] MT5 connected")
  22.  
  23. def shutdown_mt5(self):
  24. mt5.shutdown()
  25. print("[✓] MT5 shutdown selesai")
  26.  
  27. def deteksi_ob(self, indikator):
  28. rsi = indikator.get("RSI", 0)
  29. stoch_k = indikator.get("Stoch.K", 0)
  30. if rsi > 70:
  31. return "OB - RSI"
  32. elif stoch_k > 80:
  33. return "OB - Stoch"
  34. return "Normal"
  35.  
  36. def deteksi_fvg(self, df):
  37. result = {}
  38. for i in range(2, len(df)):
  39. t = df['time'].iloc[i]
  40. if df['low'].iloc[i] > df['high'].iloc[i - 2]:
  41. result[t] = "Bullish FVG"
  42. elif df['high'].iloc[i] < df['low'].iloc[i - 2]:
  43. result[t] = "Bearish FVG"
  44. else:
  45. result[t] = ""
  46. return result
  47.  
  48. def deteksi_bos(self, df, period=5):
  49. result = {}
  50. for i in range(period, len(df) - period):
  51. t = df['time'].iloc[i]
  52. swing_high = max(df['high'].iloc[i - period:i])
  53. swing_low = min(df['low'].iloc[i - period:i])
  54. if df['close'].iloc[i] > swing_high:
  55. result[t] = "BOS Bullish"
  56. elif df['close'].iloc[i] < swing_low:
  57. result[t] = "BOS Bearish"
  58. else:
  59. result[t] = ""
  60. return result
  61.  
  62. def deteksi_choch(self, df, period=5):
  63. result = {}
  64. for i in range(period + 1, len(df)):
  65. t = df['time'].iloc[i]
  66. prev_high = max(df['high'].iloc[i - period - 1:i - 1])
  67. prev_low = min(df['low'].iloc[i - period - 1:i - 1])
  68. curr = df['close'].iloc[i]
  69. prev = df['close'].iloc[i - 1]
  70. if prev > prev_high and curr < prev_low:
  71. result[t] = "CHoCH Bearish"
  72. elif prev < prev_low and curr > prev_high:
  73. result[t] = "CHoCH Bullish"
  74. else:
  75. result[t] = ""
  76. return result
  77.  
  78. def deteksi_engulfing(self, df):
  79. result = {}
  80. for i in range(1, len(df)):
  81. prev_open = df['open'].iloc[i - 1]
  82. prev_close = df['close'].iloc[i - 1]
  83. curr_open = df['open'].iloc[i]
  84. curr_close = df['close'].iloc[i]
  85.  
  86. if prev_close < prev_open and curr_close > curr_open and curr_close > prev_open and curr_open < prev_close:
  87. result[df['time'].iloc[i]] = "Bullish Engulfing"
  88. elif prev_close > prev_open and curr_close < curr_open and curr_close < prev_open and curr_open > prev_close:
  89. result[df['time'].iloc[i]] = "Bearish Engulfing"
  90. else:
  91. result[df['time'].iloc[i]] = ""
  92. return result
  93.  
  94. def konfirmasi_sinyal_buy_sell(self, df, signal_df):
  95. result = {}
  96. for i in range(2, len(signal_df)):
  97. row = signal_df.iloc[i]
  98. t = row['time']
  99. fvg = row['FVG']
  100. ob = row['OB']
  101. bos = row['BOS']
  102. choch = row['CHoCH']
  103. engulf = row.get('ENGULFING', "")
  104. harga = df['close'].iloc[i]
  105.  
  106. arah = None
  107. if "Bullish" in fvg and "Bullish" in engulf and ("Bullish" in bos or "Bullish" in choch):
  108. arah = "BUY"
  109. elif "Bearish" in fvg and "Bearish" in engulf and ("Bearish" in bos or "Bearish" in choch):
  110. arah = "SELL"
  111.  
  112. if arah == "BUY":
  113. high_fvg = df['high'].iloc[i - 2]
  114. low_fvg = df['low'].iloc[i]
  115. fibo_0618 = low_fvg + (high_fvg - low_fvg) * 0.618
  116. if harga > fibo_0618 and harga < high_fvg:
  117. result[t] = f"Konfirmasi {arah} dengan SL TP 1:2"
  118. else:
  119. result[t] = ""
  120. elif arah == "SELL":
  121. low_fvg = df['low'].iloc[i - 2]
  122. high_fvg = df['high'].iloc[i]
  123. fibo_0618 = low_fvg + (high_fvg - low_fvg) * 0.618
  124. if harga < fibo_0618 and harga > low_fvg:
  125. result[t] = f"Konfirmasi {arah} dengan SL TP 1:2"
  126. else:
  127. result[t] = ""
  128. else:
  129. result[t] = ""
  130. return result
  131.  
  132. def get_data(self):
  133. self.connect_mt5()
  134. data = mt5.copy_rates_from_pos(self.symbol, self.timeframe, 0, self.bars)
  135. if data is None:
  136. raise Exception("Gagal ambil data dari MT5")
  137.  
  138. df = pd.DataFrame(data)
  139. df['time'] = pd.to_datetime(df['time'], unit='s')
  140. self.df = df
  141.  
  142. indikator = Indicators().scrape(
  143. exchange="BINANCE",
  144. symbol=self.symbol,
  145. timeframe="1d",
  146. indicators=["RSI", "Stoch.K"]
  147. )
  148.  
  149. ob_status = self.deteksi_ob(indikator)
  150. fvg = self.deteksi_fvg(df)
  151. bos = self.deteksi_bos(df)
  152. choch = self.deteksi_choch(df)
  153. engulfing = self.deteksi_engulfing(df)
  154.  
  155. signal_df = pd.DataFrame({
  156. 'time': df['time'],
  157. 'OB': [ob_status] * len(df),
  158. 'FVG': df['time'].map(fvg),
  159. 'BOS': df['time'].map(bos),
  160. 'CHoCH': df['time'].map(choch),
  161. 'ENGULFING': df['time'].map(engulfing),
  162. })
  163.  
  164. konfirmasi = self.konfirmasi_sinyal_buy_sell(df, signal_df)
  165. signal_df['KONFIRMASI'] = df['time'].map(konfirmasi)
  166.  
  167. self.shutdown_mt5()
  168. self.signal_df = signal_df
  169. return df, signal_df
  170.  
  171. # === Kelas Console & Visual ===
  172. class ShowConsoleSignal:
  173. def __init__(self):
  174. self.strategy = SignalStrategyTvMt5()
  175. self.df = None
  176. self.sinyal = None
  177.  
  178. def run(self):
  179. print("📊 === ALGO SIGNAL CONSOLE ===")
  180. try:
  181. self.df, self.sinyal = self.strategy.get_data()
  182. except Exception as e:
  183. print(f"[!] ERROR: {e}")
  184. return
  185.  
  186. while True:
  187. print("\nPilih menu:")
  188. print("[1] Lihat OHLC MT5 terakhir")
  189. print("[2] Lihat sinyal terakhir")
  190. print("[3] Tampilkan grafik sinyal (mplfinance)")
  191. print("[4] Keluar")
  192.  
  193. pilihan = input(">> Pilih [1-4]: ").strip()
  194.  
  195. if pilihan == "1":
  196. print(self.df.tail())
  197. elif pilihan == "2":
  198. print(self.sinyal.tail())
  199. elif pilihan == "3":
  200. self.mplft()
  201. elif pilihan == "4":
  202. break
  203. else:
  204. print("Pilihan tidak valid.")
  205.  
  206. def mplft(self):
  207. if self.df is None or self.sinyal is None:
  208. print("[!] Data belum tersedia.")
  209. return
  210.  
  211. df_plot = self.df.copy()
  212. df_plot.set_index('time', inplace=True)
  213. df_plot = df_plot[['open', 'high', 'low', 'close']]
  214.  
  215. fig, axlist = mpf.plot(
  216. df_plot,
  217. type='candle',
  218. style='yahoo',
  219. title='Sinyal Deteksi (OB, FVG, BOS, CHoCH, ENGULFING)',
  220. ylabel='Harga',
  221. volume=False,
  222. returnfig=True
  223. )
  224. ax = axlist[0]
  225.  
  226. for i in range(2, len(self.df)):
  227. row = self.sinyal.iloc[i]
  228. time = self.df['time'].iloc[i]
  229. close = self.df['close'].iloc[i]
  230.  
  231. if isinstance(row['KONFIRMASI'], str) and row['KONFIRMASI'] != "":
  232. arah = "BUY" if "BUY" in row['KONFIRMASI'] else "SELL"
  233. if arah == "BUY":
  234. high_fvg = self.df['high'].iloc[i - 2]
  235. low_fvg = self.df['low'].iloc[i]
  236. fibo_0 = high_fvg
  237. fibo_1 = low_fvg
  238. fibo_0618 = fibo_1 + (fibo_0 - fibo_1) * 0.618
  239. sl = fibo_1
  240. tp = fibo_0618 + (fibo_0618 - sl) * 2
  241. ax.text(time, close * 0.99, "BUY", color='green', fontsize=8, ha='center', va='top')
  242. else:
  243. low_fvg = self.df['low'].iloc[i - 2]
  244. high_fvg = self.df['high'].iloc[i]
  245. fibo_0 = low_fvg
  246. fibo_1 = high_fvg
  247. fibo_0618 = fibo_0 + (fibo_1 - fibo_0) * 0.618
  248. sl = fibo_1
  249. tp = fibo_0618 - (sl - fibo_0618) * 2
  250. ax.text(time, close * 1.01, "SELL", color='white', fontsize=8, ha='center', va='bottom')
  251.  
  252. ax.axhline(fibo_0, color='gray', linestyle='--', linewidth=0.8)
  253. ax.axhline(fibo_0618, color='blue', linestyle='--', linewidth=1.2)
  254. ax.axhline(fibo_1, color='gray', linestyle='--', linewidth=0.8)
  255.  
  256. box_color = 'green' if arah == 'BUY' else 'red'
  257. y_bottom = min(sl, tp)
  258. y_top = max(sl, tp)
  259. height = y_top - y_bottom
  260. rect = Rectangle((time, y_bottom), pd.Timedelta(days=0.5), height, color=box_color, alpha=0.2)
  261. ax.add_patch(rect)
  262.  
  263. plt.tight_layout()
  264. plt.show()
  265.  
  266. # === Entry Point ===
  267. if __name__ == "__main__":
  268. ShowConsoleSignal().run()
  269.  
Advertisement
Add Comment
Please, Sign In to add comment