Spaces:
Sleeping
Sleeping
rwirangira
commited on
Commit
•
be47ded
1
Parent(s):
e776ea5
Create ai_mode.py
Browse files- ai_mode.py +284 -0
ai_mode.py
ADDED
@@ -0,0 +1,284 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import random
|
2 |
+
import time
|
3 |
+
from pocketoptionapi.stable_api import PocketOption
|
4 |
+
import logging
|
5 |
+
import pandas as pd
|
6 |
+
import os
|
7 |
+
from dotenv import load_dotenv,dotenv_values
|
8 |
+
from stock_indicators import indicators
|
9 |
+
from stock_indicators.indicators.common.quote import Quote
|
10 |
+
import numpy as np
|
11 |
+
from huggingface_hub import InferenceClient
|
12 |
+
|
13 |
+
load_dotenv()
|
14 |
+
|
15 |
+
# logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(message)s')
|
16 |
+
ssid=os.getenv('ssid')
|
17 |
+
api = PocketOption(ssid, True) # DEMO=True, ELSE=False
|
18 |
+
Token=os.getenv('token')
|
19 |
+
client = InferenceClient(
|
20 |
+
"meta-llama/Meta-Llama-3-8B-Instruct",
|
21 |
+
token=Token,
|
22 |
+
)
|
23 |
+
|
24 |
+
def fetch_candles(api, active, period, num_candles):
|
25 |
+
try:
|
26 |
+
synced_time = api.sync_datetime()
|
27 |
+
logging.info(f"Time synchronized before fetching data: {synced_time}")
|
28 |
+
|
29 |
+
retries = 22
|
30 |
+
while retries > 0:
|
31 |
+
try:
|
32 |
+
candles = api.get_candles(active, period)
|
33 |
+
candles_df = pd.DataFrame(candles)
|
34 |
+
|
35 |
+
if len(candles_df) > num_candles:
|
36 |
+
candles_df = candles_df.iloc[-num_candles:]
|
37 |
+
|
38 |
+
logging.info(f"Fetched {len(candles_df)} candles for {active}")
|
39 |
+
|
40 |
+
if candles_df.isnull().values.any():
|
41 |
+
logging.warning("Data contains NaN values. Replacing with zeros.")
|
42 |
+
candles_df.fillna(0, inplace=True)
|
43 |
+
|
44 |
+
required_columns = ['time', 'open', 'high', 'low', 'close']
|
45 |
+
if 'volume' in candles_df.columns:
|
46 |
+
required_columns.append('volume')
|
47 |
+
|
48 |
+
for col in required_columns:
|
49 |
+
if col not in candles_df.columns:
|
50 |
+
logging.error(f"Data for {active} is missing '{col}' column")
|
51 |
+
logging.error(f"Available columns: {candles_df.columns.tolist()}")
|
52 |
+
return pd.DataFrame()
|
53 |
+
|
54 |
+
candles_df['time'] = pd.to_datetime(candles_df['time'], unit='s')
|
55 |
+
logging.info(f"Candles data for {active}: \n{candles_df.head()}")
|
56 |
+
return candles_df
|
57 |
+
except Exception as e:
|
58 |
+
logging.error(f"Error fetching candles: {e}")
|
59 |
+
retries -= 1
|
60 |
+
if retries == 0:
|
61 |
+
logging.error(f"Failed to fetch candles for {active} after multiple retries.")
|
62 |
+
return pd.DataFrame()
|
63 |
+
time.sleep(1)
|
64 |
+
except Exception as e:
|
65 |
+
logging.error(f"Error fetching candles: {e}")
|
66 |
+
return pd.DataFrame()
|
67 |
+
|
68 |
+
def calculate_indicators(candles_df):
|
69 |
+
# Convert candles to a format suitable for the indicators library
|
70 |
+
quotes = [
|
71 |
+
Quote(
|
72 |
+
date=row['time'],
|
73 |
+
open=row['open'],
|
74 |
+
high=row['high'],
|
75 |
+
low=row['low'],
|
76 |
+
close=row['close'],
|
77 |
+
volume=row['volume'] if 'volume' in row else 0
|
78 |
+
)
|
79 |
+
for _, row in candles_df.iterrows()
|
80 |
+
]
|
81 |
+
|
82 |
+
# Calculate various indicators
|
83 |
+
keltner_results = indicators.get_keltner(quotes, 7, 2.0, 7)
|
84 |
+
macd_results = indicators.get_macd(quotes, 5, 15, 5)
|
85 |
+
rsi_results = indicators.get_rsi(quotes, 7)
|
86 |
+
supertrend_results = indicators.get_super_trend(quotes, 3, 2)
|
87 |
+
bollinger_results = indicators.get_bollinger_bands(quotes, 10, 2)
|
88 |
+
sma_results = indicators.get_sma(quotes, 20)
|
89 |
+
ema_results = indicators.get_ema(quotes, 20)
|
90 |
+
stoch_results = indicators.get_stoch(quotes, 14, 3, 3)
|
91 |
+
atr_results = indicators.get_atr(quotes, 14)
|
92 |
+
adx_results = indicators.get_adx(quotes, 14)
|
93 |
+
|
94 |
+
return {
|
95 |
+
"keltner": keltner_results,
|
96 |
+
"macd": macd_results,
|
97 |
+
"rsi": rsi_results,
|
98 |
+
"supertrend": supertrend_results,
|
99 |
+
"bollinger": bollinger_results,
|
100 |
+
"sma": sma_results,
|
101 |
+
"ema": ema_results,
|
102 |
+
"stochastic": stoch_results,
|
103 |
+
"atr": atr_results,
|
104 |
+
"adx": adx_results,
|
105 |
+
"quotes": quotes
|
106 |
+
}
|
107 |
+
|
108 |
+
def calculate_smc(candles_df):
|
109 |
+
# Simple implementation of SMC concept (e.g., detecting break of structure)
|
110 |
+
high = candles_df['high']
|
111 |
+
low = candles_df['low']
|
112 |
+
close = candles_df['close']
|
113 |
+
|
114 |
+
swing_highs = (high.shift(1) < high) & (high.shift(-1) < high)
|
115 |
+
swing_lows = (low.shift(1) > low) & (low.shift(-1) > low)
|
116 |
+
|
117 |
+
last_swing_high = high[swing_highs].max()
|
118 |
+
last_swing_low = low[swing_lows].min()
|
119 |
+
|
120 |
+
return last_swing_high, last_swing_low
|
121 |
+
|
122 |
+
def calculate_fibonacci(candles_df):
|
123 |
+
high = candles_df['high'].max()
|
124 |
+
low = candles_df['low'].min()
|
125 |
+
diff = high - low
|
126 |
+
|
127 |
+
levels = {
|
128 |
+
"0.0%": high,
|
129 |
+
"23.6%": high - 0.236 * diff,
|
130 |
+
"38.2%": high - 0.382 * diff,
|
131 |
+
"50.0%": high - 0.5 * diff,
|
132 |
+
"61.8%": high - 0.618 * diff,
|
133 |
+
"100.0%": low
|
134 |
+
}
|
135 |
+
|
136 |
+
return levels
|
137 |
+
|
138 |
+
def calculate_price_action(candles_df):
|
139 |
+
# Simple implementation of price action concept (e.g., detecting engulfing patterns)
|
140 |
+
candles_df['previous_close'] = candles_df['close'].shift(1)
|
141 |
+
candles_df['engulfing_bullish'] = (candles_df['close'] > candles_df['open']) & (candles_df['previous_close'] < candles_df['open'])
|
142 |
+
candles_df['engulfing_bearish'] = (candles_df['close'] < candles_df['open']) & (candles_df['previous_close'] > candles_df['open'])
|
143 |
+
|
144 |
+
return candles_df['engulfing_bullish'].any(), candles_df['engulfing_bearish'].any()
|
145 |
+
|
146 |
+
def generate_trade_insight(asset, indicator_results, smc_levels, fib_levels, price_action_signals):
|
147 |
+
print("Hello there")
|
148 |
+
messages = [
|
149 |
+
{"role": "user",
|
150 |
+
"content": f"Provide a trade insight for {asset} based on the following indicators and levels: {indicator_results}, SMC Levels: {smc_levels}, Fibonacci Levels: {fib_levels}, Price Action Signals: {price_action_signals}"}
|
151 |
+
]
|
152 |
+
print(f"asset: {asset} ,indicator_results: {indicator_results}, SMC Levels: {smc_levels}, Fibonacci Levels:{fib_levels}, Price Action Signals: {price_action_signals}")
|
153 |
+
|
154 |
+
response = ""
|
155 |
+
for message in client.chat_completion(
|
156 |
+
messages=messages,
|
157 |
+
max_tokens=500,
|
158 |
+
stream=True,
|
159 |
+
):
|
160 |
+
print(message.choices[0].delta.content, end="")
|
161 |
+
response += message.choices[0].delta.content.strip()
|
162 |
+
|
163 |
+
print()
|
164 |
+
|
165 |
+
print(f"AI Trade Insight for {asset}: {response}")
|
166 |
+
return response
|
167 |
+
|
168 |
+
def make_trade_decision(indicator_results, smc_levels, fib_levels, price_action_signals, ai_insight):
|
169 |
+
try:
|
170 |
+
# Ensure that there are results to process
|
171 |
+
for key in indicator_results:
|
172 |
+
if not indicator_results[key]:
|
173 |
+
logging.error(f"Indicator results for {key} are empty.")
|
174 |
+
return None
|
175 |
+
|
176 |
+
last_keltner = indicator_results["keltner"][-1]
|
177 |
+
last_macd = indicator_results["macd"][-1]
|
178 |
+
last_rsi = indicator_results["rsi"][-1]
|
179 |
+
last_supertrend = indicator_results["supertrend"][-1]
|
180 |
+
last_bollinger = indicator_results["bollinger"][-1]
|
181 |
+
last_stoch = indicator_results["stochastic"][-1]
|
182 |
+
last_atr = indicator_results["atr"][-1]
|
183 |
+
last_adx = indicator_results["adx"][-1]
|
184 |
+
|
185 |
+
upper_band = float(last_keltner.upper_band)
|
186 |
+
center_line = float(last_keltner.center_line)
|
187 |
+
lower_band = float(last_keltner.lower_band)
|
188 |
+
close_price = float(indicator_results["quotes"][-1].close)
|
189 |
+
macd_line = float(last_macd.macd)
|
190 |
+
signal_line = float(last_macd.signal)
|
191 |
+
rsi_value = float(last_rsi.rsi)
|
192 |
+
super_trend = float(last_supertrend.super_trend)
|
193 |
+
bollinger_upper = float(last_bollinger.upper_band)
|
194 |
+
bollinger_lower = float(last_bollinger.lower_band)
|
195 |
+
stoch_k = float(last_stoch.k)
|
196 |
+
stoch_d = float(last_stoch.d)
|
197 |
+
atr_value = float(last_atr.atr)
|
198 |
+
adx_value = float(last_adx.adx)
|
199 |
+
|
200 |
+
# Ensure that none of the required values are None
|
201 |
+
if any(value is None for value in
|
202 |
+
[macd_line, signal_line, rsi_value, upper_band, center_line, lower_band, close_price, super_trend,
|
203 |
+
bollinger_upper, bollinger_lower, stoch_k, stoch_d, atr_value, adx_value]):
|
204 |
+
logging.error(
|
205 |
+
f"One of the required values for decision making is None. Check the values.")
|
206 |
+
return None
|
207 |
+
|
208 |
+
last_swing_high, last_swing_low = smc_levels
|
209 |
+
fib_levels_values = fib_levels.values()
|
210 |
+
engulfing_bullish, engulfing_bearish = price_action_signals
|
211 |
+
|
212 |
+
# Uptrend
|
213 |
+
if macd_line > signal_line and rsi_value > 70 and close_price > super_trend and close_price > bollinger_upper:
|
214 |
+
if close_price > last_swing_high or engulfing_bullish:
|
215 |
+
return 'call'
|
216 |
+
|
217 |
+
# Downtrend
|
218 |
+
elif macd_line < signal_line and rsi_value < 30 and close_price < super_trend and close_price < bollinger_lower:
|
219 |
+
if close_price < last_swing_low or engulfing_bearish:
|
220 |
+
return 'put'
|
221 |
+
|
222 |
+
# Fibonacci retracement levels (optional logic)
|
223 |
+
if close_price in fib_levels_values:
|
224 |
+
if close_price == fib_levels["23.6%"] or close_price == fib_levels["38.2%"]:
|
225 |
+
return 'call'
|
226 |
+
elif close_price == fib_levels["61.8%"] or close_price == fib_levels["50.0%"]:
|
227 |
+
return 'put'
|
228 |
+
|
229 |
+
# AI Insight
|
230 |
+
if "call" in ai_insight.lower():
|
231 |
+
return 'call'
|
232 |
+
elif "put" in ai_insight.lower():
|
233 |
+
return 'put'
|
234 |
+
|
235 |
+
return None
|
236 |
+
except Exception as e:
|
237 |
+
logging.error(f"Error making trade decision: {e}")
|
238 |
+
return None
|
239 |
+
|
240 |
+
if __name__ == "__main__":
|
241 |
+
api.connect()
|
242 |
+
time.sleep(2)
|
243 |
+
|
244 |
+
# List of currency pairs to analyze
|
245 |
+
currency_pairs = [
|
246 |
+
"AEDCNY_otc", "AUDCAD_otc", "AUDCHF_otc", "AUDUSD_otc", "CADCHF_otc", "AUDNZD_otc", "CADJPY_otc","BHDCNY_otc",
|
247 |
+
"CHFJPY_otc", "CHFNOK_otc","EURNZD_otc","EURTRY_otc","GBPJPY_otc","JODCNY_otc"
|
248 |
+
]
|
249 |
+
|
250 |
+
while True:
|
251 |
+
try:
|
252 |
+
if api.check_connect():
|
253 |
+
print("Connected to the server")
|
254 |
+
|
255 |
+
for asset in currency_pairs:
|
256 |
+
period = 60 # Set the period to 1 minute
|
257 |
+
num_candles = 60 # Fetch enough candles for short period analysis
|
258 |
+
|
259 |
+
candles_df = fetch_candles(api, asset, period, num_candles)
|
260 |
+
if not candles_df.empty:
|
261 |
+
indicator_results = calculate_indicators(candles_df)
|
262 |
+
smc_levels = calculate_smc(candles_df)
|
263 |
+
fib_levels = calculate_fibonacci(candles_df)
|
264 |
+
price_action_signals = calculate_price_action(candles_df)
|
265 |
+
ai_insight = generate_trade_insight(asset, indicator_results, smc_levels, fib_levels, price_action_signals)
|
266 |
+
trade_direction = make_trade_decision(indicator_results, smc_levels, fib_levels, price_action_signals, ai_insight)
|
267 |
+
if trade_direction:
|
268 |
+
ido = api.buy(5, asset, trade_direction, 120)[1] # Trade duration set to 120 seconds (2 minutes)
|
269 |
+
print(f"Placed a {trade_direction} trade with ID: {ido} for {asset}")
|
270 |
+
api.check_order_closed(ido)
|
271 |
+
else:
|
272 |
+
print(f"No trade decision yet for {asset}")
|
273 |
+
|
274 |
+
else:
|
275 |
+
print(f"Failed to fetch candle data for {asset}")
|
276 |
+
|
277 |
+
# Add delay between checking each asset
|
278 |
+
time.sleep(4)
|
279 |
+
except KeyboardInterrupt:
|
280 |
+
print("Terminating script")
|
281 |
+
break
|
282 |
+
except Exception as e:
|
283 |
+
logging.error(f"Error in main loop: {e}")
|
284 |
+
time.sleep(5)
|