socialmodel / app.py
developersajidbashir's picture
Update app.py
e296f90 verified
Raw
History Blame Contribute Delete
6.77 kB
import threading
import gym
import numpy as np
import requests
import pandas as pd
from datetime import datetime, timedelta
from stable_baselines3 import PPO
from stable_baselines3.common.vec_env import DummyVecEnv
from gym import spaces
import time
import firebase_admin
from firebase_admin import credentials, db
import os
import gradio as gr
cred = credentials.Certificate("credentials.json")
firebase_admin.initialize_app(cred, {"databaseURL": "https://socail-swap-default-rtdb.asia-southeast1.firebasedatabase.app/"})
ref = db.reference()
buy_signals = []
sell_signals = []
hold_signals = []
class TradingEnv(gym.Env):
def __init__(self, data, window_size=50):
super(TradingEnv, self).__init__()
super(TradingEnv, self).__init__()
self.data = data
self.window_size = window_size
self.current_step = window_size
self.action_space = spaces.Discrete(3)
self.observation_space = spaces.Box(
low=0, high=1, shape=(window_size, 2), dtype=np.float32)
def reset(self):
self.current_step = self.window_size
return self._get_observation()
def _get_observation(self):
window_data = self.data[self.current_step-self.window_size:self.current_step]
obs = window_data[['close', 'EMA']].values
obs = (obs - obs.min()) / (obs.max() - obs.min())
return obs
def step(self, action):
reward = 0
done = False
self.current_step += 1
if self.current_step >= len(self.data):
done = True
else:
if action == 1:
reward = self.data['close'].iloc[self.current_step] - self.data['close'].iloc[self.current_step - 1]
elif action == 2:
reward = self.data['close'].iloc[self.current_step - 1] - self.data['close'].iloc[self.current_step]
return self._get_observation(), reward, done, {}
def fetch_data(symbol='ETH', tsym='USD', start_date='2021-01-01', api_key='66bc686cb714fadda1fad0320704c98869d4b31ce7d9d27560c6c574b4d04c54'):
start_date = datetime.strptime(start_date, '%Y-%m-%d')
end_date = datetime.utcnow()
to_ts = int(end_date.timestamp())
url = f'https://min-api.cryptocompare.com/data/v2/histohour?fsym={symbol}&tsym={tsym}&toTs={to_ts}&api_key={api_key}'
response = requests.get(url)
data = response.json()
if data['Response'] == 'Success':
data_points = data['Data']['Data']
df = pd.DataFrame(data_points)
df['time'] = pd.to_datetime(df['time'], unit='s')
df.set_index('time', inplace=True)
# Filter data based on start_date
df = df[df.index >= start_date]
return df[['close']]
else:
print(f"Error fetching data: {data['Message']}")
return None
def calculate_ema(data, span=20):
data['EMA'] = data['close'].ewm(span=span, adjust=False).mean()
return data
def run_model():
while True:
try:
new_data = fetch_data(start_date=(datetime.utcnow() - timedelta(days=3)).strftime('%Y-%m-%d'))
new_data = calculate_ema(new_data)
if len(new_data) < 50:
print("Not enough data to update the environment.")
time.sleep(3600)
continue
env = DummyVecEnv([lambda: TradingEnv(new_data)])
model.set_env(env)
obs = env.reset()
dates = new_data.index[50:]
prices = new_data['close'][50:]
emas = new_data['EMA'][50:]
actions = []
for date, price, ema in zip(dates, prices, emas):
action, _ = model.predict(obs)
actions.append(action[0])
obs, _, done, _ = env.step(action)
if done:
break
new_buy_signals = [(date, price, ema) for date, price, ema, action in zip(dates, prices, emas, actions) if action == 1 and date not in [signal[0] for signal in buy_signals]]
new_sell_signals = [(date, price, ema) for date, price, ema, action in zip(dates, prices, emas, actions) if action == 2 and date not in [signal[0] for signal in sell_signals]]
new_hold_signals = [(date, price, ema) for date, price, ema, action in zip(dates, prices, emas, actions) if action == 0 and date not in [signal[0] for signal in hold_signals]]
for signal in new_buy_signals:
if signal[0] not in [s[0] for s in buy_signals] and signal[0] not in [s[0] for s in sell_signals] and signal[0] not in [s[0] for s in hold_signals]:
buy_signals.append(signal)
for signal in new_sell_signals:
if signal[0] not in [s[0] for s in sell_signals] and signal[0] not in [s[0] for s in buy_signals] and signal[0] not in [s[0] for s in hold_signals]:
sell_signals.append(signal)
for signal in new_hold_signals:
if signal[0] not in [s[0] for s in hold_signals] and signal[0] not in [s[0] for s in buy_signals] and signal[0] not in [s[0] for s in sell_signals]:
hold_signals.append(signal)
buy_signals_data = [{'timestamp': signal[0].strftime('%Y-%m-%d %H:%M:%S'), 'type': 'b', 'price': round(signal[1], 2), 'ema': round(signal[2], 2)} for signal in buy_signals]
sell_signals_data = [{'timestamp': signal[0].strftime('%Y-%m-%d %H:%M:%S'), 'type': 's', 'price': round(signal[1], 2), 'ema': round(signal[2], 2)} for signal in sell_signals]
hold_signals_data = [{'timestamp': signal[0].strftime('%Y-%m-%d %H:%M:%S'), 'type': 'h', 'price': round(signal[1], 2), 'ema': round(signal[2], 2)} for signal in hold_signals]
all_signals_data = buy_signals_data + sell_signals_data + hold_signals_data
all_signals_data.sort(key=lambda x: x['timestamp'], reverse=True)
ref.child('signals').child('data').set(all_signals_data)
time.sleep(3590)
except Exception as e:
print(f"An error occurred: {e}")
break
def start_model_in_background():
thread = threading.Thread(target=run_model)
thread.daemon = True
thread.start()
def dummy_interface():
return "Model is running in the background."
if __name__ == "__main__":
data = fetch_data()
data = calculate_ema(data)
if len(data) < 50:
raise ValueError("Not enough data to fill the window size.")
env = DummyVecEnv([lambda: TradingEnv(data)])
model = PPO.load("ppo_trading_agent", env=env)
start_model_in_background()
gr.Interface(fn=dummy_interface, inputs=[], outputs="text").launch()