def test_sidebar(self): url = reverse("core:sidebar") rsp = self.client.get(url) cb = Company.get_centralbank() should_be = { "companies": [ { "name": self.company.name, "isin": self.company.isin, "id": self.company.id, "share_price": float(self.company.keyfigures.share_price), }, { "name": cb.name, "isin": cb.isin, "id": cb.id, "share_price": float(cb.keyfigures.share_price) }, ], "bond_rate": float(InterestRate.get_latest_rate()), "companies_count": Company.objects.count(), "buy_orders_count": Order.objects.filter(typ=Order.type_buy()).count(), "sell_orders_count": Order.objects.filter(typ=Order.type_sell()).count(), } self.assertDictEqual(should_be, rsp.json())
def check_single_company(self, c: Company): values = [ "price", "amount", "order_by", "order_of", "id", "order_by__user_id", "order_of__name" ] buys = c.orders_of.select_related("order_by").filter( typ=Order.type_buy()).order_by("-price") sells = c.orders_of.select_related("order_by").filter( typ=Order.type_sell()).order_by("price") buys = buys.values(*values) sells = sells.values(*values) buys_count = len(buys) sells_count = len(sells) i, j = 0, 0 while i < buys_count and j < sells_count: buy = buys[i] sell = sells[j] # none of the orders will match for this company if buy["price"] < sell["price"]: break if buy["order_by"] == sell["order_by"]: self.order_ids_delete.append(buy["id"]) i = i + 1 else: i, j = self.match_order(buy, sell, i, j)
def calc_share_price(cls, c: Company) -> Decimal: """ Calculates the share price of a company. Should probably move the calculation to somewhere else """ # Todo: May move the setting of the share price to matching orders and whenever an order gets created highest_buy = c.orders_of.filter( typ=Order.type_buy()).order_by("price").values("price").first() lowest_sell = c.orders_of.filter( typ=Order.type_sell()).order_by("-price").values("price").first() curr = c.keyfigures.share_price if highest_buy is None and lowest_sell is None: return curr if highest_buy is not None: price = highest_buy.get("price") if price > curr: return price if lowest_sell is not None: price = lowest_sell.get("price") if price < curr: return price return curr
def setUp(self): super().setUp() self.user_two = User.objects.create(username="******", email="*****@*****.**") self.company_two = Company.objects.create(user=self.user_two, name="Company 2") self.cb = Company.get_centralbank() self.sell = DynamicOrder.objects.create( order_by=self.cb, order_of=self.company, price=10, dynamic_value=1, limit=5, amount=1000, typ=Order.type_sell(), ) self.buy = DynamicOrder.objects.create( order_by=self.company, order_of=self.company_two, price=10, dynamic_value=1, limit=15, amount=1000, typ=Order.type_buy(), )
def test_orders_matched(self): sell_order = Order.objects.create(order_by_id=4, order_of_id=2, price=2, amount=1_000, typ=Order.type_sell()) buy_order = Order.objects.create(order_by_id=3, order_of_id=2, price=2, amount=1_000, typ=Order.type_buy()) OrderTask().run() self.assertFalse(Order.objects.filter(id=sell_order.id).exists()) self.assertFalse(Order.objects.filter(id=buy_order.id).exists()) self.assertEqual(1, Trade.objects.count()) self.assertTrue( Trade.objects.filter(buyer_id=3, seller_id=4, company_id=2, price=2, amount=1_000).exists()) self.check_market()
def test_multiple_sell_orders_get_matched_by_single_buy(self): sell_order_one = Order.objects.create(order_by_id=4, order_of_id=2, price=2, amount=100, typ=Order.type_sell()) sell_order_two = Order.objects.create(order_by_id=5, order_of_id=2, price=2, amount=100, typ=Order.type_sell()) buy_order = Order.objects.create(order_by_id=6, order_of_id=2, price=2, amount=200, typ=Order.type_buy()) OrderTask().run() for id_ in [sell_order_one.id, sell_order_two.id, buy_order.id]: self.assertFalse(Order.objects.filter(id=id_).exists()) self.check_cash_order_fully_matched(sell_order_one) self.check_cash_order_fully_matched(sell_order_two) self.check_cash_order_fully_matched(buy_order) self.check_market()
def test_bid(self): """Test bid returns the correct value""" bid = self.company.bid() self.assertEqual(None, bid) ask = self.company.ask() self.assertEqual(None, ask) Order.objects.create(order_of=self.company, order_by=self.company_b, price=1, amount=100, typ=Order.type_buy()) Order.objects.create(order_of=self.company, order_by=self.company_b, price=1, amount=100, typ=Order.type_sell()) bid = self.company.bid() self.assertDictEqual( { "price": Decimal("1.00"), "total_amount": Decimal("100") }, bid) ask = self.company.ask() self.assertDictEqual( { "price": Decimal("1.00"), "total_amount": Decimal("100") }, ask)
def test_multiple_buy_orders_get_matched_by_single_sell(self): sell_order = Order.objects.create(order_by_id=4, order_of_id=2, price=2, amount=1_000, typ=Order.type_sell()) buy_order_one = Order.objects.create(order_by_id=3, order_of_id=2, price=2, amount=100, typ=Order.type_buy()) buy_order_two = Order.objects.create(order_by_id=6, order_of_id=2, price=2, amount=100, typ=Order.type_buy()) OrderTask().run() for id_ in [buy_order_one.id, buy_order_two.id]: self.assertFalse(Order.objects.filter(id=id_).exists()) sell_order.refresh_from_db() self.assertEqual(1_000 - 200, sell_order.amount) self.check_cash_order_fully_matched(buy_order_one) self.check_cash_order_fully_matched(buy_order_two) should_be = 1_000_000 + (200 * 2) self.assertEqual(should_be, Company.objects.get(id=sell_order.order_by_id).cash) self.check_market()
def get_order(request): if request.method == 'POST': try: reqdict = to_reqdict(request) table_id = reqdict.get('table_id') menu_ids = reqdict.get('menu_id') quantity = reqdict.get('quantity') taste = reqdict.get('quantity') staff_id = None table = Table.objects.get(id=table_id) item = OrderedMenu(menu_id=menu_ids) item.quantity = quantity item.taste = taste item.save() order = Orders() order.table = table order.name = f"{order.table.name.lower()}_{datetime.datetime.now().isoformat()}" order.save() order.menu.add(item) messages.success(request, f'Order has been placed for {table.name}') except Exception as e: messages.error(request, 'Failed to add Menu') import traceback e = traceback.format_exc() print(e) return redirect(reverse('home'))
def _read_orders(self, path: str): with open(path + "orders.txt", "r") as file: orders = list() next(file) for line in file: data = line.split(",") company_name = data[0].strip() depot_of_name = data[1].strip() amount = int(data[2]) price = int(data[3]) typ = data[4].strip().capitalize() assert any([typ == Order.type_buy(), typ == Order.type_sell()]) order_of = Company.objects.get(name=company_name) order_by = Company.objects.get(name=depot_of_name) orders.append( Order(order_of=order_of, order_by=order_by, amount=amount, price=price, typ=typ)) if self.setup_path == path: Order.objects.bulk_create(orders) return orders
def test_is_frozen_if_paid_internally(self): order = Order(**self.data) order.is_paid = True order.save() payment_method = PaymentMethod(name='Internal Test', is_internal=True) payment_method.save() pref = PaymentPreference(payment_method=payment_method, user=order.user, identifier='InternalTestIdentifier') pref.save() payment = Payment(payment_preference=pref, amount_cash=order.amount_cash, order=order, user=order.user, currency=order.currency) payment.save() order = Order.objects.last() # it's paid self.assertTrue(order.is_paid) # therefore it's frozen self.assertTrue(order.payment_status_frozen) # even though deadline is in the future self.assertTrue(order.payment_deadline >= timezone.now())
def get(self, request, *args, **kwargs): data = dict() # TODO: Cache queries companies = Company.objects.select_related("keyfigures").order_by( "-id")[:5] bond_rate = InterestRate.get_latest_rate() companies_count = Company.objects.count() orders = Order.objects.aggregate( sell_count=Count("id", filter=Q(typ=Order.type_sell())), buy_count=Count("id", filter=Q(typ=Order.type_buy())), ) sell_orders_count = orders.get("sell_count") buy_orders_count = orders.get("buy_count") serializer = CompanySidebarSerializer(companies, many=True) data["companies"] = serializer.data data["bond_rate"] = bond_rate data["companies_count"] = companies_count data["buy_orders_count"] = buy_orders_count data["sell_orders_count"] = sell_orders_count return Response(data=data)
def setUp(self): super(PaymentReleaseTestCase, self).setUp() self.method_data = {"is_internal": 1, 'name': 'Robokassa'} amount_cash = Decimal(30000.00) self.payment_method = PaymentMethod(name='ROBO') self.payment_method.save() self.addr_data = { 'type': 'W', 'name': '17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j', 'address': '17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j', } self.addr = Address(**self.addr_data) self.addr.user = self.user self.addr.save() pref_data = { 'user': self.user, 'comment': 'Just testing', 'payment_method': self.payment_method } pref = PaymentPreference(**pref_data) pref.save('internal') self.data = { 'amount_cash': amount_cash, 'amount_btc': Decimal(1.00), 'currency': self.RUB, 'user': self.user, 'admin_comment': 'test Order', 'unique_reference': '12345', 'payment_preference': pref, 'is_paid': True } self.order = Order(**self.data) self.order.save() self.pay_data = { 'amount_cash': self.order.amount_cash, 'currency': self.RUB, 'user': self.user, 'payment_preference': pref, } self.payment = Payment(**self.pay_data) self.payment.save() tx_id_ = '76aa6bdc27e0bb718806c93db66525436' \ 'fa621766b52bad831942dee8b618678' self.transaction = Transaction(tx_id=tx_id_, order=self.order, address_to=self.addr) self.transaction.save()
def generateOrder(request): total = 0 for item in request.items.all(): partial = _price(item) total += partial.get('price', 0) order = Order(request=request, price=total, status=Order.PENDING) order.save()
def test_type_cannot_be_empty(self): """Test the typ cannot be empty and must be set""" order = Order(order_by=self.company, order_of=self.company_2, price=5, amount=10000) with self.assertRaises(IntegrityError): order.save()
def order(db, store, merchant, item): order = Order(address="This is the test address", merchant=merchant, store=store, order_subtotal=123.23, taxes=452.24, order_total=234.12) order.save() item_list = [item.id] order.items.add(*item_list) return order
def setUp(self): super(UpdateWithdrawAddressTestCase, self).setUp() PaymentMethod.objects.all().delete() method_data = { 'bin': 426101, 'fee': 0.0, 'is_slow': 0, 'name': 'Alpha Bank Visa' } payment_method = PaymentMethod(**method_data) payment_method.save() pref_data = { 'user': self.user, 'identifier': str(payment_method.bin), 'comment': 'Just testing' } pref = PaymentPreference(**pref_data) pref.save() pref.currency.add(self.USD) pref.save() """Creates an order""" data = { 'amount_cash': Decimal(30674.85), 'amount_btc': Decimal(1.00), 'currency': self.USD, 'user': self.user, 'admin_comment': 'test Order', 'unique_reference': '12345', 'payment_preference': pref } order = Order(**data) # TODO: patch and uncomment # order.full_clean() # ensure is initially correct order.save() self.order = order pk = self.order.pk self.url = reverse('core.update_withdraw_address', kwargs={'pk': pk}) self.addr_data = { 'type': 'W', 'name': '17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j', 'address': '17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j', } self.addr = Address(**self.addr_data) self.addr.user = self.user self.addr.save() # The 'other' address for the Transaction user = User.objects.create_user(username='******') addr2 = Address(**self.addr_data) addr2.user = user addr2.save()
def test_auto_set_amount_cash_sell_btc_for_rub(self): amount_btc = 2.5 expected = OrderBaseTestCase.PRICE_BUY_RUB * amount_btc self.order = Order(order_type=Order.SELL, amount_btc=amount_btc, currency=self.RUB, user=self.user) self.order.save() self.assertEqual(self.order.amount_cash, expected)
def test_payment_deadline_calculation(self): created_on = timezone.now() payment_window = 60 order = Order(**self.data) order.payment_window = payment_window expected = created_on + timedelta(minutes=payment_window) order.save() # ignore ms self.assertTrue( abs(expected - order.payment_deadline) < timedelta(seconds=1))
def test_auto_set_amount_cash_buy_btc_with_usd(self): # When the client slees we buy and vice versa # TODO: consider different naming conventions amount_btc = 2.5 expected = OrderBaseTestCase.PRICE_SELL_USD * amount_btc self.order = Order(order_type=Order.BUY, amount_btc=amount_btc, currency=self.USD, user=self.user) self.order.save() self.assertEqual(self.order.amount_cash, expected)
def run(self): cb = Company.get_centralbank() depot = DepotPosition.objects.filter(depot_of=cb) active_orders = Order.objects.filter(typ=Order.type_sell(), order_by=cb).values_list( "order_of_id", flat=True) total_new_orders = 0 logger.info( f"Checking {depot.count()} depot positions of the centralbank") with transaction.atomic(): for position in depot.iterator(): # TODO Add this into the query so we do not have to check this again if position.company_id in active_orders: continue company = position.company # get 10% of the shares in the depot amount = position.amount * 0.1 if position.amount < company.shares * 0.1: amount = position.amount # The centralbank sell orders start always little bit over the last trade. # As it is a dynamic order and not a normal order # the price will dynamically fall every tick. # For more information please see the DynamicOrder model price = company.keyfigures.share_price * Decimal(1.5) dynamic_value = price * Decimal(0.01) # cannot bulk create because of multi inherited table DynamicOrder.objects.create( order_by=cb, order_of=company, amount=amount, price=price, limit=0.5, dynamic_value=dynamic_value, typ=Order.type_sell(), ) total_new_orders += 1 logger.info( f"A total of {total_new_orders} sell orders have been created by the centralbank" )
def test_not_frozen_if_paid(self): order = Order(**self.data) order.is_paid = True order.save() order = Order.objects.last() # it's paid self.assertTrue(order.is_paid) # therefore it's frozen self.assertFalse(order.payment_status_frozen) # even though deadline is in the future self.assertTrue(order.payment_deadline >= timezone.now())
def basket_add(request, product_id): product_ = Product.objects.get(id=product_id) if Order.objects.filter(user=request.user, status__base_status__id=1): order_ = Order.objects.get(user=request.user, status__base_status__id=1) else: status = Status(base_status=BaseStatus.objects.get(id=1), datetime=datetime.now()) status.save() order_ = Order(user=request.user) order_.save() order_.status.add(status) order_.save() ordered_products = order_.products.all() if product_ in [ ordered_product.product for ordered_product in ordered_products ]: for order_prod in ordered_products: if order_prod.product == product_: order_prod.count += 1 order_prod.save() break else: ordered_product = OrderedProduct(product=product_, count=1) ordered_product.save() order_.products.add(ordered_product) order_.save() return HttpResponseRedirect(request.GET.get("path"))
def setUp(self): super().setUp() Order.objects.create(typ=Order.type_sell(), order_by=Company.get_centralbank(), order_of=self.company, price=2, amount=100)
def run(self): orders = DynamicOrder.objects.all() logger.info(f"Updating a total of {orders.count()} dynamic orders") with transaction.atomic(): for order in orders.iterator(): # If the current order is a sell order, then the price # should decrease. If it is a buy order, the price should increase # with the dynamic value. sign = -1 if order.typ == Order.type_sell() else 1 new_price = order.price + (order.dynamic_value * sign) # TODO Delete DynamicOrder and convert to normal order # or filter the orders out during the query.ß if sign == -1 and new_price < order.limit: continue if sign == 1 and new_price > order.limit: continue order.price = new_price self.orders_list.append(order) self.bulk_update() self.bulk_update(force=True)
def generate_orders(request, times): for i in range(0, times): o = Order() o.user = get_random_instance(User) o.bill_address = get_random_instance(Address, choice='B') o.ship_address = get_random_instance(Address, choice='S') o.payment = get_random_instance(Payment, relation='Order') o.save() return HttpResponse(f'{times} Orders generated !')
def test_is_not_frozen_if_is_not_paid_neither_expired(self): payment_window = 60 order = Order(**self.data) order.payment_window = payment_window order.save() order = Order.objects.last() # it's not paid self.assertFalse(order.is_paid) # also it's not expired self.assertFalse(order.expired) # so it's not frozen self.assertFalse(order.payment_status_frozen)
def test_if_sell_and_buy_same_company_buy_gets_deleted(self): sell_order = Order.objects.create(order_by_id=4, order_of_id=2, price=2, amount=1_000, typ=Order.type_sell()) buy_order = Order.objects.create(order_by_id=4, order_of_id=2, price=2, amount=1_000, typ=Order.type_buy()) OrderTask().run() self.assertTrue(Order.objects.filter(id=sell_order.id).exists()) self.assertFalse(Order.objects.filter(id=buy_order.id).exists()) self.check_market()
def test_company_can_place_multiple_orders(self): Order.objects.create(order_by=self.company, order_of=self.company_2, price=5, amount=10000, typ=Order.type_buy()) self.assertEqual( Order.objects.filter(order_by=self.company, order_of=self.company_2).count(), 2)
def setUp(self): super(OrderSetAsPaidTestCase, self).setUp() currency = self.RUB self.data = { 'amount_cash': Decimal(30674.85), 'amount_btc': Decimal(1.00), 'currency': currency, 'user': self.user, 'admin_comment': 'test Order', 'unique_reference': '12345' } self.order = Order(**self.data) self.order.save() self.url = reverse('core.payment_confirmation', kwargs={'pk': self.order.pk})
def form_valid(self, form): """ Logic for valid form. """ context = self.get_context_data(form=form) context.update({ 'seats': form.cleaned_data['seats'], 'name': form.cleaned_data['name'], 'phone': form.cleaned_data['phone'], 'email': form.cleaned_data['email'], 'comment': form.cleaned_data['comment'] }) action = self.request.GET.get('action') if action == 'preview': self.template_name = "core/event_order_preview.html" return self.render_to_response(context) elif action == 'confirm': # Now we can create an order client, created = Client.objects.get_or_create( name=form.cleaned_data['name'], phone=form.cleaned_data['phone'], email=form.cleaned_data['email'], event=context['event'] ) client.save() order = Order( client=client, status=ORDER_STATUS_CHOICES[0][0], comment=form.cleaned_data['comment'], event=context['event'] ) order.save() for seat in form.cleaned_data['seats']: # Check for seat status if seat.status == SEAT_STATUS_CHOICES[0][0]: seat.order = order seat.save() else: order.delete() self.template_name = 'core/event_order.html' return self.render_to_response(context) # Send email to managers that order has been created. # We put it into try clause logger = logging.getLogger('orders') handler = logging.FileHandler('var/orders.log') formatter = logging.Formatter( '%(asctime)s %(levelname)s %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(logging.INFO) try: subject = u'Новый заказ - № %s: %s заказал %s билетов.' % \ (order.id, order.client, len(order.seats.all())) message = render_to_string('core/email/new_order.txt', {'order': order}) recipients = [u.email for u in User.objects.filter(is_staff=True) if u.profile.event == context['event']] send_mail(subject, message, '*****@*****.**', recipients, fail_silently=False) # Log about success logger.info(subject) except Exception, e: # Log error and order ID logger.error('Error during managers send mail: %s : %s' % \ (e, subject)) self.template_name = "core/event_order_success.html" return self.render_to_response(context)