Giter Site home page Giter Site logo

thecsw / memeinvestor_bot Goto Github PK

View Code? Open in Web Editor NEW
135.0 17.0 35.0 5.31 MB

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

Python 78.90% Shell 0.70% TeX 3.94% Dockerfile 0.14% Perl 1.03% Go 15.30%

memeinvestor_bot's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

memeinvestor_bot's Issues

Suggestion: Make main.py single-threaded instead of using workers

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.

Bot should be easier to configure and deploy from scratch in a test environment

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.

Suggestion: Add cosmetic reward for users who have never gone bankrupt (or cosmetic punishment for users who have)

(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.

Bot should gracefully handle SIGTERM so it can be stopped without disrupting in-progress requests

(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.

Suggestion: Add inside trading penalty

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

Prevent investing in stickied posts?

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.

Calculator.py should query the database less furiously

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.

All in

Either a simple !allin or !invest balance to streamline betting all of your meme coins on one meme

Meme success should be determined by a time series, not by a comparison to initial vote count. (+other suggestions)

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.

ย 

Preface

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.

Problems

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.

ย 

Formula Enhancement

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.

ย 

Investment Changes:

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.

Investors can make profit from posts with 0 upvotes

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.

Change graph for Step 1 on the README

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 ๐Ÿ˜„

j0u2gzp

Bot should not process mentions

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().

Bot ignoring active transactions after 4 hours

#88 introduced a pretty big bug.

One of my investment was not processed at all after 4 hours.


direct link

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.

Going to Gitlab?

We all know that Microsoft has very aggressive business strategy. Remember Skype, Nokia, LinkedIn, Minecraft and etc.? Let's migrate to Gitlab!

Request: the OP will get a small percentage of investments as a reward for their post

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.

Big flaw in investment algorithm

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.

Bot is causing infinite calls to self.

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.

Add command to report unprocessed investment

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.

Before economy reset

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.

Add some time logging so we can see how long each request takes

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.

Deploying the bot should create an empty database if no database exists

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.

Minor timing bug when checking investments

(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.)

Some website css and functionality

Firstly, the search bar is a bit too high. At least for me.

Secondly, the search is working only when I press the arrow icon. Isn't more intuitive to press ENTER?

Thanks.

deepinscreenshot_select-area_20180606144701

Suggestion: Decouple the bot's input loop from its output loop

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.

Make a single top level comment on all /r/MemeEconomy posts, and only parse commands that are a reply to it

/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.

How is the initial growth factor of a post calculated when the initial score is 0?

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?

Reduce latency of bot replies

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:

untitled

(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.

Make chart dates more universal

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.

Inbox reading is making too many Reddit API calls

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().

Make it easy to quickly capture a backup of the live database

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).

Formula should be adjusted

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.

Problem

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.

How?

The key is to invest as early as possible, it almost always doesn't matter if the meme is good or not.

Example

Procedure

  • New meme is published (karma = 1).
  • User invests 1000 MemeCoins as quickly as possible.
  • User waits for bot to confirm the investment.
  • Bot confirms that 1000 MemeCoins have been invested when the submission had 1 karma.
  • User upvotes the meme

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...)

Some numbers

Investment Start karma End karma result
1000 1 5 1710
1000 1 10 2154
1000000000 1 5 1709975947
1000000000 1 10 2154434690

Solution

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 return

By 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.

TL;DR

After 4 hours, if the meme has...

  • A low total score, limit the maximum investment return.
  • A high total score, do not limit the maximum investment return.

I'm a little sleepy, so if there's anything unclear, let me know, I'll clarify.

Minor typos in messages

The word "successfull" should be "successful" and the word "unsuccessfull" should be "unsuccessful"

Add bot health monitoring service

We should have a service that can watch the bot's behavior and detect certain problematic patterns.

Possibilities include:

  • Detect when one of the service containers is crashing/restarting
  • Detect when the bot has stopped replying to requests
  • Detect if the bot's latency is getting high (large numbers of requests are aging past the 15 minute statute of limitations)

Maybe status could be displayed via another website off of memes.market. Or maybe we could message status to the bot runners directly.

!invest command should announce user's buy-in price

(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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.