-
Notifications
You must be signed in to change notification settings - Fork 0
/
watchlist.py
150 lines (131 loc) · 6.79 KB
/
watchlist.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import requests
import vectorbt as bt
class WatchlistItem:
"""
Represents an item in the watchlist, holding details about the asset, its current price,
associated trading framework, and the results of evaluations and backtests.
Attributes:
name (str): Human-readable name of the asset.
ticker (str): Ticker symbol of the asset.
asset_type (str): Type of the asset (e.g., 'Stock', 'Crypto').
api_key (str): API key used for fetching data.
current_price (float): Current price of the asset. Default is None.
framework (TradingFramework): Trading framework associated with this asset. Default is None.
framework_results (dict): Results from the latest framework evaluation. Default is None.
backtest_results (object): Results object from the last backtest. Default is None.
backtest_pnl_percent (float): Percentage P&L from the last backtest. Default is None.
"""
def __init__(self, name, ticker, asset_type, api_key, current_price=None, framework=None):
"""Initializes a new Watchlist instance with the provided API key."""
self.name = name
self.ticker = ticker
self.asset_type = asset_type
self.api_key = api_key
self.current_price = current_price
self.framework = framework
self.framework_results = {"timeframe_statuses": None, "overall_status": None}
self.backtest_results = None
self.backtest_pnl_percent = None
def fetch_current_price(self):
"""
Fetches and updates the current price of the asset using the API.
Handles both stock and crypto assets based on the asset_type.
"""
url = ''
if self.asset_type == 'Stock':
url = f"https://api.polygon.io/v2/snapshot/locale/us/markets/stocks/tickers/{self.ticker}?apiKey={self.api_key}"
elif self.asset_type == 'Crypto':
url = f"https://api.polygon.io/v2/snapshot/locale/global/markets/crypto/tickers/{self.ticker}?apiKey={self.api_key}"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
if self.asset_type == 'Stock':
self.current_price = data['ticker']['min']['o']
elif self.asset_type == 'Crypto':
self.current_price = data['ticker']['min']['o']
else:
print(f"Failed to fetch current price for {self.ticker}: {response.text}")
def evaluate_framework(self):
"""
Evaluates the associated trading framework against the asset. Updates
the framework_results with timeframe statuses and overall status.
"""
if self.framework:
print(f"Evaluating framework for {self.ticker}")
timeframe_statuses = self.framework.evaluate_all_timeframes()
overall_status = self.framework.determine_overall_status(self.framework.bias_timeframes, self.framework.confirmation_timeframes)
self.framework_results = {"timeframe_statuses": timeframe_statuses, "overall_status": overall_status}
print("Timeframe Statuses:", timeframe_statuses)
print("Overall Trading Status:", overall_status)
else:
print(f"No framework assigned to {self.ticker}.")
def perform_backtest(self, initial_capital=10000):
"""
Performs backtesting on the asset using the associated framework and historical data.
Stores the backtest results and calculates P&L percentage.
Args:
initial_capital (float): The starting capital for the backtest. Default is 10,000.
"""
if self.framework:
print(f"Performing backtest for {self.ticker}")
self.backtest_results = self.framework.backtest(initial_capital=initial_capital)
self.backtest_pnl_percent = round(self.backtest_results.total_return() * 100, 2)
print(f"Backtest completed for {self.ticker}")
else:
print(f"No framework assigned for backtesting {self.ticker}.")
self.backtest_results = None
def __str__(self):
return f"{self.name} ({self.ticker}) - {self.asset_type}: Current Price: {self.current_price}, Framework Overall Status: {self.framework_results['overall_status']}, Backtest P&L%: {self.backtest_pnl_percent}"
class Watchlist:
"""
Manages a collection of WatchlistItems, allowing for operations like adding and removing items,
updating prices, evaluating trading frameworks, and performing backtests.
Attributes:
api_key (str): API key used for data fetching across all watchlist items.
items (dict): Dictionary holding WatchlistItems, keyed by their ticker symbols.
"""
def __init__(self, api_key):
self.api_key = api_key
self.items = {}
def add_item(self, name, ticker, asset_type, framework=None):
"""
Adds a new item to the watchlist.
Args:
name (str): Name of the asset.
ticker (str): Ticker symbol of the asset.
asset_type (str): Type of the asset (e.g., 'Stock', 'Crypto').
framework (TradingFramework): Optional. Trading framework to associate with this asset.
"""
print(f'Adding {ticker} to watchlist')
self.items[ticker] = WatchlistItem(name, ticker, asset_type, self.api_key, framework=framework)
def remove_item(self, ticker):
"""
Removes an item from the watchlist by its ticker symbol.
Args:
ticker (str): Ticker symbol of the item to remove.
"""
if ticker in self.items:
print(f'Removing {ticker} from watchlist')
del self.items[ticker]
def update_prices(self):
"""Updates the current prices for all items in the watchlist."""
for ticker, item in self.items.items():
print(f'Updating price for {ticker}')
item.fetch_current_price()
def evaluate_frameworks(self):
"""Evaluates the trading frameworks for all items in the watchlist."""
print("Evaluating frameworks for all watchlist items...")
for item in self.items.values():
item.evaluate_framework()
def perform_backtests(self, initial_capital=10000):
"""
Initiates backtesting for all items in the watchlist using their associated frameworks.
Args:
initial_capital (float): The starting capital for the backtests. Default is 10,000.
"""
print("Performing backtests for all watchlist items...")
for item in self.items.values():
item.perform_backtest(initial_capital=initial_capital)
def show(self):
for item in self.items.values():
print(item)