tosin2013 commited on
Commit
1b4fca8
1 Parent(s): d3959d1

working code

Browse files
Files changed (3) hide show
  1. README.md +43 -0
  2. app.py +66 -16
  3. instructions.md +23 -0
README.md CHANGED
@@ -10,3 +10,46 @@ pinned: false
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
13
+ **Overview:**
14
+
15
+ This Python code implements a forex trading tool that combines technical analysis with sentiment analysis to generate trading signals. It leverages the Backtrader library for backtesting, the Alpha Vantage API for fetching forex data and sentiment data, and Gradio for creating a user-friendly interface.
16
+
17
+ **Key Features:**
18
+
19
+ - **Trend-following strategy:** Employs a simple moving average crossover strategy to identify potential buy and sell signals.
20
+ - **Sentiment analysis:** Incorporates sentiment analysis from news data to refine trade decisions.
21
+ - **Backtesting capabilities:** Allows users to test the strategy's performance on historical data.
22
+ - **User-friendly interface:** Provides a Gradio interface for easy interaction and visualization of results.
23
+
24
+ **Code Structure:**
25
+
26
+ 1. **Import Necessary Libraries:**
27
+ - `gradio`, `pandas`, `backtrader`, `requests`
28
+ 2. **Define Instructions:**
29
+ - Reads Markdown-formatted instructions from a file for user guidance.
30
+ 3. **TrendFollowingStrategy Class:**
31
+ - Implements the trend-following strategy logic using a moving average crossover.
32
+ - Tracks trade details (count, wins, losses) and logs trade information.
33
+ 4. **Data Fetching Functions:**
34
+ - `fetch_forex_intraday`: Retrieves forex data from Alpha Vantage.
35
+ - `fetch_sentiment_data`: Fetches sentiment data from Alpha Vantage.
36
+ - `analyze_sentiment`: Analyzes sentiment data for a given ticker.
37
+ - `load_data`: Converts fetched data into a Backtrader data feed.
38
+ 5. **Trade Decision Function:**
39
+ - `should_trade`: Determines whether to make a trade based on technical signals and sentiment analysis.
40
+ 6. **Backtesting Function:**
41
+ - `run_backtest`: Runs a backtest using specified parameters and returns performance statistics and trade decisions.
42
+ 7. **Interface Creation:**
43
+ - Sets up Gradio interface elements for user input and output.
44
+ - Launches the interface, allowing users to interact with the tool.
45
+
46
+ **How to Use:**
47
+
48
+ 1. Obtain an API key from Alpha Vantage.
49
+ 2. Run the Python code.
50
+ 3. Enter your API key in the Gradio interface.
51
+ 4. Select the desired currency pair and time interval.
52
+ 5. Click the "Run" button to initiate the backtest.
53
+ 6. Review the generated backtest results and trade decisions.
54
+
55
+
app.py CHANGED
@@ -3,6 +3,11 @@ import pandas as pd
3
  import backtrader as bt
4
  import requests
5
 
 
 
 
 
 
6
  class TrendFollowingStrategy(bt.Strategy):
7
  params = (('ma_period', 15),)
8
 
@@ -16,6 +21,7 @@ class TrendFollowingStrategy(bt.Strategy):
16
  self.trade_count = 0
17
  self.win_count = 0
18
  self.loss_count = 0
 
19
 
20
  def next(self):
21
  # Check if we are in the market
@@ -36,7 +42,6 @@ class TrendFollowingStrategy(bt.Strategy):
36
  # We are short and get a buy signal
37
  self.close() # Close the short position
38
 
39
-
40
  def notify_trade(self, trade):
41
  if trade.isclosed:
42
  outcome = 'win' if trade.pnl > 0 else 'loss'
@@ -51,8 +56,21 @@ class TrendFollowingStrategy(bt.Strategy):
51
  self.win_count += 1
52
  elif outcome == 'loss':
53
  self.loss_count += 1
 
 
 
 
 
 
54
  print(f"Trade {self.trade_count}: {trade_type} - {outcome}")
55
 
 
 
 
 
 
 
 
56
  def fetch_forex_intraday(api_key, from_symbol, to_symbol, interval, outputsize='compact'):
57
  url = f'https://www.alphavantage.co/query?function=FX_INTRADAY&from_symbol={from_symbol}&to_symbol={to_symbol}&interval={interval}&apikey={api_key}&outputsize={outputsize}'
58
  response = requests.get(url)
@@ -184,8 +202,8 @@ def should_trade(strategy, api_endpoint, api_key, base_currency, quote_currency)
184
 
185
  # Fetch and analyze sentiment data
186
  json_response = fetch_sentiment_data(api_endpoint, f"{base_ticker}", api_key)
187
- print(fetch_sentiment_data(api_endpoint, f"{quote_currency}", api_key))
188
- print(json_response)
189
  base_sentiment = analyze_sentiment(json_response, base_ticker)
190
  quote_sentiment = analyze_sentiment(json_response, quote_currency)
191
 
@@ -198,7 +216,8 @@ def should_trade(strategy, api_endpoint, api_key, base_currency, quote_currency)
198
  return True, trade_decision, timeframe, decision_reason
199
  return False, None, None, "Not enough consistent signals or conflicting sentiment " +decision_reason+"."
200
 
201
- # Define a function to run the backtest and provide trading signals
 
202
  def run_backtest(api_key, from_symbol, to_symbol, interval):
203
  # Set up Cerebro engine
204
  cerebro = bt.Cerebro()
@@ -231,7 +250,39 @@ def run_backtest(api_key, from_symbol, to_symbol, interval):
231
  signal = "Sell"
232
  color = "red"
233
 
234
- return f"Signal: <span style='color: {color}'>{signal}</span>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
 
237
  # Define a list of popular currency pairs for the dropdowns
@@ -241,18 +292,17 @@ to_currency_choices = ['USD', 'JPY', 'GBP', 'AUD', 'CAD']
241
  # Placeholder link for API key
242
  api_key_link = "https://www.alphavantage.co/support/#api-key"
243
 
244
- import gradio as gr
245
- # Create a Gradio interface
 
 
 
246
  gr.Interface(
247
  fn=run_backtest,
248
- inputs=[
249
- gr.inputs.Textbox(label="API Key", placeholder="Enter your API key"),
250
- gr.inputs.Dropdown(label="From Currency", choices=['EUR', 'GBP', 'USD', 'AUD', 'JPY']),
251
- gr.inputs.Dropdown(label="To Currency", choices=['USD', 'JPY', 'GBP', 'AUD', 'CAD']),
252
- gr.inputs.Radio(label="Interval", choices=["1min", "5min", "15min", "30min", "60min"])
253
- ],
254
  outputs="html",
255
  live=True,
256
- title="Trading Signal",
257
- description="Run Backtest and Get Trading Signal"
258
- ).launch()
 
 
3
  import backtrader as bt
4
  import requests
5
 
6
+
7
+ # Define the Markdown-formatted instructions
8
+ with open("instructions.md", "r") as md_file:
9
+ instructions = md_file.read()
10
+
11
  class TrendFollowingStrategy(bt.Strategy):
12
  params = (('ma_period', 15),)
13
 
 
21
  self.trade_count = 0
22
  self.win_count = 0
23
  self.loss_count = 0
24
+ self.trade_log = [] # Store trade details as a list of dictionaries
25
 
26
  def next(self):
27
  # Check if we are in the market
 
42
  # We are short and get a buy signal
43
  self.close() # Close the short position
44
 
 
45
  def notify_trade(self, trade):
46
  if trade.isclosed:
47
  outcome = 'win' if trade.pnl > 0 else 'loss'
 
56
  self.win_count += 1
57
  elif outcome == 'loss':
58
  self.loss_count += 1
59
+ trade_details = {
60
+ 'trade_num': self.trade_count,
61
+ 'trade_type': trade_type,
62
+ 'outcome': outcome
63
+ }
64
+ self.trade_log.append(trade_details)
65
  print(f"Trade {self.trade_count}: {trade_type} - {outcome}")
66
 
67
+ def get_trade_log(self):
68
+ """
69
+ Get the trade log as a list of dictionaries.
70
+ """
71
+ return self.trade_log
72
+
73
+
74
  def fetch_forex_intraday(api_key, from_symbol, to_symbol, interval, outputsize='compact'):
75
  url = f'https://www.alphavantage.co/query?function=FX_INTRADAY&from_symbol={from_symbol}&to_symbol={to_symbol}&interval={interval}&apikey={api_key}&outputsize={outputsize}'
76
  response = requests.get(url)
 
202
 
203
  # Fetch and analyze sentiment data
204
  json_response = fetch_sentiment_data(api_endpoint, f"{base_ticker}", api_key)
205
+ #print(fetch_sentiment_data(api_endpoint, f"{quote_currency}", api_key))
206
+ #print(json_response)
207
  base_sentiment = analyze_sentiment(json_response, base_ticker)
208
  quote_sentiment = analyze_sentiment(json_response, quote_currency)
209
 
 
216
  return True, trade_decision, timeframe, decision_reason
217
  return False, None, None, "Not enough consistent signals or conflicting sentiment " +decision_reason+"."
218
 
219
+ import backtrader as bt
220
+
221
  def run_backtest(api_key, from_symbol, to_symbol, interval):
222
  # Set up Cerebro engine
223
  cerebro = bt.Cerebro()
 
250
  signal = "Sell"
251
  color = "red"
252
 
253
+ # Get trade decision information
254
+ trade_decision, trade_type, trade_timeframe, reason = should_trade(strategy_instance, api_endpoint, api_key, from_symbol, to_symbol)
255
+
256
+
257
+ # Create an HTML message with the calculated statistics, trade log, and trade decision information
258
+ html_message = f"""
259
+ <p><strong>Strategy Performance Summary:</strong></p>
260
+ <p>On the {interval} timeframe</p>
261
+ <p>*****************************</p>
262
+ <p>Total Trades: {total_trades}</p>
263
+ <p>Total Wins: {total_wins} ({win_percentage:.2f}%)</p>
264
+ <p>Total Losses: {total_losses} ({loss_percentage:.2f}%)</p>
265
+ <p>Signal: <span style='color: {color}'>{signal}</span></p>
266
+ <p><strong>Trade Log:</strong></p>
267
+ <ul>
268
+ """
269
+ # Get trade log from the strategy
270
+ trade_log = strategy_instance.get_trade_log()
271
+
272
+ for trade in trade_log:
273
+ html_message += f"<li>Trade {trade['trade_num']}: {trade['trade_type']} - {trade['outcome']}</li>"
274
+
275
+ html_message += "</ul>"
276
+
277
+ # Include trade decision information
278
+ html_message += f"""
279
+ <p><strong>Trade Decision:</strong></p>
280
+ <p>Trade Type: {trade_type}</p>
281
+ <p>Timeframe: {trade_timeframe}</p>
282
+ <p>Reason: {reason}</p>
283
+ """
284
+
285
+ return html_message
286
 
287
 
288
  # Define a list of popular currency pairs for the dropdowns
 
292
  # Placeholder link for API key
293
  api_key_link = "https://www.alphavantage.co/support/#api-key"
294
 
295
+ api_key_input = gr.Textbox(label="API Key", placeholder="Enter your API key")
296
+ from_currency_input = gr.Dropdown(label="From Currency", choices=['EUR', 'GBP', 'USD', 'AUD', 'JPY'])
297
+ to_currency_input = gr.Dropdown(label="To Currency", choices=['USD', 'JPY', 'GBP', 'AUD', 'CAD'])
298
+ interval_input = gr.Radio(label="Interval", choices=["1min", "5min", "15min", "30min", "60min"])
299
+
300
  gr.Interface(
301
  fn=run_backtest,
302
+ inputs=[api_key_input, from_currency_input, to_currency_input, interval_input],
 
 
 
 
 
303
  outputs="html",
304
  live=True,
305
+ title="Forex Trend Trading Signals",
306
+ description=instructions,
307
+ cache_examples=True
308
+ ).launch()
instructions.md ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Purpose:
2
+ This script is for research purposes only and is not intended for actual trading. It demonstrates how to use the AlphaVantage API to perform backtesting and generate trading signals.
3
+
4
+ ### Instructions:
5
+ 1. **Get Your API Key:**
6
+ - Sign up for an API key on the [AlphaVantage website](https://www.alphavantage.co/).
7
+ - Enter your API key in the 'API Key' field.
8
+
9
+ 2. **Select Currency Pairs:**
10
+ - Choose the 'From Currency' and 'To Currency' from the dropdown menus.
11
+
12
+ 3. **Choose Interval:**
13
+ - Select the 'Interval' for your backtest.
14
+
15
+ 4. **Run Backtest:**
16
+ - Click 'Submit' to run the backtest and get trading signals.
17
+
18
+
19
+ Code Documentation
20
+ ------------------
21
+ [README.md](README.md)
22
+ ---
23
+