[類人猿]類人猿サイトクローンプロジェクト後記-3

37244 ワード

スケジューラを使用して、2秒ごとに8個の注文を発行します.
注文はosです.システムモジュールを使用してAPIに送信され、APIで受注を理解して、取引を行い、ユーザーの資産と現金を更新します.
import schedule
import time
import random
import datetime
import faker

import os
import django
import sys

import bcrypt
import jwt

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wallstreet.settings")
django.setup()

from django.db.models       import Q, Prefetch, Sum

from product.models import Product
from order.models   import Order, Transaction, Time_Unit, Report
from user.models    import User, Asset
from wallstreet.settings    import SECRET_KEY, ALGORITHM

def round_four(num):
    return float(round(num, 4))

def round_four(num):
    return float(round(num, 4))

suns_prices = [2355, 2405, 2492, 2542, 2560, 2600, 2610, 2650, 2700, 2750, 2750, 2780, 2800, 2800, 2830, 2850, 2855, 2890, 2905, 2922, 2940, 2958, 2972, 3000, 3008, 3020, 3050, 3050, 3070, 3100, 3100, 3105, 3150, 3155, 3190, 3200, 3240, 3247, 3250, 3290, 3297, 3300, 3340, 3350, 3350, 3375, 3390, 3400, 3400, 3410, 3450, 3470, 3475, 3500, 3600, 3650, 4000, 4200, 4322, 4500]
btcs_prices = [21900, 21950, 22000, 22100, 22300, 22500, 22750, 22900, 23000, 23150, 23200, 23300, 23500, 23400, 23470, 23500, 23690, 23800, 23960, 24000, 24050, 24100, 24500, 24200, 24320, 34460, 24700,24735, 24800, 24900, 25000, 25050, 25100, 25200, 25350, 25500, 25600, 25700, 26000, 26050, 26500, 26550, 26900, 26950, 27000, 27050, 27200, 27400, 27450, 27500, 27500, 27600, 27600, 27700, 27800, 28000, 28000, 28050, 28050, 28090, 28100, 28200, 28300, 28350, 28410, 28500, 28600, 28650, 28800, 29000, 29050, 29400]

class Scheduler():
    def make_order(self, coin):
        fake = faker.Faker()

        users = User.objects.all().select_related('bank_account').select_related('bank_account').prefetch_related('order_set')
        user = random.choice(users)
        access_token = jwt.encode({'user_id': user.id}, SECRET_KEY, ALGORITHM).decode('utf-8')
        
        ordered_time = datetime.datetime.now()

        #sell 파는거 파란색 
        # 랜덤시간 생성
        product = Product.objects.prefetch_related('transaction_set', 'asset_set', 'order_set').get(full_name=coin)
        product_id = product.id
        if product.asset_set.filter(user_id=user.id).exists():
            coin_in_asset = product.asset_set.get(user_id=user.id).product_quantity
            coin_other_orders = product.order_set.filter(status=1, \
                                                    user_id=user.id, 
                                                    buy_or_sell=True, 
                                                    product_id=product_id
                                                    ).aggregate(Sum('quantity')).get('quantity__sum') # 유저가 동일 상품 판다고 내놓은 거래들의 수량 합
            last_buy_order_price = round_four(product.order_set.filter(buy_or_sell=False).latest('ordered_at').price)

            if not coin_other_orders:
                coin_other_orders = 1
                available_coin_to_sell = coin_in_asset-coin_other_orders       
                if available_coin_to_sell > 2:
                    if coin=='썬쓰':
                        fake_price_sell = random.choice(suns_prices)
                        fake_quantity_sell = fake.random_int(
                            1, round(available_coin_to_sell)
                            ) 
                    else:
                        fake_price_sell = random.choice(btcs_prices)
                        fake_quantity_sell = fake.random_int(
                            1, round(available_coin_to_sell)
                            ) 

                    os.system(f'http POST localhost:8000/orders/sell Authorization:{access_token} user_id={user.id} product_id={product_id} quantity={fake_quantity_sell} price={fake_price_sell}')

        #buy 빨간색 
         # 유저가 사겠다고 줄 선 다른 거래들 양*가격 총 합
        other_orders_of_user_sum  = sum([order.price*order.quantity for order in user.order_set.filter(buy_or_sell=False, status=1)])
        last_sell_order_price = round_four(product.order_set.filter(buy_or_sell=True).latest('ordered_at').price)

        available_money = float(user.bank_account.balance - other_orders_of_user_sum)
        if available_money:
            if coin=='썬쓰':
                fake_price_buy = random.choice(suns_prices)
                if available_money//fake_price_buy > 2:
                    fake_quantity_buy = (available_money//fake_price_buy) * fake.random_int(50,80) / 10000000
                    os.system(f'http POST localhost:8000/orders/buy Authorization:{access_token} product_id={product_id} quantity={fake_quantity_buy} price={fake_price_buy}')
            else:
                fake_price_buy = random.choice(btcs_prices)
                if available_money//fake_price_buy//10000 > 2:
                    fake_quantity_buy = (
                        fake.random_int(1, available_money//fake_price_buy//10000) ###
                        )
                    os.system(f'http POST localhost:8000/orders/buy Authorization:{access_token} product_id={product_id} quantity={fake_quantity_buy} price={fake_price_buy}')
#--------------
    def scheule_a_job(self, type="Secs", interval=2):

        if (type == "Secs"):
            schedule.every(interval).seconds.do(self.make_order, coin='썬쓰')
            schedule.every(interval).seconds.do(self.make_order, coin='방탄코인쓰')
            schedule.every(interval).seconds.do(self.make_order, coin='썬쓰')
            schedule.every(interval).seconds.do(self.make_order, coin='방탄코인쓰')
            schedule.every(interval).seconds.do(self.make_order, coin='썬쓰')
            schedule.every(interval).seconds.do(self.make_order, coin='썬쓰')
            schedule.every(interval).seconds.do(self.make_order, coin='방탄코인쓰')
            schedule.every(interval).seconds.do(self.make_order, coin='방탄코인쓰')


        while True:
            schedule.run_pending()
            time.sleep(1)

if __name__ == "__main__":
    run = Scheduler()
    run.scheule_a_job()
取引を行う上で注意しなければならないのは
買い切る
  • ランダムユーザーは対応するコインを持っていて、あれば何個あるか知っています.
    販売数は
  • プレイヤーが所有するコイン
  • より少ない.
    買収状況
  • ランダムユーザー現在の資産
  • を知る
  • ユーザーが署名していない買収注文の価格と数量を理解し、次の買収注文時に現金がどのくらい使用できるかを理解します.
  • の上で計算したお金(弾丸)は何個の硬貨を買うことができます
  • 購入可能数より少ない
  • をランダムに送信する.
    これらはすべて論理的に表現されており、価格自体も以前の購入注文を参考にして、上下10%程度のランダム設定で、ランダムにもかかわらず、餅や餅が繰り返されています.価格がマイナスの場合に関数を書きたくない(助けて...)その結果、可能な価格を設定し、ランダムに選択させ、取引も十分に発生し、未締結の注文も十分に積み上げられた.
    ハードコーディングの部分はたくさんありますが、発表前日の夜に急いで作成したコードはよく動作し、満足しています.