thecsw / memeinvestor_bot Goto Github PK
View Code? Open in Web Editor NEWThis bot can help you invest in memes and make a fortune out of it!
Home Page: https://meme.market
License: GNU General Public License v2.0
This bot can help you invest in memes and make a fortune out of it!
Home Page: https://meme.market
License: GNU General Public License v2.0
I think the multithreading approach in main.py is likely a case of over-optimization. I haven't run the bot myself, but from what I can see of the code, there shouldn't be much benefit to using multiple concurrent CommentWorkers mediated by a Queue.
Explanation: From what I can tell, the limiting factor determining the bot's maximum throughput is likely to be the Reddit-enforced limit on its comment posting rate, not the processing time per response. If I understand correctly, the bot is limited to about 1 comment per second, which is far longer than it should take to process a request (even if we use inefficient code and have a database of millions of entries).
With that in mind, I'd recommend designing for clarity over cleverness by simplifying the main comment-processing loop to be single-threaded. Simple code is easier to maintain and reduces the chance of coding errors in the long run.
Of course this is just my hunch based on personal experience and my understanding of the codebase. If your direct experience with the bot says otherwise, that's fine.
Ideally a new developer should be able to install Docker, clone the repo, and run a single command to spin up a "dummy" version of the bot.
The dummy wouldn't need to have full functionality (like actually monitoring or posting to Reddit) but it should spin up a real database instance (probably empty). It should probably accept commands via stdin and print replies and output via stdout - enough functionality that devs can use it to validate certain changes easily.
(Totally up to you what direction you want to take your bot--just throwing this possible feature out there.)
It could encourage high-quality investment decisions if, for example, users who have gone bankrupt 3 times have a little [3โ ] added to their messages. Or, on the flip side, maybe users who have never gone bankrupt could get a little [๐ฐ] added to their messages.
(This is a longer-term change, not necessarily high priority.)
As currently architected, if we run docker-compose stop bot
it just straight up kills main.py
wherever it happens to be in the code. This could happen in the middle of handling a request, which means we could potentially have replied to a user but not updated the database, or other funky situations.
A better approach would be to allow the bot to complete its current request before shutting down gracefully.
Edit: Same goes for calculator
and submitter
services too, of course.
9 house after the command the bot finally replied. I can see this being a problem if someone invested and it took too long.
Proof: https://imgur.com/a/BiScB9g
Per suggestion by @thecsw, the api
service should expose a method to compute the return given a set of parameters. This way, tweaks to our formula will automatically be reflected on the website.
Could be fun for users to see how many investments are currently awaiting evaluation. This would kind of mimic the concept of "market volume" in the real stock markets. The command could give the total number of active trades, plus the total amount of MemeCoin currently on the line.
As some redditors have pointed out, insider trading ( investing in your own meme) can be a serious issue, and should be penalized with a profit reduction in case of succesful investment
When a r/memeeconomy post is stickied, the submitter agent still makes an Invest Here! comment and people are able to invest in the stickied post. But since these posts are not usually memes, that means people are investing in something that's not a meme! Up to you guys, but maybe we should ignore stickied posts.
I don't think it's actually causing any problems, but I noticed that calculator.py
is checking dozens of times per second for investments to mature, which is clearly overkill. It should probably sleep for a little bit between checks, or (more complicated) look up when the next investment will mature and sleep that long.
Either a simple !allin or !invest balance to streamline betting all of your meme coins on one meme
Let me start out by pointing out I'm an Economics major in university with an extensive background in statistical economics, not that this makes me an expert by any means; I just hope to establish some sort of credibility for my claims.
ย
The investor bot could be a great tool to keep users active on the subreddit, if implemented correctly.
Let me ask you a question: do you want the bot to just be a short-term gimmick, or a long-term tool to keep users engaged and active in the community?
Given that the creator has developed a beautiful website for the bot, I'm going to assume the answer is the latter. If this is the case, then something needs to change.
There are two separate issues that must be addressed: the formula and the investing system. The formula is self-explanatory, but when I say "investing system", I refer to two fatal flaws: users can invest as much as they want, and any post can take an infinite amount of investments.
To fix the investing problem, both of these flaws must be addressed. But first, I'd like to talk about the formula.
ย
The current main problem with the formula is with the first step in the two-step process; specifically, that it determines success by comparing final with initial. As mentioned, this leaves a large hole for users to take advantage of, specifically by investing when a post is at 1 or 2 upvotes and (at worst) having it naturally increase into the teens. In fact, even the smallest upvote increase possible, from 1 to 2, is considered successful according to the bot, when it clearly isn't.
My proposal is to deem a meme successful by the rate, not the amount, at which upvotes increase, compared to an established baseline of success (the value of which should be determined from real, human analysis of "successful" and "unsuccessful" threads). Specifically, the bot should conduct a time series on the amount of upvotes, tracked every 30 minutes to determine whether the upward trend is greater or less than a certain baseline.
It would be way more beneficial to use a time series, a method of calculation that is actually used in the stock market, as opposed to an algebraic function that allows for disproportionate, spastic growth for investments made at the post's creation.
ย
To correct those two points of failure I mentioned above, I propose a 50,000 coin cap on investments per user per image (and to prevent using multiple !invest comments to get around this). This prevents users from investing as much as they can on an image to reap infinite benefits.
Secondly, I propose a net investment cap per image ("net cap") at any given time; i.e. if a meme currently has a total of 1,000,000 coins invested in it, then no one else can invest until one of those investments has expired and the total amount of coins invested has decreased below the cap. This means the opportunity to invest is no longer infinite, leading to a reduction in exponential growth.
ย
I understand the mods are fully competent and able to handle the situation on their own, however if they are open to the idea of discussing any means to stabilize the economy, I'd be more than happy to reach out and toss some ideas back and forth as well as assist in crafting an effective time series system.
(Also the figures of 50,000 and 1,000,000 are just examples and not set in stone.)
ย
Please let me know your thoughts. I will be cloning the source code and testing different formulas to show the benefits of a time series.
This is not a serious issue, but it does raise some concerns on how powerful a single vote can be and how it affects profits.
Given the current state of the algorithm, there is relatively no risk in investing something with 0 score, because it can't have a lower score than that. You only lose profits if a post doesn't gain score or only has a lower score after you've invested.
This means that memes that... attract downvotes are actually very profitable. One can invest in posts that have 0 upvotes, wait, then upvote before four hours. By then, the post has lost attention and is probably 50 pages away from new.
See Example 1.
It's a bit counter-intuitive but hey that's economics for you.
think it should be .profit, rather than .proft.
As the current graph with the blue line looks outdated, I decided to make a new graph that compliments what's already present on the README.
I recommend using the graph below, or make a different one of course if you want. I'd love to help you guys out more with what you need but I know nothing about coding/programming. You guys are doing God's work here ๐
As mentioned in #30, commands that are not replies to the top level comment should be completely ignored.
That way, not only can the bot be improved (only check for replies of top level comment rather than all comments), it will be future-proof as some users will eventually complain about the fact that all the !invest
, !balance
, !create
commands are ruining the comment section of the subreddit.
Reported by genericusername123
The inbox doesn't just contain comment replies and direct messages--it also contains mentions. Since I removed the .parent()
check, the bot will currently process any commands in a mention, even from other subreddits.
We could fix this by putting the .parent()
check back in or by testing for the bot's name in every processed comment, but I think the best way is to switch from praw.reddit.inbox.unread()
to praw.reddit.inbox.comment_replies()
.
Seems we changed the graph on the readme, might as well update the graph on the website's homepage too?
Sell risky investments to other investors to make it a more realistic market
#88 introduced a pretty big bug.
One of my investment was not processed at all after 4 hours.
It's fine to ignore old !invest
commands, but active investments should not be ignored.
At worse, updating the bot's comment after 4 hours could be skipped, as long as the user's balance is updated on the database.
I think we should rework the way we're dealing with the way !invest
commands are processed: Even if the bot hasn't commented, the investment should be registered in the database.
That would prevent the bot from being inaccurate due to the limitations of Reddit's API.
We all know that Microsoft has very aggressive business strategy. Remember Skype, Nokia, LinkedIn, Minecraft and etc.? Let's migrate to Gitlab!
I'm assuming there is no insider trading. If there is no insider trading, it means there is less motivation for an OP to put out a good meme. If theirs is doing really well, and they are unable to invest in it, it benefits everyone besides the OP. I'm thinking the poster should get 1% of whatever investments are made or less.
It also gives OP a reason to not delete their meme if it starts doing really well. If it stays up, then more people will invest and OP will benefit. I'm not sure exactly what happens though right now if someone takes down a post that people just put a lot of investments into though.
Currently the "x" variable in the algorithm for the return is an absolute change in upvotes. This creates problems. If I invest in something with 1 upvote I am risking a lot, no one knows what will happen, pretty good if it then ends up at 1000 upvotes after 4 hours. On the other hand if there's a post with 100k upvotes, it's pretty much guaranteed that it will gain more than just 1000 additional upvotes in 4 hours, why wouldn't it? It's already at 100k. In these examples I feel like the first investor should get about a 10x return on his investment and the second investor should gain pretty much nothing, probably in fact lose half of his/hers investment as it gained only a 1% increase in upvotes. The return should be a mix of absolute change and percentage based change.
Whenever a user attempts to !help or !create the bot will print the help text which contains !help which will cause the !help text to be printed again which causes the same issue example.
One easy way to fix this would be to add a !ignore command to main.py and check for it first before any of the other commands around this line in main.py. Then have the !ignore as one of the listed commands in the !help message.py which would both solve the problem and give a way for users to demonstrate the commands someone would need without triggering them.
Some people have investments that are still unprocessed (e.g. me)
The command would force the bot to read the previous investment comment it posted, and update it accordingly.
I am aware that this is no easy command to add, but having a command like !fixinvestment
is significantly easier than having to re-process all comments.
I'm not sure if this has happened to others, but it has happened to me on several occasions.
This would make it easier to test the bot on the test subreddit without having to make code changes.
Today we tell users how many MemeCoins they gained/lost. If we also (or instead) told them their new balance, we could save users some mental math or a !balance request.
I think that we should list everything that has to be done before the economy reset here.
We can't afford to reset the economy weekly, so we should make sure that everything is in place before.
Most importantly, we need to find a way to make the bot faster.
A slow bot means inaccurate investments (and angry investors), so while this is going to be hard to work around due to the API limitations, it has to be done.
I think main.py
, which handles incoming Reddit requests, should include some timing measurement and logging so that we can tell how long each request takes. Might be useful for improving performance.
To start with, we could just measure the time each iteration of the inbox for
loop takes, and log it.
I'm also not sure what the right timing mechanism to use is.
Bot messages include the line "For more information type !help", which triggers the bot itself. Comment thread for reference: https://www.reddit.com/r/MemeEconomy/comments/8lmryv/versatile_and_easy_to_use_format/dzh4zun/
The code today depends on the existence of a pre-initialized database, which makes it difficult to do your own test deployment from scratch.
If someone who understands SQLAlchemy could update the project to handle the case when no Investor or Investment tables exist (at least when DRY_RUN is enabled), that would be super helpful.
!short AMOUNT
To short bad memes
(This is a minor issue unlikely to affect many users or many investments.)
There's a small logical error in the way check_investments timing and upvote counts. Basically, if a bunch of people make investments around the same time, then 6 hours later, only the first investment of that bunch will have his investment evaluated at 6 hours---the rest will have their investments evaluated at 6hrs+1sec, 6hrs+2sec, 6hrs+3sec, etc.
So if sixty people camping /new all invest in a new meme simultaneously, the one who invested last by a few milliseconds would unfairly get the benefit of an extra minute's worth of upvotes six hours later. (Like I said, this is not a big deal unless you see lots of bursts of investing activity or you increase your 1s loop delay.)
Currently, the bot only processes new commands and updates the game state as fast as it can output the results. (Said differently, its input loop, game state loop, and output loop are all closely coupled.) The bot could be made more flexible and responsive if these loops were decoupled: allow the input loop to process commands and update the game state in real time, while the output loop is responsible for independently reading the game state and posting updates on Reddit (the slow part). This would also free up the system to support additional output loops (like a website) that can run independently and be updated in real time.
Explanation: (I'll focus on the input loops in main.py, although this all applies similarly to calculator.py.) Currently, the processing loops post comments synchronously. This means that the loop cannot continue until the posted/edited comment goes through, limiting throughput to one processed command per second. (I'm assuming the bot is still limited to one post or edit per second; please let me know if that's inaccurate.)
A decoupled design would have the input loop read comments, process commands, and update the database in real time. However, actually posting the results to Reddit would be the work of an output loop running separately. At first, this output loop should probably just makes direct replies like the bot does today. But with a decoupled design we have the flexibility to make the output loop, say, provide batched investment summary posts instead of direct replies (to help with posting limits).
This is obviously a major refactoring job, but I think it will be necessary to keep up with demand and also to provide other interfaces (output loops) to the game state.
/r/MemeEconomy comment threads have become littered with MemeInvestor Bot commands. The easiest way to circumvent this is to have the bot add a single comment upon the posting of a new thread, and to only listen for/respond to commands that are in reply to that comment. (Effectively, just check that a comment is replying to any comment made by the bot).
This will greatly improve the /r/MemeEconomy browsing experience while giving the added benefit of keeping all MemeInvestor commands in a single place.
From the formula on your website, it looks to be impossible to calculate the return on an investment on a post that started with 0 upvotes, as it would require to divide by zero. However, having invested in a post with 0 upvotes myself, I know this not to be true.
Is there some other way to calculate the initial growth factor of a post when it has a score of 0 points?
After our conversation the other day about performance, I went ahead and did some rudimentary measurements. More work to be done of course, but this is a starting point.
tl;dr: We do appear to have a latency problem (i.e. the bot takes too long to reply to commands) but also there is some weird resetting pattern that I can't explain. There have been a variety of proposals to reduce latency, we'll need to look into which ones make sense.
I wrote a simple script to monitor the bot's posts and compare their timestamps to the timestamps of the posts the bot was replying to. I can't be sure my script was bug-free but I did some sanity checks and it appears to be accurate. Here are the results:
(Each bar in the chart is one response from the bot. The height of the bar is the time, in seconds, between the command and bot's reply. This was looking at replies the bot made from about noon-1 Pacific time today.)
First thing to notice: Latency gets very bad. The bot is regularly taking over 10 minutes to reply to commands. So there's a problem to be solved.
Second thing: Latency consistently increases with time. I believe this means that on average during these hours, the bot simply doesn't have the throughput to keep up with demand.
Third thing: There's an obvious pattern where the latency drops down occasionally. I'm guessing the bot is hitting some sort of error and resetting. Unclear if the bot is dropping commands during these events.
Edit: Not all of these conclusions are accurate; see below for updated thoughts.
Could be fun for people to be able to see, for example, the top 10 balances (and associated usernames)
Easy tweak:
Currently, the dates on the website's investment chart go like: 8/6
, 9/6
, 10/6
. As a silly American this confuses me because I expect dates like 6/8
, 6/9
, 6/10
.
Requesting that we localize the chart dates, or at least update them to something slightly more intuitive for those visitors like me: something like 8 June
, 9 June
, 10 June
would be fine.
When we changed from
for comment in reddit.subreddit('+'.join(config.subreddits)).stream.comments(skip_existing=True):
to
for comment in reddit.inbox.unread(limit=None):
we switched from a "streaming" method to a regular querying method. The difference is that stream.comments()
has automatic backoff logic---if Reddit returns no new comments, it waits a bit longer before asking Reddit again (1 second, then 2, then 4, etc. up to a maximum of 16 seconds).
On the other hand, inbox.unread()
gets called every second, even if no new comments are returned.
It probably doesn't make too much of a difference, as long as there are lots of new comments coming in. But we could save some Reddit API calls by switching to inbox.stream()
.
We should be in the habit of backing up the live database every time we make a major change to the bot. We should make that as easy as possible (maybe just a script that can be run from the server, or maybe a service that automatically captures periodic backups).
NOTE: I'm not saying that there is anything wrong with investing early! However, if a meme ends up with 10 upvotes at the end of the 4 hours mark, the meme should not be considered as high quality, thus the value of the meme on the market should yield a lower investment return than a meme that has 500+ upvotes after 4 hours.
Making MemeCoins is too easy with the current formula, and it needs to be adjusted. Even if a meme is bad, as long as one invests as early as possible, he's guaranteed to make a fortune.
The only factor currently taken in consideration is the submission karma when the user invests and the karma when the 4 hours passed. The value of the meme itself on the market is completely ignored.
The key is to invest as early as possible, it almost always doesn't matter if the meme is good or not.
At this point, the meme already has 2 karma, which bypasses the 1.2 threshold. While it can get downvoted, it is much more likely that at the very least** a few people will upvote, even if the meme is not necessarily high quality.
Maybe you don't see the problem yet, so to be more clear, if after 4 hours, the meme has a score of 10, the meme should be considered bad (an average of 2.5 upvotes per hour is bad). However, the user who voted when there was 1 upvote will still make a ton of MemeCoins because every single upvote is a multiple of initial investment, (10 upvotes = 10 x 1 upvotes...)
Investment | Start karma | End karma | result |
---|---|---|---|
1000 | 1 | 5 | 1710 |
1000 | 1 | 10 | 2154 |
1000000000 | 1 | 5 | 1709975947 |
1000000000 | 1 | 10 | 2154434690 |
To be as accurate as possible, we'd need to monitor the rise of each memes over time, and calculate the investment return based on the growth factor over time, but clearly, that's not possible due to the large amount of submissions.
Instead, a range threshold should also be added.
With real stocks, we'd have a volume and a price per share, however, there's no volume and no price per share for memes. To replace the volume, the total amount of upvotes should be used.
For instance:
End karma < 10
: max investment return = 120%End karma < 20
: max investment return = 140%End karma > 100
: no limit to max investment returnBy implementing a range like that, early investors will not get a big investment return if after 4 hours, the meme has a small volume on the market whereas if the meme has a large volume, the user would not be affected by this limitation.
After 4 hours, if the meme has...
I'm a little sleepy, so if there's anything unclear, let me know, I'll clarify.
It would be nice if every row in "Investments" table had a final investments return result.
For example, +100 or -400 MemeCoins.
The word "successfull" should be "successful" and the word "unsuccessfull" should be "unsuccessful"
just save the current timestamp on page load, and check it every time the update function is called
We should have a service that can watch the bot's behavior and detect certain problematic patterns.
Possibilities include:
Maybe status could be displayed via another website off of memes.market. Or maybe we could message status to the bot runners directly.
(Just a suggestion to make investments more dramatic and social.) I noticed several memes where someone had invested early and were about to make bank, but others couldn't really tell how early. The !invest command should include something like, "You bought in at 4 upvotes" so spectators can really tell when a master got in on the ground floor.
See the example response here:
https://www.reddit.com/r/MemeEconomy/comments/8o173y/meme_wars_the_bot_awakens/dzzw5fz/?st=jhxmedmk&sh=1d68ad6a
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.