def shop_orders_inputs_update(): if not request.args: return 'shop_orders_inputs_update/amo/XCURR/ECURR' ## входящая - это валюта платежа curr = db(db.currs.abbrev == request.args(1)).select().first() if not curr: return 'curr ' + request.args(1) + ' not exist' rates = rates_lib.get_best_rates( db, curr) # загодя возьмем курсы обмена для этой крипты for (k, v) in rates.iteritems(): v.append(db.currs[k].abbrev) res = {'rates': rates} ## выходящая это валюта счета #### curr_out = db.currs[shop_order.curr_id] curr_out = db(db.currs.abbrev == request.args(2)).select().first() if not curr_out: return 'curr ' + request.args(2) + ' not exist' shop_order_addr = created_on = None amount = request.args(0) amo_out, rate_order, rate_ = rates_lib.get_amo_out(db, rates, shop_order_addr, curr_out, amount, created_on) res['amo_out'] = amo_out res['rate_order'] = rate_order res['rate_'] = rate_ return res
def get_best_rates(): if not request.args(0): return 'get_best_rates/RUB' curr_in = db(db.currs.abbrev == request.args(0)).select().first() rates = rates_lib.get_best_rates(db, curr_in, curr_out=None) #print rates h = CAT() for i, r in rates.iteritems(): #print i,r h += DIV(db.currs[i].abbrev, ' base: ', r[0], ' tax: ', r[1], ' rate:', r[2], ' - 1/rate:', 1 / r[2] if r[2] else 0) return dict(h=h)
def get_rate_powers(): if len(request.args) == 0: mess = 'len(request.args)==0' print mess return mess import rates_lib curr_in = db(db.currs.abbrev == request.args[0]).select().first() best_rates = rates_lib.get_best_rates(db, curr_in) res = '' for v in best_rates: res = res + '[%s]->[%s]=' % ( curr_in.abbrev, db.currs[v].abbrev) + '%s' % best_rates[v] + '<br>' return res
def bill_rates(): time.sleep(1) if len(request.args) == 0: mess = 'ERROR: - use api/rates/BTC' return mess curr_in = db(db.currs.abbrev == request.args(0).upper()).select().first() if not curr_in: return 'curr not found' from rates_lib import get_best_rates best_rates = get_best_rates(db, curr_in, True) res = {} for v in best_rates: if v == curr_in.id: continue res[db.currs[v].abbrev] = best_rates[v] return res
def bills_draw_insert(db, shop_order, curr, amo, desc): # сначала подсчет общего веса tab = shop_order.addrs vol = 0 for (k, v) in tab.iteritems(): v = float(v) vol += v tab[k] = v # теперь вычислим курсы обмена для данной крипты входа rates = rates_lib.get_best_rates( db, curr) # загодя возьмем курсы обмена для этой крипты amo = float(amo) # посмотрим что оставить магазину в резерв amo_keep = 0 keep = shop_order.keep if keep and keep > 0: if keep > 1: keep = 1 amo_keep = amo * float(keep) # новое АМО берем amo = amo - amo_keep for (addr, v) in tab.iteritems(): amo_out = rnd_8(v / vol * amo) # найдем курс обмена curr2, x, e = db_common.get_currs_by_addr(db, addr) if curr2.id != curr.id: rate = rates_lib.get_best_rate(rates, curr2, amo_out) amo_out = rate * amo_out _id = db.bills_draws.insert( shop_order_id=shop_order.id, curr_id=curr2.id, addr=addr, amo=amo_out, ) db.commit() # гаче там потом берется неизмененый баланс return Decimal(amo_keep)
def get_xcurrs_for_deal(db, amo_out, curr_out, deal, dealer=None, s_b_in=None, not_used=None): curr_out_id = curr_out.id dealer_id = dealer and dealer.id or None # берем в расчет только недавние цены expired = datetime.now() - timedelta(0, 360) pairs = [] is_order = False dealer_deal = None deal = db.deals[current.TO_COIN_ID] s_b = s_b_in == None and True or s_b_in ############################ d_e = None # теперь по всем криптам пройдемся и если нет в парах то # значит запрет в форме сделаем for rec_in in db((db.currs.used == True) & (db.xcurrs.curr_id == db.currs.id)).select( orderby='currs.name'): curr_in = rec_in.currs if not_used and curr_in.abbrev in not_used: continue disabled = None if curr_in.id == curr_out.id: continue if not amo_out: rates = rates_lib.get_best_rates(db, curr_in, curr_out) if rates: amo_in = rates[curr_out.id][0] else: amo_in = 0 else: # количество уже жестко задано от магазина pr_b, pr_s, pr_avg = rates_lib.get_average_rate_bsa( db, curr_in.id, curr_out.id, expired) #print pr_b, pr_s, pr_avg if pr_b: amo_in = amo_out / pr_b rate = None if False: # OLD style - without taxes if not amo_out or pr_b: #print 'amo_in:', amo_in amo_out, rate_order, rate = rates_lib.get_rate( db, curr_in, curr_out, amo_in) else: # new STYLE - full price # amo_in = 1 _, _, best_rate = rates_lib.get_rate(db, curr_in, curr_out, amo_in) if best_rate: amo_out, mess_out = calc_fees(db, deal, dealer_deal, curr_in, curr_out, amo_in, best_rate, is_order=0, note=0, only_tax=1) ## vol_out - is Decimal amo_out = common.rnd_8(amo_out) if amo_in: rate = amo_out / amo_in if not rate: rate = -1 disabled = True currs_stats = db((db.currs_stats.curr_id == curr_in.id) & (db.currs_stats.deal_id == deal.id)).select().first() pairs.append({ 'id': curr_in.id, 'price': rate, 'name': curr_in.name, 'abbrev': curr_in.abbrev, 'icon': curr_in.icon, 'expired': disabled, 'name_out': curr_out.abbrev, 'used': currs_stats and currs_stats.count_ or 0, 'curr_id': curr_in.id, # для того чтобы по 2му разу не брало 'bal': curr_in.balance, 'bal_out': curr_free_bal(curr_in) # сколько можно продать }) return pairs
def inputs_update(db, curr_block, curr, xcurr, conn): pay_ins_st = db(db.pay_ins_stack.xcurr_id == xcurr.id).select() if len(pay_ins_st) == 0: return 'pay_ins enpty' # все приходы в стеке - пока они там значит они не ДОНЕ и не начислены еще магазину conf_true = xcurr.conf_true == None and 6 or xcurr.conf_true conf_hard = xcurr.conf_hard == None and 3 or xcurr.conf_hard conf_soft = xcurr.conf_soft == None and 1 or xcurr.conf_soft #print 'inputs_update [%s]%s' % (curr.id, curr.abbrev), conf_soft, conf_hard, conf_true rates = rates_lib.get_best_rates( db, curr) # загодя возьмем курсы обмена для этой крипты #print rates #print conf_soft, xcurr # у каждого адреса - может быть много проводок - поэтому потом по адресам смотрим for r in pay_ins_st: #print r pay_in = db.pay_ins[r.ref_id] pay_old_status = pay_in.status pay_old_status = len( pay_old_status or '' ) > 0 and pay_old_status or '-' # пустые и с длинною 0 - как пустые conf = curr_block - pay_in.in_block + 1 #print 'OLD STATUS:', pay_old_status, 'PAY_IN:', pay_in.amount, pay_in.amo_out, '\nconf:', conf shop_order_addr = db.shop_order_addrs[pay_in.shop_order_addr_id] shop_order = db.shop_orders[shop_order_addr.shop_order_id] # проверим - есть ли связь с кошельком сначала а потом проверим транзакцию bbb = conn.getblockcount() if not crypto_client.trans_exist(conn, pay_in.txid): # а есть ли ввобще такая проводка? мож она была в двойной цепочке блоков и исчезла new_status = 'INVALID' pay_in.amo_out = -1 ## зададим курс иначе в update_payed статус не поменяется del db.pay_ins_stack[r.id] update_payed(db, curr, xcurr, pay_in, pay_old_status, new_status, conf, shop_order, shop_order_addr) continue # определим сразу тут курс!! amo_out = pay_in.amo_out #print 'AMO_OUT: ',amo_out if not amo_out or amo_out == 0: # если курс еще не вычислен - попробуем его задать curr_out = db.currs[shop_order.curr_id] #print 'curr -> curr_out', curr.abbrev, curr_out.abbrev if curr.id == curr_out.id: # это без обмена amo_out = pay_in.amount pay_in.update_record(amo_out=amo_out) elif conf > 0 and shop_order.status not in UNUSED_STATUSES: # если подтверждения уже есть и счет еще не протух то ищем обменный курс #print 'orders_lib: try rates_lib.get_amo_out' # изменим величину входа - # уменьшим погрешности на колебания курса - тут минусуем # берем именно крипту входа и ее txfee # тут уже с добавкой пришла крипта поэтому: # -если заказ на курс жив то все без изменений - там лимит уже забит # -если заказ на курс просрочен то тут получится завышенное кол-во на входе # поэтому нужно уменьшитть amo_out, rate_order, rate_ = rates_lib.get_amo_out( db, rates, shop_order_addr, curr_out, pay_in.amount, pay_in.created_on) # если нет курса... то будет 0 if not amo_out: # если нет курса то не надо его обрабатывать на таксу и тд pass else: if rate_order: # если по заказу на курс то ничего не делаем - там уже все учтено pass else: # если по текущему курсу то вычтем лиимит на колебания курса ##amo_out = rate_ * rates_lib.add_limit( pay_in.amount, xcurr.txfee, -0.8, -0.8) ## НЕТ без уменьшения курса - просто сдачу потом вернем amo_out = rate_ * float(pay_in.amount) #print 'not rate_order -> amo_in limited -0.8, -0.8' #print 'amo_out, rate_, rate_order', amo_out, rate_, rate_order amo_out = Decimal(amo_out) price = shop_order.price if price: # если задана цена то погрешность курса нивелируем - так как было заплочено больше на limit+1+1 # теперь надо глянуть погрешность между ценою, остатком для доплаты и данным входом # если разница небольшая то принять погрешность all_payed = shop_order.payed_true + shop_order.payed_hard + shop_order.payed_soft print 'amo_out:', amo_out, 'all_payed:', all_payed all_payed_full = all_payed + amo_out ## тут и так уже погрешность добавлена (выше) к величине входов print 'all_payed_full:', all_payed_full diff_ = all_payed_full - price accur_ = abs(float(diff_ / price)) print 'accur_:', accur_ if accur_ < 0.01: # погрешность очень маленькая - простим ее amo_out = price - all_payed print 'accurated amo_out:', amo_out # если курс нашелся то обновим amo_out pay_in.update_record( rate_order_id=rate_order and rate_order.id or None, amo_out=amo_out) print 'update amo_out:', amo_out, 'rate_order:', rate_order if conf >= conf_true: new_status = 'TRUE' #if conf >= conf_true + 2: if conf >= conf_true + 3 * conf_true * (1 + pay_in.tryed): pay_in.update_record(tryed=pay_in.tryed + 1) log( db, 'inputs_update', 'conf >= conf_true *10 **TRY: %s** - [%s]%s %s' % (pay_in.tryed, curr.abbrev, pay_in.amount, pay_in.txid)) if not amo_out: ### ### ВНИМАНИЕ !!!! кол-во подтверждений может быть и намного больше - если ### если сервис подвис или курс неизвестен - поэтому нельзя возвращать сразу обратно ### if not shop_order.price: # Эта запись подвисла - видимо курса нет - надо ее вернуть # такой вход подлежит возврату ## !!!!!!!!!!!!!!!! это платеж от пула - ннельзя возвращать! ##del db.pay_ins_stack[r.id] ##return_pay_ins_one(db, xcurr, pay_in, pay_in.amount, 'RETURNED') # вернем все if pay_in.tryed < 8: continue else: # на возврат платежа log( db, 'inputs_update', 'DEL from pay_in_STACK pay_ins.id: %s and RETURN' % r.id) del db.pay_ins_stack[r.id] return_pay_ins_one(db, xcurr, pay_in, pay_in.amount, 'RETURNED') # вернем все if not amo_out: # запомним что нет курса и поэтому удаляем log( db, 'inputs_update', 'becouse not RATE for %s -> %s' % (curr.abbrev, curr_out.abbrev)) continue elif shop_order.status in UNUSED_STATUSES: # на возврат платежа log( db, 'inputs_update', 'DEL from pay_in_STACK pay_ins.id: %s and RETURN' % r.id) del db.pay_ins_stack[r.id] return_pay_ins_one(db, xcurr, pay_in, pay_in.amount, 'RETURNED') # вернем все continue else: continue del db.pay_ins_stack[r.id] update_payed(db, curr, xcurr, pay_in, pay_old_status, new_status, conf, shop_order, shop_order_addr) continue elif conf >= conf_hard: # заходим сюда чтобы нииже не шла и непеределывала на СОФТ все if pay_old_status != 'HARD': new_status = 'HARD' update_payed(db, curr, xcurr, pay_in, pay_old_status, new_status, conf, shop_order, shop_order_addr) elif conf >= conf_soft: if pay_old_status != 'SOFT': new_status = 'SOFT' update_payed(db, curr, xcurr, pay_in, pay_old_status, new_status, conf, shop_order, shop_order_addr)