-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbacktesting.py
78 lines (63 loc) · 3.17 KB
/
backtesting.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
# Importing the yfinance library for historical stock data
import yfinance as yf
# Class Backtester will be used for backtesting
class Backtester:
def __init__(self, start_date, end_date, initial_capital, frequency_of_trades, symbol_list):
# Initializing the Backtester class with the specified parameters
self.start_date = start_date
self.end_date = end_date
self.initial_capital = initial_capital
self.frequency_of_trades = frequency_of_trades
self.symbol_list = symbol_list
self.data = {}
self.trades = []
def import_stock_data(self):
# A dictionary to store the historical stock data
# Method to import historical stock data for each symbol in symbol_list
for symbol in self.symbol_list:
# Downloading historical stock data using yfinance and storing it in the data dictionary based on symbol as key
self.data[symbol] = yf.download(symbol, start=self.start_date, end=self.end_date)
# Checks if any specific value is missing for the symbol
if self.data[symbol].isna().any().any():
# Outputs Warning Message based on missing data for symbol
print(f"Warning: Missing data found for symbol {symbol}")
# Removing rows with missing values. Plan to remove specific values later
self.data[symbol] = self.data[symbol].dropna()
return self.data
def strategy(self):
# Implementing a basic pair trading strategy under the assumption of 2 symbols in symbol list
close_prices_1 = self.data[self.symbol_list[0]]['Close']
close_prices_2 = self.data[self.symbol_list[1]]['Close']
# Calculating the standard deviation of the 'Close' prices
std1 = close_prices_1.std(ddof=0)
std2 = close_prices_2.std(ddof=0)
z_score = (close_prices_1 - close_prices_2) / (std1 + std2)
if z_score > 1.0:
return 'SELL'
elif z_score < -1.0:
return 'BUY'
elif abs(z_score) < 0.5:
return 'CLOSE'
return 'HOLD'
def execute_trade(self, symbol, action, price, quantity):
trade = {'Symbol': symbol, 'Action': action, 'Price': price, 'Quantity': quantity}
self.trades.append(trade)
def trades(self):
# Placeholder method for executing trades based on the strategy
for symbol in self.symbol_list:
current_price = self.data[symbol].iloc[-1]['Close']
action = self.strategy()
if action == 'BUY':
quantity = int(self.initial_capital / (2 * current_price))
self.execute_trade(symbol, 'BUY', current_price, quantity)
elif action == 'SELL':
quantity = int(self.initial_capital / (2 * current_price))
self.execute_trade(symbol, 'SELL', current_price, quantity)
def run(self):
self.import_stock_data()
self.trades()
return self.trades
fun = Backtester(start_date='2022-01-01', end_date='2022-12-31', initial_capital=100000, frequency_of_trades=10, symbol_list=['AAPL', 'MSFT'])
trades = fun.run()
for trade in trades:
print(trade)