teddykoker / blog Goto Github PK
View Code? Open in Web Editor NEWSource code for my personal blog
Home Page: https://teddykoker.com
License: MIT License
Source code for my personal blog
Home Page: https://teddykoker.com
License: MIT License
Hi Teddy, great post. I'm a bit confused with the following code though:
self.rankings.sort(key=lambda d: self.inds[d]["momentum"][0])
and then
# buy stocks with remaining cash for i, d in enumerate(self.rankings[:int(num_stocks * 0.2)]): cash = self.broker.get_cash() value = self.broker.get_value() if cash <= 0: break if not self.getposition(self.data).size: size = value * 0.001 / self.inds[d]["atr20"] self.buy(d, size=size)
Seems to be picking stocks with the lowest momentum? And It's supposed to be picking stocks with the highest momentum in Andreas F. Clenow's book?
Thanks!
I can't seem to be able to reproduce your results with my own back-testing program.
hence I installed the backtester yesterday, trying to run your program, and found some problems,
in below code, rebalance portfolio never executed correctly.
if self.getposition(self.data).size: ==> should be ==> if self.getposition(d).size: huge bug...
after fixing this bug, I still have some problems... hence I'm contacting you to see if you have fixed any other bugs on this program. or there are some issues in Backtester itself. I am not an expert on Backtester. just started to use it.
my own testers seem to be working correctly.
thanks in advance.
def rebalance_portfolio(self):
# only look at data that we can have indicators for
self.rankings = list(filter(lambda d: len(d) > 100, self.stocks))
self.rankings.sort(key=lambda d: self.inds[d]["momentum"][0])
num_stocks = len(self.rankings)
# sell stocks based on criteria
for i, d in enumerate(self.rankings):
if self.getposition(self.data).size:
if i > num_stocks * 0.2 or d < self.inds[d]["sma100"]:
self.close(d)
if self.spy < self.spy_sma200:
return
# buy stocks with remaining cash
for i, d in enumerate(self.rankings[:int(num_stocks * 0.2)]):
cash = self.broker.get_cash()
value = self.broker.get_value()
if cash <= 0:
break
if not self.getposition(self.data).size:
size = value * 0.001 / self.inds[d]["atr20"]
self.buy(d, size=size)
HI teddy
I would like to know as to who should I replace the following part ii , if I whant say instead want to maximize for other variant quantities say like calmar ratio
A = np.mean(R)
B = np.mean(np.square(R))
S = A / np.sqrt(B - A ** 2) # under function gradient
the above is just for sharpe ratio , that means that I have to write down the equivalent quantity to be maximized , then is it just enough to the following
def calc_calmar(rets):
# Peaks and bottoms indexes in sequence
mins = np.ravel(argrelmin(rets))
maxs = np.ravel(argrelmax(rets))
extrema = np.concatenate((mins, maxs))
extrema.sort()
return -rets.median()/np.diff(rets[extrema]).min()
then the above is just the another definition just like the one you introduced in your article i.e.
def sharpe_ratio(rets):
return rets.mean() / rets.std()
but now shall I add the quantity under gradient as well
mins = np.ravel(argrelmin(rets))
maxs = np.ravel(argrelmax(rets))
extrema = np.concatenate((mins, maxs))
extrema.sort()
return -rets.mean()/np.diff(rets[extrema]).min()
then finding derivatives w.r.t. the parameters of the calamr ratio , which are argmin and argmax ? is that right
your input is highly appreciated
best regards
Just a quick note to thank you for a splendid series of posts on Backtrader.
They are a great read!
Splendid code too.
hello, Thanks for your great work. I learned a lot from your posts
I have a question.
On post
trading-with-reinforcement-learning-in-python-part-two-application.ipynb
each time step, the flowing grad is calculated
(dRdF * dFdtheta + dRdFp * dFpdtheta)
my question is: it seems this is only part of grad of each step?
Hi Teddy,
I was trying to implement the code you have written.
Can you provide a sample csv file so that I can cross check with my csv file whether they are same or not. Because with my csv file, I am getting a lot of error.
There is a data leakage in "trading with reinforcement learning part two" notebook. You need to split data before making normalization, and not the other way around.
I admit your project and math are over my head. I'm still struggling to understand your position function and with that I'm trying to come up with a simple
How would that be done in your code?
best30 = momentums30.iloc[-1:].max().sort_values(ascending=False).index[:5]
plt.figure(figsize=(12, 9))
plt.xlabel('Days')
plt.ylabel('Stock Price')
for best in best30:
print ("best = ", best, " momentum = ", momentums30[best].iloc[-1 :])
rets = np.log(stocks[best].iloc[-30 :])
x = np.arange(len(rets))
slope, intercept, r_value, p_value, std_err = linregress(x, rets)
plt.plot(np.arange(90), stocks[best][-90:]);
y = np.arange(60, 90)
z = np.e ** (intercept + slope*x)
plt.plot(y, z)
plt.show();
Hello, great work. But, I just read thru here and found some trouble understanding this. Don't you want to find the best 5 momentum stocks of the the current day, not anyday in the past?
hence, I changed the code to
best30 = momentums30.iloc[-1:].max().sort_values(ascending=False).index[:5]
to get the current day best 5 momentum candidates. ( i used 30 days momentum in this example)
Also changed the plot on regression line from the current day back to 30 days ago.
a. I plotted the 90 day stock prices from 90 days ago to today
b. plotted the regression line only for the last 30 days of the stock prices.
I believe this makes much more sense.
Comments? thanks in advance.
Thanks for the bt version of Clenow momentum equity strategy.
QQ: Should the rankings be reverse sorted, as we want higher values first?
The line
self.rankings.sort(key=lambda d: self.inds[d]["momentum"][0])
would become
self.rankings.sort(key=lambda d: self.inds[d]["momentum"][0], reverse=True)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.