def find_threshold_old(f, fixed_b, min_a, max_a, target): for a in range(min_a, max_a, 1): if a > fixed_b: multA = formula.calculate(a, fixed_b) multB = formula.calculate(a + 1, fixed_b) if multA < target and multB >= target: return a return None
def main(): # == Parse initial and final upvotes from command line parser = argparse.ArgumentParser(description='Interactive command line tool for performing test calculations for investment return.') parser.add_argument('u_init', metavar='u_init', type=int, help='Post upvotes at time of investment.') parser.add_argument('u_final', metavar='u_final', type=int, help='Post upvotes at maturation of investment.') parser.add_argument('invested', metavar='invested', type=int, help='MemeCoins Invested in post.') parser.add_argument("-s", "--save-img", help="Save generated plot to file 'investment_performance.png'", action="store_true") args = parser.parse_args() print("Starting Upvotes:", args.u_init) print("Final Upvotes:", args.u_final) print("Amount Invested:", args.invested, "M¢") inv_return = calculate(args.u_final,args.u_init) * args.invested profit = inv_return - args.invested print(">> RETURN:", inv_return, "M¢ (Profit:", profit, "M¢)") #Generate data for performance plot olds = list(range(args.u_init, args.u_final * 2, 1))# + list(range(args.u_final, args.u_final * 2, 10)) x = [] x2 = [] y = [] y2 = [] for i in olds: x.append(i) result = calculate(i,args.u_init) * args.invested y.append(result) if i <= args.u_final: x2.append(i) y2.append(result) #Generate performance plot fig = plt.figure(figsize=(7,7)) plt.grid(color='k', alpha=0.15, which='major') plt.title('Investment Performance',fontsize='18') plt.xlabel('Upvotes',fontsize='14') plt.ylabel('Return / M¢',fontsize='14') plt.plot(x,y,label='Return curve') plt.plot(x2,y2,label='Meme Performance',color='r') plt.plot(args.u_final, inv_return, color='r', marker='X', markersize=8, linestyle='none', label='Return: %i M¢ (Profit: %i M¢)' %(inv_return,profit)) plt.legend(fontsize='12') #Interactive show plot plt.show() #Optional save plot if args.save_img: out_filename = 'investment_performance.png' print ("Saving image to: '",out_filename,"'") fig.savefig(out_filename)
def calculate_investment(): new = int(request.args.get('new')) old = int(request.args.get('old')) factor = calculate(new, old) res = {"factor": factor} return jsonify(res)
def calculate_investment(): """ !!! DEPRECATED !!! Calculate investment """ new = int(request.args.get('new')) old = int(request.args.get('old')) factor = calculate(new, old) res = {"factor": factor} return jsonify(res)
def find_threshold(fixed_b, min_a, max_a, target): # print(f"min: {min_a}, max: {max_a}, target: {target}") if abs(max_a - min_a) <= 1: # print("Reached base case") v = calculate(min_a, fixed_b) # print(f"v: {v}") return min_a mid_a = (max_a + min_a) / 2 # print(f"mid: {mid_a}") v = calculate(mid_a, fixed_b) # print(f"v: {v}") if v < target: # print("Below the target - guessing higher") return find_threshold(fixed_b, mid_a, max_a, target) else: # print("Above the target - guessing lower") return find_threshold(fixed_b, min_a, mid_a, target)
def main(): startings = [1, 5, 10, 20, 50] limit = 230 deltas = [2, 5, 10, 20] threshs = [1, 1.25, 1.5, 2, 2.5] min_n = 0 max_n = 1000 print('Inizio | Fine | Totale | Rendimento') print('---|---|----|----') for starting in startings: endings = list([d * starting for d in deltas]) for t in threshs: endings.append(find_threshold(starting, min_n, max_n, t)) endings = set([int(math.ceil(e)) for e in endings if e and e <= limit]) endings = sorted(endings) for ending in endings: ret = calculate(ending, starting) print('{:d} | {:d} | {:.2f} | {:+.2f}'.format( starting, ending, ret, ret - 1))
def main(): startings = [1, 10, 20, 50] limit = 230 deltas = [2, 5, 10, 20] threshs = [1, 1.25, 1.5, 2, 2.5] min_n = 0 max_n = 1000 print("Inizio | Fine | Totale | Rendimento") print("---|---|----|----") rets = set() for starting in startings: endings = list([d * starting for d in deltas]) for t in threshs: endings.append(find_threshold(starting, min_n, max_n, t)) endings = set([int(math.ceil(e)) for e in endings if e and e <= limit]) endings = sorted(endings) for ending in endings: ret = calculate(ending, starting) rets.add(ret) print("{:d} | {:d} | {:.2f} | {:+.2f}".format( starting, ending, ret, ret - 1)) pnet_worths = [0.1, 0.2, 0.5, 0.8, 1] top_networths = [1000, 5000, 100000, 100000000, 100000000000] rets = [0.1, 0.5, 1.0, 1.2, 1.5, 2, 2.5] print("\nPatrimonio | Top | Aggiustamento") print("---|---|---") for pnet_worth in pnet_worths: ret = 3 top_networth = 1000000 net_worth = int(pnet_worth * top_networth) nret = adjust(ret, net_worth, top_networth) print("{:,d} | {:,d} | {:+.2f}%".format(net_worth, top_networth, (nret - ret) / ret * 100)) print("\nRend. Orig. | Patrimonio | Top | Totale | Rendimento | Delta") print("---|---|---|---|----|----") for ret in rets: for top_networth in top_networths: for pnet_worth in pnet_worths: net_worth = int(pnet_worth * top_networth) nret = adjust(ret, net_worth, top_networth) print("{:.2f} | {:,d} | {:,d} | {:.2f} | {:+.2f} | {:+.2f}". format(ret, net_worth, top_networth, nret, nret - 1, (nret - ret) / ret * 100))
def main(): logging.info("Starting calculator...") killhandler = KillHandler() engine = create_engine() session_maker = sessionmaker(bind=engine) reddit = praw.Reddit( client_id=config.CLIENT_ID, client_secret=config.CLIENT_SECRET, username=config.USERNAME, password=config.PASSWORD, user_agent=config.USER_AGENT, ) # We will test our reddit connection here if not utils.test_reddit_connection(reddit): return () praw.models.Comment.edit_wrap = edit_wrap stopwatch = Stopwatch() logging.info("Retrieving top ...") # query sess = session_maker() try: top_networth = (sess.query( Investor.name, func.coalesce(Investor.balance + func.sum(Investment.amount), Investor.balance).label("networth"), ).outerjoin( Investment, and_(Investor.name == Investment.name, Investment.done == 0)).group_by(Investor.name).order_by( desc("networth")).limit(1).one())[1] except NoResultFound: top_networth = 0 top_networth = max(top_networth, config.STARTING_BALANCE * 10) # al last starting * 10 sess.close() logging.info("Top networth: %d", top_networth) logging.info("Monitoring active investments...") while not killhandler.killed: sess = session_maker() then = int(time.time()) - config.INVESTMENT_DURATION investment = (sess.query(Investment).filter( Investment.done == 0).filter(Investment.time < then).order_by( Investment.time.asc()).first()) if not investment: # Nothing matured yet; wait a bit before trying again time.sleep(50) continue duration = stopwatch.measure() investor = sess.query(Investor).filter( Investor.name == investment.name).one() net_worth = investor.networth(sess) logging.info("New mature investment: %s", investment.comment) logging.info(" -- by %s", investor.name) # Retrieve the post the user invested in (lazily, no API call) post = reddit.submission(investment.post) # Retrieve the post's current upvote count (triggers an API call) upvotes_now = post.ups investment.final_upvotes = upvotes_now investment.op = (post.author and investor.name == post.author.name) investment.net_worth = net_worth investment.top_networth = top_networth # Updating the investor's balance factor = formula.calculate(upvotes_now, investment.upvotes, net_worth, top_networth) if factor > 1 and post.author and investor.name == post.author.name: # bonus per OP factor *= formula.OP_BONUS amount = investment.amount balance = investor.balance new_balance = int(balance + (amount * factor)) change = new_balance - balance profit = change - amount # Updating the investor's variables investor.completed += 1 # Retrieve the bot's original response (lazily, no API call) if investment.response != "0": response = reddit.comment(id=investment.response) else: response = EmptyResponse() if new_balance < BALANCE_CAP: # If investor is in a firm and he profits, # 15% goes to the firm investor.balance = new_balance # Edit the bot's response (triggers an API call) if profit > 0: logging.info(" -- profited %s", profit) elif profit == 0: logging.info(" -- broke even") else: logging.info(" -- lost %s", profit) edited_response = message.modify_invest_return( investment.amount, investment.upvotes, upvotes_now, change, profit, investor.balance, ) response.edit_wrap(edited_response) else: # This investment pushed the investor's balance over the cap investor.balance = BALANCE_CAP # Edit the bot's response (triggers an API call) logging.info(" -- profited %s but got capped", profit) response.edit_wrap( message.modify_invest_capped( investment.amount, investment.upvotes, upvotes_now, change, profit, investor.balance, )) investment.success = profit > 0 investment.profit = profit investment.done = True sess.commit() if top_networth < investor.balance: top_networth = investor.balance logging.info("New Top networth: %d", top_networth) # Measure how long processing took duration = stopwatch.measure() logging.info(" -- processed in %.2fs", duration) # Report the Reddit API call stats rem = int(reddit.auth.limits["remaining"]) res = int(reddit.auth.limits["reset_timestamp"] - time.time()) logging.info(" -- API calls remaining: %s, resetting in %.2fs", rem, res) sess.close()
def main(): fig = plt.figure(figsize=(15, 15)) # Lay out the figure as a grid of subplots gridspec.GridSpec(6, 2) # ---GRAPH A--- # Plotting return curve for different olds # Upper left subplot ax = plt.subplot2grid((6, 2), (0, 0), rowspan=3, colspan=1) olds = [ 0, 1, 5, 10, 25, 50, 100, 200, 500, 1000, 2500, 5000, 7500, 10000, 15000, 20000 ] news = range(0, 25000) xy = [] for o in olds: x = [] y = [] for n in news: if n > o: x.append(n) y.append(formula.calculate(n, o)) xy.append([x, y]) for (x, y) in xy: plt.plot(x, y) ax.grid(color='k', alpha=0.15, which='major') ax.set_ylim([0, 5.5]) plt.legend(list(olds)) plt.title('Return factor') plt.xlabel('new') plt.ylabel('calculate(new, old)') # ---GRAPH B--- # Plotting return curve for small olds only # Bottom left subplot ax = plt.subplot2grid((6, 2), (3, 0), rowspan=3, colspan=1) olds = [0, 1, 5, 10, 25, 50, 100, 200, 300] news = range(0, 500) xy = [] for o in olds: x = [] y = [] for n in news: if n > o: x.append(n) y.append(formula.calculate(n, o)) xy.append([x, y]) for (x, y) in xy: plt.plot(x, y) ax.grid(color='k', alpha=0.15, which='major') ax.set_ylim([0, 5.5]) plt.legend(list(olds)) plt.title('Return factor') plt.xlabel('new') plt.ylabel('calculate(new, old)') # ---GRAPH C.1--- # Plotting sigmoid_max # Upper right subplot ax = plt.subplot2grid((6, 2), (0, 1), rowspan=1, colspan=1) olds = range(0, 25000) x = [] y = [] for o in olds: x.append(o) y.append(formula.sigmoid_max(o)) plt.plot(x, y) ax.grid(color='k', alpha=0.15, which='major') ax.set_ylim([0, 5.5]) plt.title('sigmoid_max(old)') plt.xlabel('old') # ---GRAPH C.2:--- # Plotting sigmoid_midpoint # Upper right subplot ax = plt.subplot2grid((6, 2), (1, 1), rowspan=1, colspan=1) olds = range(0, 25000) x = [] y = [] for o in olds: x.append(o) y.append(formula.sigmoid_midpoint(o)) plt.plot(x, y) ax.grid(color='k', alpha=0.15, which='major') plt.title('sigmoid_midpoint(old)') plt.xlabel('old') # ---GRAPH C.3--- # Plotting sigmoid_steepness # Upper right subplot ax = plt.subplot2grid((6, 2), (2, 1), rowspan=1, colspan=1) olds = range(0, 25000) x = [] y = [] for o in olds: x.append(o) y.append(formula.sigmoid_steepness(o)) plt.plot(x, y) ax.grid(color='k', alpha=0.15, which='major') plt.title('sigmoid_steepness(old)') plt.xlabel('old') # ---GRAPH D--- # Plotting return multiplier thresholds # A recursive function to quickly find the threshold parameter value faster. # # Given: # - function f(a, b) # - fixed input value b # - range of input values min_a to max_a # - target output value # # The find_threshold function basically does a binary search from min_a to max_a # until it finds a value of 'a' such that f(a, b) ~ 'target'. This corresponds # to the threshold value of 'a' where f(a, b) first exceeds 'target' (assuming # a monotonically increasing function, like the sigmoid function). def find_threshold(f, fixed_b, min_a, max_a, target): # print(f"min: {min_a}, max: {max_a}, target: {target}") if abs(max_a - min_a) <= 1: # print("Reached base case") v = f(min_a, fixed_b) # print(f"v: {v}") if abs(v - target) < 0.01: # print("Close enough!") return min_a else: # print("Nope, returning None") return None mid_a = (max_a + min_a) / 2 # print(f"mid: {mid_a}") v = f(mid_a, fixed_b) # print(f"v: {v}") if v < target: # print("Below the target - guessing higher") return find_threshold(f, fixed_b, mid_a, max_a, target) else: # print("Above the target - guessing lower") return find_threshold(f, fixed_b, min_a, mid_a, target) # And here's the previous approach, just in case you prefer it or want # to compare results against the new version. def find_threshold_old(f, fixed_b, min_a, max_a, target): for a in range(min_a, max_a, 1): if a > fixed_b: multA = formula.calculate(a, fixed_b) multB = formula.calculate(a + 1, fixed_b) if multA < target and multB >= target: return a return None # Bottom right subplot ax = plt.subplot2grid((6, 2), (3, 1), rowspan=3, colspan=2) olds = range(0, 1000, 1) min_n = 0 max_n = 10000 xy = [] x2y2 = [] mult_threshs = [1, 1.25, 1.5, 2, 3, 4, 5] for M in mult_threshs: x = [] y = [] x2 = [] y2 = [] for o in olds: # n = find_threshold_old(formula.calculate, o, min_n, max_n, M) n = find_threshold(formula.calculate, o, min_n, max_n, M) if n: x.append(o) x2.append(o) y.append(n) y2.append(n - o) xy.append([x, y]) x2y2.append([x2, y2]) for (x, y) in x2y2: plt.plot(x, y) ax.legend(['break-even', '1.25x', '1.5x', 'x2', 'x3', 'x4', 'x5']) plt.grid(color='k', alpha=0.15, which='major') plt.title('1-8 Factor thresholds') plt.xlabel('old') plt.ylabel('delta') plt.tight_layout() fig.set_size_inches(18, 18) fig.savefig('all_plot.png')
def main(): logging.info("Starting calculator...") logging.info( "Sleeping for 8 seconds. Waiting for the database to turn on...") time.sleep(8) killhandler = KillHandler() engine = create_engine(config.DB, pool_recycle=60, pool_pre_ping=True) session_maker = sessionmaker(bind=engine) reddit = praw.Reddit(client_id=config.CLIENT_ID, client_secret=config.CLIENT_SECRET, username=config.USERNAME, password=config.PASSWORD, user_agent=config.USER_AGENT) # We will test our reddit connection here if not utils.test_reddit_connection(reddit): exit() praw.models.Comment.edit_wrap = edit_wrap stopwatch = Stopwatch() logging.info("Monitoring active investments...") while not killhandler.killed: sess = session_maker() then = int(time.time()) - config.INVESTMENT_DURATION investment = sess.query(Investment).\ filter(Investment.done == 0).\ filter(Investment.time < then).\ order_by(Investment.time.asc()).\ first() if not investment: # Nothing matured yet; wait a bit before trying again time.sleep(5) continue duration = stopwatch.measure() investor = sess.query(Investor).filter( Investor.name == investment.name).one() net_worth = sess.\ query(func.sum(Investment.amount)).\ filter(and_(Investment.name == investor.name, Investment.done == 0)).\ scalar()\ + investor.balance logging.info("New mature investment: %s", investment.comment) logging.info(" -- by %s", investor.name) # Retrieve the post the user invested in (lazily, no API call) post = reddit.submission(investment.post) # Retrieve the post's current upvote count (triggers an API call) upvotes_now = post.ups investment.final_upvotes = upvotes_now # Updating the investor's balance factor = formula.calculate(upvotes_now, investment.upvotes, net_worth) amount = investment.amount balance = investor.balance new_balance = int(balance + (amount * factor)) change = new_balance - balance profit = change - amount percent_str = f"{int((profit/amount)*100)}%" # Updating the investor's variables investor.completed += 1 # Retrieve the bot's original response (lazily, no API call) if investment.response != "0": response = reddit.comment(id=investment.response) else: response = EmptyResponse() firm_profit = 0 if new_balance < BALANCE_CAP: # If investor is in a firm and he profits, # 15% goes to the firm firm_name = '' if investor.firm != 0 and profit >= 0: firm = sess.query(Firm).\ filter(Firm.id == investor.firm).\ first() firm_name = firm.name user_profit = int(profit * ((100 - firm.tax) / 100)) investor.balance += user_profit + amount firm_profit = int(profit * (firm.tax / 100)) firm.balance += firm_profit else: investor.balance = new_balance # Edit the bot's response (triggers an API call) if profit > 0: logging.info(" -- profited %s", profit) elif profit == 0: logging.info(" -- broke even") else: logging.info(" -- lost %s", profit) edited_response = message.modify_invest_return( investment.amount, investment.upvotes, upvotes_now, change, profit, percent_str, investor.balance) if investor.firm != 0: edited_response += message.modify_firm_tax( firm_profit, firm_name) response.edit_wrap(edited_response) else: # This investment pushed the investor's balance over the cap investor.balance = BALANCE_CAP # Edit the bot's response (triggers an API call) logging.info(" -- profited %s but got capped", profit) response.edit_wrap( message.modify_invest_capped(investment.amount, investment.upvotes, upvotes_now, change, profit, percent_str, investor.balance)) investment.success = (profit > 0) investment.profit = profit investment.done = True sess.commit() # Measure how long processing took duration = stopwatch.measure() logging.info(" -- processed in %.2fs", duration) # Report the Reddit API call stats rem = int(reddit.auth.limits['remaining']) res = int(reddit.auth.limits['reset_timestamp'] - time.time()) logging.info(" -- API calls remaining: %s, resetting in %.2fs", rem, res) sess.close()
def main(): logging.info("Starting calculator") killhandler = KillHandler() engine = create_engine(config.db, pool_recycle=60) sm = sessionmaker(bind=engine) reddit = praw.Reddit(client_id=config.client_id, client_secret=config.client_secret, username=config.username, password=config.password, user_agent=config.user_agent) praw.models.Comment.edit_wrap = edit_wrap stopwatch = Stopwatch() logging.info("Monitoring active investments...") while not killhandler.killed: try: sess = sm() then = int(time.time()) - config.investment_duration investment = sess.query(Investment).\ filter(Investment.done == 0).\ filter(Investment.time < then).\ order_by(Investment.time.asc()).\ first() if not investment: # Nothing matured yet; wait a bit before trying again time.sleep(5) continue duration = stopwatch.measure() investor = sess.query(Investor).filter(Investor.name == investment.name).one() logging.info(f"New mature investment: {investment.comment}") logging.info(f" -- by {investor.name}") # Retrieve the post the user invested in (lazily, no API call) post = reddit.submission(investment.post) # Retrieve the post's current upvote count (triggers an API call) upvotes_now = post.ups investment.final_upvotes = upvotes_now # Updating the investor's balance factor = formula.calculate(upvotes_now, investment.upvotes) amount = investment.amount balance = investor.balance new_balance = int(balance + (amount * factor)) change = new_balance - balance profit = change - amount percent_str = f"{int((profit/amount)*100)}%" # Updating the investor's variables investor.completed += 1 # Retrieve the bot's original response (lazily, no API call) if investment.response != "0": response = reddit.comment(id=investment.response) else: response = EmptyResponse() if new_balance < BalanceCap: investor.balance = new_balance # Edit the bot's response (triggers an API call) if profit > 0: logging.info(f" -- profited {profit}") elif profit == 0: logging.info(f" -- broke even") else: logging.info(f" -- lost {profit}") response.edit_wrap(message.modify_invest_return(investment.amount, investment.upvotes, upvotes_now, change, profit, percent_str, investor.balance)) else: # This investment pushed the investor's balance over the cap investor.balance = BalanceCap # Edit the bot's response (triggers an API call) logging.info(f" -- profited {profit} but got capped") response.edit_wrap(message.modify_invest_capped(investment.amount, investment.upvotes, upvotes_now, change, profit, percent_str, investor.balance)) investment.success = (profit > 0) investment.profit = profit investment.done = True sess.commit() # Measure how long processing took duration = stopwatch.measure() logging.info(f" -- processed in {duration:5.2f}s") # Report the Reddit API call stats rem = int(reddit.auth.limits['remaining']) res = int(reddit.auth.limits['reset_timestamp'] - time.time()) logging.info(f" -- API calls remaining: {rem:3d}, resetting in {res:3d}s") except prawcore.exceptions.OAuthException as e_creds: traceback.print_exc() logging.error(e_creds) logging.critical("Invalid login credentials. Check your .env!") logging.critical("Fatal error. Cannot continue or fix the problem. Bailing out...") exit() except Exception as e: logging.error(e) traceback.print_exc() time.sleep(10) finally: sess.close()
import formula maxHP = input( "What is the maximum HP of the Pokemon you are trying to capture?") currentHP = input( "What is the current HP of the Pokemon you are trying to capture?") caughtPokemon = input("How many Pokemon species have you captured?") captureRate = input( "What is the intrinsic catch rate (go to Bulbapedia if you don't know what this is) of the Pokemon you are trying to capture?" ) ballBonus = input( "What type of ball are you trying to use to catch the Pokemon? (Use proper spacing!)" ) primaryType = input("What is the first type of your Pokemon?") secondaryType = input("What is the second type, if any, of you Pokemon?") statusAilment = input( "Does the Pokemon have a status ailment? (If no, leave blank)") rotomPow = input("What is the level of Rotom Power you are using, if any?") turnNum = input( "What is the turn number of the battle you are in when trying to catch the Pokemon?" ) isBeast = input("Is your Pokemon a Beast? (Yes or No)") print( formula.calculate(maxHP, currentHP, caughtPokemon, captureRate, ballBonus, primaryType, secondaryType, statusAilment, rotomPow, turnNum, isBeast))
def main(): # == Parse initial and final upvotes from command line parser = argparse.ArgumentParser( description= "Interactive command line tool for performing test calculations for investment return." ) parser.add_argument("u_init", metavar="u_init", type=int, help="Post upvotes at time of investment.") parser.add_argument("u_final", metavar="u_final", type=int, help="Post upvotes at maturation of investment.") parser.add_argument( "invested", metavar="invested", type=int, help="% of MemeCoins Invested in post, base on the net worth.", ) parser.add_argument("net_worth", metavar="net_worth", type=int, help="Account's net worth.") parser.add_argument( "-s", "--save-img", help="Save generated plot to file 'investment_performance.png'", action="store_true", ) args = parser.parse_args() print("Starting Upvotes:", args.u_init) print("Final Upvotes:", args.u_final) print("Invested:", args.invested, "%") invested = args.invested * args.net_worth / 100 print("Amount Invested:", invested, "M¢") print("Net worth:", args.net_worth, "M¢") factor = calculate(args.u_final, args.u_init, args.net_worth) inv_return = factor * invested profit = inv_return - invested print(">> RETURN:", inv_return, "M¢ (Profit:", profit, "M¢)") print("Factor:", factor) print("Base Factor:", calculate(args.u_final, args.u_init, 0)) if args.net_worth: # Generate data for performance plot olds = list(range(args.u_init, args.u_final * 2, args.net_worth) ) # + list(range(args.u_final, args.u_final * 2, 10)) x = [] x2 = [] y = [] y2 = [] for i in olds: x.append(i) result = calculate(i, args.u_init, args.net_worth) * args.invested y.append(result) if i <= args.u_final: x2.append(i) y2.append(result) # Generate performance plot fig = plt.figure(figsize=(7, 7)) plt.grid(color="k", alpha=0.15, which="major") plt.title("Investment Performance", fontsize="18") plt.xlabel("Upvotes", fontsize="14") plt.ylabel("Return / M¢", fontsize="14") plt.plot(x, y, label="Return curve") plt.plot(x2, y2, label="Meme Performance", color="r") plt.plot( args.u_final, inv_return, color="r", marker="X", markersize=8, linestyle="none", label="Return: %i M¢ (Profit: %i M¢)" % (inv_return, profit), ) plt.legend(fontsize="12") # Interactive show plot plt.show() # Optional save plot if args.save_img: out_filename = "investment_performance.png" print("Saving image to: '", out_filename, "'") fig.savefig(out_filename)
def main(): logging.info("Starting calculator") killhandler = KillHandler() engine = create_engine(config.db, pool_recycle=60) sm = sessionmaker(bind=engine) reddit = praw.Reddit(client_id=config.client_id, client_secret=config.client_secret, username=config.username, password=config.password, user_agent=config.user_agent) praw.models.Comment.edit_wrap = edit_wrap stopwatch = Stopwatch() logging.info("Monitoring active investments...") while not killhandler.killed: try: sess = sm() then = int(time.time()) - config.investment_duration investment = sess.query(Investment).\ filter(Investment.done == 0).\ filter(Investment.time < then).\ order_by(Investment.time.asc()).\ first() if not investment: # Nothing matured yet; wait a bit before trying again time.sleep(5) continue duration = stopwatch.measure() investor = sess.query(Investor).filter(Investor.name == investment.name).one() logging.info(f"New mature investment: {investment.comment}") logging.info(f" -- by {investor.name}") if investment.response != "0": response = reddit.comment(id=investment.response) else: response = EmptyResponse() post = reddit.submission(investment.post) upvotes_now = post.ups # <--- triggers a Reddit API call # Updating the investor's balance factor = formula.calculate(upvotes_now, investment.upvotes) amount = investment.amount balance = investor.balance new_balance = int(balance + (amount * factor)) change = new_balance - balance profit = change - amount profit_str = f"{int((profit/amount)*100)}%" # Updating the investor's variables investor.completed += 1 investor.balance = new_balance # Editing the comment as a confirmation text = response.body # <--- triggers a Reddit API call if profit > 0: logging.info(f" -- profited {profit}") response.edit_wrap(message.modify_invest_return(text, upvotes_now, change, profit_str, new_balance)) elif profit == 0: logging.info(f" -- broke even") response.edit_wrap(message.modify_invest_break_even(text, upvotes_now, change, profit_str, new_balance)) else: lost_memes = int( amount - change ) logging.info(f" -- lost {profit}") response.edit_wrap(message.modify_invest_lose(text, upvotes_now, lost_memes, profit_str, new_balance)) investment.success = (profit > 0) investment.profit = profit investment.done = True sess.commit() # Measure how long processing took duration = stopwatch.measure() logging.info(f" -- processed in {duration:5.2f}s") # Report the Reddit API call stats rem = int(reddit.auth.limits['remaining']) res = int(reddit.auth.limits['reset_timestamp'] - time.time()) logging.info(f" -- API calls remaining: {rem:3d}, resetting in {res:3d}s") except Exception as e: logging.error(e) traceback.print_exc() time.sleep(10) finally: sess.close()