def handle(self, *args, **options): if already_running(): self.stdout.write("Already running") return time_script_started = util.get_utc_time_now() #Perform a sanity check self.check_payments_less_than_amount_in_wallet() self.check_payments_less_than_receives() (unpaid_commissions, total_commission) = self.get_unpaid_commissions() self.check_for_unconfirmed_receives() #Manually say it's OK responses_to_continue = ["y", ""] if raw_input( "Do you want to continue? [Yn] ") not in responses_to_continue: print "Cancelled. No transactions made" return #Make the returns returns_by_address = gather_returns_by_address(self.amounts_to_return) returned_txs = [] for address in returns_by_address: amount = returns_by_address[address]["amount"] returned_amounts = returns_by_address[address]["returns"] returned_tx = make_return_payment(address, amount, returned_amounts) if returned_tx is not None: returned_txs.append(returned_tx) # make commission payment make_commission_payment(unpaid_commissions, total_commission, returned_txs)
def handle(self, *args, **options): wait_period = 2 #seconds between checks of the alarms if already_running(): #self.stdout.write("Already running") return time_now = util.get_utc_time_now() while (time_now.second < 55): check_ssh_log_for_bad_entries() check_bitcoind_is_running() check_hdd_space() check_price_is_not_far_behind() check_cpu_and_ram_state() check_for_missing_prices() check_bitcoin_conf() time.sleep(wait_period) time_now = util.get_utc_time_now()
def handle(self, *args, **options): if already_running(): self.stdout.write("Already running") return time_script_started = util.get_utc_time_now() #Perform a sanity check self.check_payments_less_than_amount_in_wallet() self.check_payments_less_than_receives() (unpaid_commissions, total_commission) = self.get_unpaid_commissions() self.check_for_unconfirmed_receives() #Manually say it's OK responses_to_continue = ["y", ""] if raw_input("Do you want to continue? [Yn] ") not in responses_to_continue: print "Cancelled. No transactions made" return #Make the returns returns_by_address = gather_returns_by_address(self.amounts_to_return) returned_txs = [] for address in returns_by_address: amount = returns_by_address[address]["amount"] returned_amounts = returns_by_address[address]["returns"] returned_tx = make_return_payment(address, amount, returned_amounts) if returned_tx is not None: returned_txs.append(returned_tx) # make commission payment make_commission_payment(unpaid_commissions, total_commission, returned_txs)
def on_open(self, ws): print("%s websocket open" % util.get_utc_time_now().isoformat()) self.ws.send(json.dumps({ "op": "unsubscribe", "channel": TICKER})) self.ws.send(json.dumps({ "op": "unsubscribe", "channel": DEPTH})) self.ws.send(json.dumps({ "op": "subscribe", "channel": TRADE}))
def handle(self, *args, **options): wait_period = 2 #seconds between checks of the deposits if already_running(): #self.stdout.write(datetime.datetime.now().isoformat() + " check_deposits is already running\n") return try: last_received_amount = Received_Amount.objects.order_by('-time')[0] last_tx_id = last_received_amount.tx_id except: #IndexError: last_tx_id = None #self.stdout.write("started\n") time_now = util.get_utc_time_now() while (time_now.second < 55): new_transactions = util.get_bitcoin_transactions(last_tx_id) #self.stdout.write("New txs: %i\n" % len(new_transactions)) for new_tx in new_transactions: try: amount = new_tx["amount"] except TypeError: print "TYPERROR!!!!: %s" % new_tx print new_tx["amount"] if(new_tx["amount"] > 0): tx = { "tx_id": new_tx["txid"], } num_existing_transaction_entries = Received_Amount.objects.filter(**tx).count() predictions = Prediction.objects.filter(receive_address=new_tx["address"]) if(num_existing_transaction_entries == 0 and predictions.count() == 1): tx["prediction"] = predictions[0] tx["amount"] = new_tx["amount"] tx["time"] = util.unix_time_to_datetime_utc(new_tx["time"]) new_payment_obj = Received_Amount(**tx) new_payment_obj.save() elif last_tx_id is not None: pass #TODO raise some better notice, something has gone wrong, should never count the same tx twice. if(len(new_transactions) > 0): last_tx_id = new_transactions[-1]["txid"] #self.stdout.write(last_tx_id + "\n") time.sleep(wait_period) time_now = util.get_utc_time_now()
def get_future_price_data(f): is_open = f.time_window_closes > util.get_utc_time_now() precision = "%0.2f" number_split_by_dp = str(f.target_price).split(".") if len(number_split_by_dp) == 2: precision = "%%0.%if" % max(2,len(number_split_by_dp[1].rstrip('0'))) future_price = { 'expires': f.time_to_match_price.strftime(DATETIME_FORMAT), 'js_expires': int(util.datetime_to_unix_time(f.time_to_match_price) * 1e3), 'is_open': is_open, 'target_price_str': precision % float(f.target_price), 'target_price': float(precision % float(f.target_price)), 'currency_symbol': "$", 'exchange': f.exchange, 'currency_code': f.currency_code, 'deposits': [ { 'received_address': d.prediction.receive_address, 'return_address': d.prediction.return_address, 'received_address_short': d.prediction.receive_address[:10], 'return_address_short': d.prediction.return_address[:10], 'amount': float(d.amount), 'time_received': d.time.strftime("%Y-%m-%d %H:%M:%S"), 'js_time_received': int(util.datetime_to_unix_time(d.time) * 1e3), 'lt': d.prediction.price_will_be_less_than_target, 'returns': [{ 'return_address': r.to_prediction.return_address, 'return_address_short': r.to_prediction.return_address[:10], 'return_amount': float(r.amount), 'is_unpaid': Returned_Tx_To_Returned_Amount_Link.objects.filter(returned_amount=r).count() == 0, } for r in Returned_Amount.objects.filter(from_received_amount=d)] } for d in Received_Amount.objects.filter(prediction__future_price=f).order_by('time', 'id')] } future_price["has_unpaid_returns"] = False for deposit in future_price['deposits']: for returned_amount in deposit['returns']: if returned_amount['is_unpaid']: future_price["has_unpaid_returns"] = True break if future_price["has_unpaid_returns"]: break future_price["total_more_than"] = sum([d["amount"] for d in future_price["deposits"] if not d["lt"]]) future_price["total_less_than"] = sum([d["amount"] for d in future_price["deposits"] if d["lt"]]) actual_price = Bitcoin_Price.objects.filter(time=f.time_to_match_price) if len(actual_price) == 1: future_price["actual_price"] = float(actual_price[0].price) future_price["actual_price_url"] = "https://mtgox.com/api/1/BTCUSD/trades?since=%i" % (actual_price[0].rollover_id_a-1) else: future_price["actual_price"] = None return future_price
def handle(self, *args, **options): if already_running(): #self.stdout.write("Already running") return time_started = util.get_utc_time_now() has_expired = False now = util.get_utc_time_now() one_hour = datetime.timedelta(0, 3600, 0) try: last_bitcoin_price = Bitcoin_Price.objects.order_by('-time')[0] last_tid = last_bitcoin_price.rollover_id_b except IndexError: last_tid = int(util.datetime_to_unix_time(now - one_hour) * 1e6) trades = self.get_gox_trades( last_tid - 1) # needs to include the last rollover trade if len(trades) > 0: try: last_tid = int(trades[0]["tid"]) except: return last_price = trades[0]["price"] while (len(trades) > 0 and not has_expired): prices = find_clear_minute_prices(trades, last_tid, last_price) for price in prices: bitcoin_price = Bitcoin_Price(**price) bitcoin_price.save() last_tid = int(trades[-1]["tid"]) last_price = trades[-1]["price"] time.sleep(1) # Don't hammer the gox server too hard time_taken = util.get_utc_time_now() - time_started has_expired = time_taken.total_seconds() > 30 # Check if there are more trades after the last trade in the # previous set of trades if (len(trades) == 500): trades = self.get_gox_trades(last_tid) else: trades = []
def the_future(request): #Check for rate limiting if too many requests max_allowable_requests = 3600 ip = util.get_client_ip(request) Rate_Limit.objects.create(ip=ip, function='the_future') limit = Rate_Limit.objects.filter(ip=ip, function='the_future').count() if limit > max_allowable_requests: error_text = _("Slow down <span class='notranslate'>Rainman</span> - you've made too many requests in the last hour") return HttpResponse(error_text, mimetype="text/plain", status=429) after = True if "after" in request.GET: time = util.unix_time_to_datetime_utc(float(request.GET["after"]) / 1e3) elif "before" in request.GET: time = util.unix_time_to_datetime_utc(float(request.GET["before"]) / 1e3) after=False else: time = util.get_utc_time_now() predictions_per_page = 10 if after: future_price_times = Future_Price.objects.filter(time_to_match_price__gt=time).distinct('time_to_match_price').order_by('time_to_match_price')[0:predictions_per_page] future_prices = Future_Price.objects.filter(time_to_match_price__in=[x.time_to_match_price for x in future_price_times]).order_by('time_to_match_price', 'target_price') else: future_price_times = Future_Price.objects.filter(time_to_match_price__lt=time).distinct('time_to_match_price').order_by('-time_to_match_price')[0:predictions_per_page] future_prices = Future_Price.objects.filter(time_to_match_price__in=[x.time_to_match_price for x in future_price_times]).order_by('time_to_match_price', 'target_price') response_data = [] for f in future_prices: received_amounts = Received_Amount.objects.filter(prediction__future_price=f) if len(received_amounts) > 0: expires = f.time_to_match_price.isoformat() prediction = { 'id': f.id, 'target_price': float(f.target_price), 'deposits': [{ 'amount': float(r.amount), 'lt': r.prediction.price_will_be_less_than_target, 'time_received': r.time.isoformat(), 'js_time_received': int(util.datetime_to_unix_time(r.time) * 1e3) } for r in received_amounts] } if len(response_data) == 0 or response_data[-1]["expires"] != expires: response_data.append({ 'expires': expires, 'js_expires': int(util.datetime_to_unix_time(f.time_to_match_price) * 1e3), 'predictions': [prediction]}) else: response_data[-1]['predictions'].append(prediction) return HttpResponse(json.dumps(response_data), mimetype="application/json")
def handle(self, *args, **options): if already_running(): #self.stdout.write("Already running") return time_started = util.get_utc_time_now() has_expired = False now = util.get_utc_time_now() one_hour = datetime.timedelta(0, 3600, 0) try: last_bitcoin_price = Bitcoin_Price.objects.order_by('-time')[0] last_tid = last_bitcoin_price.rollover_id_b except IndexError: last_tid = int(util.datetime_to_unix_time(now-one_hour) * 1e6) trades = self.get_gox_trades(last_tid - 1) # needs to include the last rollover trade if len(trades) > 0: try: last_tid = int(trades[0]["tid"]) except: return last_price = trades[0]["price"] while (len(trades) > 0 and not has_expired): prices = find_clear_minute_prices(trades, last_tid, last_price) for price in prices: bitcoin_price = Bitcoin_Price(**price) bitcoin_price.save() last_tid = int(trades[-1]["tid"]) last_price = trades[-1]["price"] time.sleep(1) # Don't hammer the gox server too hard time_taken = util.get_utc_time_now() - time_started has_expired = time_taken.total_seconds() > 30 # Check if there are more trades after the last trade in the # previous set of trades if (len(trades) == 500): trades = self.get_gox_trades(last_tid) else: trades = []
def handle(self, *args, **options): if already_running(): #self.stdout.write("Already running") return fifty_minutes_ago = util.get_utc_time_now() - datetime.timedelta(0,50*60) unconfirmed_received_amounts = Received_Amount.objects.filter(confirmations__lt=6, time__lt=fifty_minutes_ago) for unconfirmed_amount in unconfirmed_received_amounts: tx_info = util.get_bitcoin_transaction_info(unconfirmed_amount.tx_id) if tx_info["confirmations"] >= 6: if tx_info["amount"] != unconfirmed_amount.amount: #TODO log this, it is very interesting, reversed transaction pass unconfirmed_amount.confirmations = tx_info["confirmations"] unconfirmed_amount.amount = tx_info["amount"] unconfirmed_amount.save()
def get_initial_price(self): one_hour = datetime.timedelta(0,3600,0) time_of_interest = util.get_utc_time_now() - one_hour unix_time_of_interest = util.datetime_to_unix_time(time_of_interest) * 1e6 url = "https://mtgox.com/api/1/BTCUSD/trades?since=%i" % unix_time_of_interest f = urllib.urlopen(url) trades_json = f.read() trades = json.loads(trades_json)["return"] last_trade = trades[-1] self.price_float = float(last_trade["price"]) self.price_int = float(last_trade["price_int"]) self.last_time_gox = util.unix_time_to_datetime_utc(last_trade["date"]) print("INITIAL PRICE: %f" % (self.price_float)) """
def trade(self, **k): d = k["date"] if "date" in k else util.datetime_to_unix_time(util.get_utc_time_now()) t = { "date": d, "price": k["price"] if "price" in k else 1, "amount": k["amount"] if "amount" in k else 1, "price_int": k["price_int"] if "price_int" in k else 1e5, "amount_int": k["amount_int"] if "amount_int" in k else 1e8, "tid": k["tid"] if "tid" in k else d*1e6, "price_currency": k["price_currency"] if "price_currency" in k else "USD", "item": k["item"] if "item" in k else "BTC", "trade_type": k["trade_type"] if "trade_type" in k else "bid", "primary": k["primary"] if "primary" in k else "Y", "properties": k["properties"] if "properties" in k else "limit", } self.trades.append(t)
def handle(self, *args, **options): if already_running(): #self.stdout.write("Already running") return fifty_minutes_ago = util.get_utc_time_now() - datetime.timedelta( 0, 50 * 60) unconfirmed_received_amounts = Received_Amount.objects.filter( confirmations__lt=6, time__lt=fifty_minutes_ago) for unconfirmed_amount in unconfirmed_received_amounts: tx_info = util.get_bitcoin_transaction_info( unconfirmed_amount.tx_id) if tx_info["confirmations"] >= 6: if tx_info["amount"] != unconfirmed_amount.amount: #TODO log this, it is very interesting, reversed transaction pass unconfirmed_amount.confirmations = tx_info["confirmations"] unconfirmed_amount.amount = tx_info["amount"] unconfirmed_amount.save()
def trade(self, **k): d = k["date"] if "date" in k else util.datetime_to_unix_time( util.get_utc_time_now()) t = { "date": d, "price": k["price"] if "price" in k else 1, "amount": k["amount"] if "amount" in k else 1, "price_int": k["price_int"] if "price_int" in k else 1e5, "amount_int": k["amount_int"] if "amount_int" in k else 1e8, "tid": k["tid"] if "tid" in k else d * 1e6, "price_currency": k["price_currency"] if "price_currency" in k else "USD", "item": k["item"] if "item" in k else "BTC", "trade_type": k["trade_type"] if "trade_type" in k else "bid", "primary": k["primary"] if "primary" in k else "Y", "properties": k["properties"] if "properties" in k else "limit", } self.trades.append(t)
def the_future(request): #Check for rate limiting if too many requests max_allowable_requests = 3600 ip = util.get_client_ip(request) Rate_Limit.objects.create(ip=ip, function='the_future') limit = Rate_Limit.objects.filter(ip=ip, function='the_future').count() if limit > max_allowable_requests: error_text = _( "Slow down <span class='notranslate'>Rainman</span> - you've made too many requests in the last hour" ) return HttpResponse(error_text, mimetype="text/plain", status=429) after = True if "after" in request.GET: time = util.unix_time_to_datetime_utc( float(request.GET["after"]) / 1e3) elif "before" in request.GET: time = util.unix_time_to_datetime_utc( float(request.GET["before"]) / 1e3) after = False else: time = util.get_utc_time_now() predictions_per_page = 10 if after: future_price_times = Future_Price.objects.filter( time_to_match_price__gt=time).distinct( 'time_to_match_price').order_by( 'time_to_match_price')[0:predictions_per_page] future_prices = Future_Price.objects.filter(time_to_match_price__in=[ x.time_to_match_price for x in future_price_times ]).order_by('time_to_match_price', 'target_price') else: future_price_times = Future_Price.objects.filter( time_to_match_price__lt=time).distinct( 'time_to_match_price').order_by( '-time_to_match_price')[0:predictions_per_page] future_prices = Future_Price.objects.filter(time_to_match_price__in=[ x.time_to_match_price for x in future_price_times ]).order_by('time_to_match_price', 'target_price') response_data = [] for f in future_prices: received_amounts = Received_Amount.objects.filter( prediction__future_price=f) if len(received_amounts) > 0: expires = f.time_to_match_price.isoformat() prediction = { 'id': f.id, 'target_price': float(f.target_price), 'deposits': [{ 'amount': float(r.amount), 'lt': r.prediction.price_will_be_less_than_target, 'time_received': r.time.isoformat(), 'js_time_received': int(util.datetime_to_unix_time(r.time) * 1e3) } for r in received_amounts] } if len(response_data ) == 0 or response_data[-1]["expires"] != expires: response_data.append({ 'expires': expires, 'js_expires': int( util.datetime_to_unix_time(f.time_to_match_price) * 1e3), 'predictions': [prediction] }) else: response_data[-1]['predictions'].append(prediction) return HttpResponse(json.dumps(response_data), mimetype="application/json")
def get_future_price_data(f): is_open = f.time_window_closes > util.get_utc_time_now() precision = "%0.2f" number_split_by_dp = str(f.target_price).split(".") if len(number_split_by_dp) == 2: precision = "%%0.%if" % max(2, len(number_split_by_dp[1].rstrip('0'))) future_price = { 'expires': f.time_to_match_price.strftime(DATETIME_FORMAT), 'js_expires': int(util.datetime_to_unix_time(f.time_to_match_price) * 1e3), 'is_open': is_open, 'target_price_str': precision % float(f.target_price), 'target_price': float(precision % float(f.target_price)), 'currency_symbol': "$", 'exchange': f.exchange, 'currency_code': f.currency_code, 'deposits': [{ 'received_address': d.prediction.receive_address, 'return_address': d.prediction.return_address, 'received_address_short': d.prediction.receive_address[:10], 'return_address_short': d.prediction.return_address[:10], 'amount': float(d.amount), 'time_received': d.time.strftime("%Y-%m-%d %H:%M:%S"), 'js_time_received': int(util.datetime_to_unix_time(d.time) * 1e3), 'lt': d.prediction.price_will_be_less_than_target, 'returns': [{ 'return_address': r.to_prediction.return_address, 'return_address_short': r.to_prediction.return_address[:10], 'return_amount': float(r.amount), 'is_unpaid': Returned_Tx_To_Returned_Amount_Link.objects.filter( returned_amount=r).count() == 0, } for r in Returned_Amount.objects.filter(from_received_amount=d)] } for d in Received_Amount.objects.filter( prediction__future_price=f).order_by('time', 'id')] } future_price["has_unpaid_returns"] = False for deposit in future_price['deposits']: for returned_amount in deposit['returns']: if returned_amount['is_unpaid']: future_price["has_unpaid_returns"] = True break if future_price["has_unpaid_returns"]: break future_price["total_more_than"] = sum( [d["amount"] for d in future_price["deposits"] if not d["lt"]]) future_price["total_less_than"] = sum( [d["amount"] for d in future_price["deposits"] if d["lt"]]) actual_price = Bitcoin_Price.objects.filter(time=f.time_to_match_price) if len(actual_price) == 1: future_price["actual_price"] = float(actual_price[0].price) future_price[ "actual_price_url"] = "https://mtgox.com/api/1/BTCUSD/trades?since=%i" % ( actual_price[0].rollover_id_a - 1) else: future_price["actual_price"] = None return future_price
def handle(self, *args, **options): if already_running(): #self.stdout.write("Already running") return one_hour_ago = util.get_utc_time_now() - datetime.timedelta(0, 3600) Rate_Limit.objects.filter(time__lt=one_hour_ago).delete()
def get_server_time(request): now = util.get_utc_time_now() response_data = { "server_time": util.datetime_to_unix_time(now) * 1e3, } return HttpResponse(json.dumps(response_data), mimetype="application/json")
class Command(BaseCommand): price_float = None price_int = None last_time_gox = None last_time_server = util.get_utc_time_now() ws = websocket.WebSocketApp("ws://websocket.mtgox.com/mtgox") def handle(self, *args, **options): #self.test() #websocket.enableTrace(True) self.get_initial_price() self.ws.on_message = self.on_message self.ws.on_error = self.on_error self.ws.on_close = self.on_close self.ws.on_open = self.on_open #self.get_rollover_price() while(True): try: self.ws.run_forever() except websocket.WebSockeError: print "EXCEPTION" time.sleep(5) def on_open(self, ws): print("%s websocket open" % util.get_utc_time_now().isoformat()) self.ws.send(json.dumps({ "op": "unsubscribe", "channel": TICKER})) self.ws.send(json.dumps({ "op": "unsubscribe", "channel": DEPTH})) self.ws.send(json.dumps({ "op": "subscribe", "channel": TRADE})) def on_message(self, ws, message): new_msg_time_server = util.get_utc_time_now() msg = json.loads(message) trade = msg["trade"] if(trade["price_currency"] == "USD"): self.handle_trade(trade, new_msg_time_server, "socket") def on_error(self, ws, error): print("%s ERROR - %s" % (util.get_utc_time_now(), error)) def on_close(self, ws): print("%s websocket closed" % util.get_utc_time_now().isoformat()) def handle_trade(self, trade, new_msg_time_server, source): new_msg_time_gox = util.unix_time_to_datetime_utc(trade["date"]) if(self.last_time_gox is not None): tickovers = util.get_clear_minutes(self.last_time_gox, new_msg_time_gox) # Set those minutes to the last price for tickover in tickovers: print("%s %f SAVING" % (tickover.isoformat(), self.price_float)) new_bitcoin_price = { 'time': tickover, 'price': self.price_float, } bitcoin_price = BitcoinPrice(**new_bitcoin_price) bitcoin_price.save() if source == "socket": self.price_float = trade["price"] self.price_int = trade["price_int"] self.last_time_server = new_msg_time_server self.last_time_gox = new_msg_time_gox print("%s %f %s" % (new_msg_time_gox.isoformat(), self.price_float, source)) def get_initial_price(self): one_hour = datetime.timedelta(0,3600,0) time_of_interest = util.get_utc_time_now() - one_hour unix_time_of_interest = util.datetime_to_unix_time(time_of_interest) * 1e6 url = "https://mtgox.com/api/1/BTCUSD/trades?since=%i" % unix_time_of_interest f = urllib.urlopen(url) trades_json = f.read() trades = json.loads(trades_json)["return"] last_trade = trades[-1] self.price_float = float(last_trade["price"]) self.price_int = float(last_trade["price_int"]) self.last_time_gox = util.unix_time_to_datetime_utc(last_trade["date"]) print("INITIAL PRICE: %f" % (self.price_float)) """ def get_rollover_price(self): # When a clear minute is encountered, simulate a socket message using # the current price, so that long periods between socket messages do # not mean the database lags far behind. Without this, the database # is only written when websocket messages arrive, which can be many # minutes apart. now_server = util.get_utc_time_now() now_gox = self.get_gox_time_from_server_time(now_server) if now_gox is not None: rollover_trade = { "price": self.price_float, "price_int": self.price_int, "date": util.datetime_to_unix_time(now_gox) } self.handle_trade(rollover_trade, now_server, "rollover") # future event should happen at least one second after rollover to # account for errors due to no milliseconds on the gox time. # Worst case error is when we calculate the gox time 0.999999 second # wrong. now_gox = self.get_gox_time_from_server_time(now_server) future_event = datetime.datetime(now_gox.year, now_gox.month, now_gox.day, now_gox.hour, now_gox.minute, 0, 0, utc) + datetime.timedelta(0, 60, 0) period_to_sleep = future_event - now_gox else: now_server = util.get_utc_time_now() future_event = datetime.datetime(now_server.year, now_server.month, now_server.day, now_server.hour, now_server.minute, 0, 0, utc) + datetime.timedelta(0, 60, 0) period_to_sleep = future_event - now_server t = threading.Timer(period_to_sleep.total_seconds(), self.get_rollover_price) t.daemon = True t.start() """ def get_gox_time_from_server_time(self, dt): if(self.last_time_gox is not None): return dt - self.last_time_server + self.last_time_gox def get_time_from_message(self, msg): return datetime.datetime.fromtimestamp(msg["trade"]["date"], utc)
def on_close(self, ws): print("%s websocket closed" % util.get_utc_time_now().isoformat())
def on_error(self, ws, error): print("%s ERROR - %s" % (util.get_utc_time_now(), error))
def on_message(self, ws, message): new_msg_time_server = util.get_utc_time_now() msg = json.loads(message) trade = msg["trade"] if(trade["price_currency"] == "USD"): self.handle_trade(trade, new_msg_time_server, "socket")