예제 #1
0
 def save(self, *args, **kwargs):
     # 上場済みであれば、各種情報をスクレイピング
     data = mylib_scraping.yf_detail(self.code)
     if data['status']:
         self.name = data['data']['name']
         self.market = data['data']['market']
         self.industry = data['data']['industry']
         self.is_trust = False if len(str(self.code)) == 4 else True
         if data['data']['industry'] == "REIT":
             dividend = data['data']['financial_data']['予想分配金']
             self.dividend = None if dividend in (None, "---") else int(
                 float(dividend))
             dividend_yield = data['data']['financial_data']['分配金利回り']
             self.dividend_yield = None if dividend_yield in (
                 None, "---") else dividend_yield
         elif not data['data']['industry'] == "ETF" and not self.is_trust:
             dividend = data['data']['financial_data']['1株配当']
             self.dividend = None if dividend in (None, "---") else int(
                 float(dividend))
             dividend_yield = data['data']['financial_data']['配当利回り']
             self.dividend_yield = None if dividend_yield in (
                 None, "---") else dividend_yield
     profile = mylib_scraping.yf_profile(self.code)
     if profile['status']:
         self.feature = profile['data']["特色"]
         self.consolidated_business = profile['data']["連結事業"]
         self.settlement_date = profile['data']["決算"]
         self.unit = profile['data']["単元株数"]
     return super().save(*args, **kwargs)
예제 #2
0
 def handle(self, *args, **options):
     try:
         today = date.today()
         ipos = Ipo.objects.filter(date_list=today)
         if ipos.count() == 0:
             # 上場したデータなし
             self.stdout.write("Listed IPO was not found")
         for ipo in ipos:
             # is_listed
             ipo.stock.is_listed = True
             ipo.stock.save()
             msg = "{} have been listed and the data was updated".format(
                 ipo.stock)
             self.stdout.write(self.style.SUCCESS(msg))
             # status
             if ipo.status == "3.当選(上場前)":
                 ipo.status = "4.当選(上場後)"
             else:
                 ipo.status = "4.落選(上場後)"
             # 初値
             d = mylib_scraping.yf_detail(ipo.stock.code)
             if d['status']:
                 ipo.val_initial = d['data']['val_open']
                 msg = "val_initial of {} was updated".format(ipo.stock)
                 msg_write = self.style.SUCCESS(msg)
             else:
                 msg_write = "Cannot set val_initial to {} because of the fail to scrape data".format(
                     ipo.stock)
             ipo.save()
             self.stdout.write(msg_write)
     except Exception as e:
         self.stderr.write(self.style.ERROR(e))
예제 #3
0
 def get(self, request, *args, **kwargs):
     try:
         result = {
             "msg": "",
             "status": True,
             "data": {},
             "is_registered": True,
         }
         code = request.GET['code']
         d = mylib_scraping.yf_detail(code)
         if d['status']:
             result[
                 'msg'] = 'Scraping for code: {} was completed successfully'.format(
                     code)
             result['data'] = d['data']
             result['is_registered'] = Stock.objects.filter(
                 code=code).exists()
         else:
             raise Exception(
                 'Scraping for code: {} was failed'.format(code))
     except Exception as e:
         logger.error(e)
         result["msg"] = e.args
         result["status"] = False
     finally:
         return JsonResponse(result, safe=False)
예제 #4
0
 def profit(self):
     """利益"""
     profit = 0
     for o in self.order_set.all():
         if o.is_buy:
             profit -= (o.num * o.val + o.commission)
         else:
             profit += (o.num * o.val - o.commission)
     if not self.is_closed:
         data = mylib_scraping.yf_detail(self.stock.code)
         if data['status']:
             profit += data['data']['val'] * self.remaining()
     return profit
예제 #5
0
 def post(self, request, *args, **kwargs):
     json_data = json.loads(request.body.decode())
     try:
         if Stock.objects.filter(code=json_data['code']).count() == 1:
             stock = Stock.objects.get(code=json_data['code'])
         else:
             stockinfo = mylib_scraping.yf_detail(json_data["code"])
             if stockinfo['status']:
                 stock = Stock()
                 stock.code = json_data["code"]
                 stock.name = stockinfo['data']['name']
                 stock.industry = stockinfo['data']['industry']
                 stock.market = stockinfo['data']['market']
                 stock.is_trust = False if len(str(
                     stock.code)) == 4 else True
                 stock.save()
             else:
                 res = {
                     "status": False,
                     "message": "Failed to create Stock"
                 }
                 return JsonResponse(res, safe=False)
         # slack
         sbialerts = SBIAlert.objects.filter(stock=stock,
                                             is_active=True,
                                             val=json_data['val'],
                                             type=json_data['type'])
         for sbialert in sbialerts:
             text = "【({}) {}】{}{}".format(stock.code, stock.name,
                                           sbialert.val,
                                           sbialert.get_type_display())
             mylib_slack.post_message(text)
         sbialerts.update(checked_at=datetime.now(
             timezone(timedelta(hours=9))),
                          is_active=False,
                          message=json_data['message'])
         mylib_slack.post_open_entries()
         # res
         res = {"status": True, "message": json_data['message']}
     except Exception as e:
         logger.error(e)
         res = {"status": False, "message": str(e)}
     finally:
         return JsonResponse(res, safe=False)
예제 #6
0
def register_stock(code):
    result = {"code": code, "stock": None, "status": False}
    if Stock.objects.filter(code=code).exists():
        raise Exception('Already existing')
    try:
        yf_detail = mylib_scraping.yf_detail(code)
        if yf_detail['status']:
            data = yf_detail['data']
            data.pop('financial_data')
            stock = Stock.objects.create(**data)
            result['stock'] = stock
            result['status'] = True
            logger.info("New stock object of {}".format(stock))
    except Exception as e:
        print(e)
        logger.error(e)
        result['status'] = False
    finally:
        return result
예제 #7
0
def register_stock_financial_data(code):
    result = {
        'code': code,
        'StockFinancialData': [],
        'status': False,
    }
    try:
        # 情報取得
        detail = mylib_scraping.yf_detail(code)
        profiles = mylib_scraping.yf_settlement(code, is_consolidated=True)
        if profiles['status'] and profiles['data'][0]['決算期'] is None:
            # 単体の情報を取得
            profiles = mylib_scraping.yf_settlement(code,
                                                    is_consolidated=False)
        # stock情報
        stock = Stock.objects.get(code=code)
        # 今年度を含めて3年分
        for i in range(3):
            profile = profiles['data'][i]
            if not StockFinancialData.objects.filter(
                    date=profile["決算発表日"], stock__code=code).exists():
                data = {
                    "stock": stock,
                    # profile
                    "date": profile["決算発表日"],
                    'equity': profile['自己資本'],
                    'equity_ratio': profile["自己資本比率"],
                    'capital': profile["資本金"],
                    'operating_income': profile["営業利益"],
                    'assets': profile["総資産"],
                    'recurring_profit': profile["経常利益"],
                    'net_income': profile["当期利益"],
                    'interest_bearing_debt': profile["有利子負債"],
                    'eps': profile["EPS(一株当たり利益)"],
                    'bps': profile["BPS(一株当たり純資産)"],
                    'sales': profile["売上高"],
                    'roa': profile["ROA(総資産利益率)"],
                    'roa_2': profile["総資産経常利益率"],
                    'roe': profile["ROE(自己資本利益率)"],
                }
                # 今年度分はdetail情報を利用
                if i == 0 and detail['status']:
                    data['market_value'] = detail['data']['financial_data'][
                        "時価総額"]
                    data['dividend_yield'] = detail['data']['financial_data'][
                        "配当利回り(会社予想)"]
                    data['bps_f'] = detail['data']['financial_data']["BPS(実績)"]
                    data['eps_f'] = detail['data']['financial_data'][
                        "EPS(会社予想)"]
                    data['pbr_f'] = detail['data']['financial_data']["PBR(実績)"]
                    data['per_f'] = detail['data']['financial_data'][
                        "PER(会社予想)"]
                # 保存
                logger.debug(data)
                sfd = StockFinancialData.objects.create(**data)
                result['StockFinancialData'].append(sfd)
        # status=Trueに設定
        result['status'] = True
    except Exception as e:
        logger.error(
            "register_stock_financial_date for {} was failed".formtat(code))
        logger.error(e)
        pprint(profiles)
        # status=Falseに設定
        result['status'] = False
    finally:
        return result
예제 #8
0
def register_stock_value_data_alt(code):
    '''
    record_stock_value_data_alt
    :desc: yahooファイナンスからHLOCTを取得し、StockValueDataに格納
    :param code: 銘柄コード
    :return: StockValueDataの追加数等
    '''
    # for result
    counter = 0
    list_added = list()
    list_updated = list()
    # main process
    data = mylib_scraping.yf_detail(code)
    stock = Stock.objects.get(code=code)
    if data['status']:
        today = date.today()
        if StockValueData.objects.filter(stock=stock,
                                         date=today).__len__() == 0:
            counter += 1
            if stock.is_trust:
                s = StockValueData.objects.create(
                    stock=stock,
                    date=today,
                    val_open=data['data']['val'] * 10000,
                    val_high=data['data']['val'] * 10000,
                    val_low=data['data']['val'] * 10000,
                    val_close=data['data']['val'] * 10000,
                    turnover=data['data']['balance'],
                )
            else:
                s = StockValueData.objects.create(
                    stock=stock,
                    date=today,
                    val_open=data['data']['val_open'],
                    val_high=data['data']['val_high'],
                    val_low=data['data']['val_low'],
                    val_close=data['data']['val_close'],
                    turnover=data['data']['turnover'],
                )
            list_added.append(s.date.__str__())
            logger.info('StockValueData of {} is created'.format(stock))
        elif StockValueData.objects.filter(stock=stock,
                                           date=today).__len__() == 1:
            counter += 1
            s = StockValueData.objects.filter(stock=stock, date=today)
            if stock.is_trust:
                s.update(val_open=data['data']['val'] * 10000,
                         val_high=data['data']['val'] * 10000,
                         val_low=data['data']['val'] * 10000,
                         val_close=data['data']['val'] * 10000,
                         turnover=data['data']['balance'])
            else:
                s.update(
                    val_open=data['data']['val_open'],
                    val_high=data['data']['val_high'],
                    val_low=data['data']['val_low'],
                    val_close=data['data']['val_close'],
                    turnover=data['data']['turnover'],
                )
            list_updated.append(s.first().date.__str__())
            logger.info('StockValueData of {} is updated'.format(stock))
    result = {
        "counter": counter,
        "stock": {
            "name": stock.name,
            "code": stock.code,
        },
        "list_added": list_added,
        "list_updated": list_updated,
    }
    return result
예제 #9
0
 def current_val(self):
     data = mylib_scraping.yf_detail(self.code)
     return data['data']['val'] if data['status'] else self.latest_val()
예제 #10
0
def create_order(request):
    if request.method == "POST":
        try:
            with transaction.atomic():
                json_data = json.loads(request.body.decode())
                logger.info("request_json: {}".format(json_data))
                pk_orders = list()
                for val in json_data.values():
                    logger.info(val)
                    val['user'] = User.objects.first()
                    val['commission'] = mylib_asset.get_commission(val['num'] *
                                                                   val['val'])
                    logger.info("User: {}".format(val['user']))
                    # Stocksにデータがない→登録
                    if not Stock.objects.filter(code=val["code"]).exists():
                        stockinfo = mylib_scraping.yf_detail(val["code"])
                        if stockinfo['status']:
                            stock = Stock()
                            stock.code = val["code"]
                            stock.name = stockinfo['data']['name']
                            stock.industry = stockinfo['data']['industry']
                            stock.market = stockinfo['data']['market']
                            stock.is_trust = False if len(str(
                                stock.code)) == 4 else True
                            stock.save()
                            val['stock'] = stock
                            smsg = "New stock was registered:{}".format(
                                stock.code)
                            logger.info(smsg)
                        else:
                            raise Exception("Failed to create stock {}".format(
                                val['code']))
                    else:
                        val['stock'] = Stock.objects.get(code=val['code'])
                        smsg = "Stock {} is found".format(val['code'])
                        logger.info(smsg)
                    # Order作成
                    val.pop("code")
                    val['datetime'] = datetime.strptime(
                        "{}+0900".format(val['datetime']), "%Y-%m-%d %H:%M%z")

                    o = Order.objects.create(**val)
                    pk_orders.append(o.pk)
                    msg = "New Order is created: {}".format(o)
                    logger.info(msg)
                # OrderProcessの実行
                """is_buyを入れると、デイトレのケースが通らない。外すと、A買い・B売り・A買いが通らない。後者は買付余力を上げて対応"""
                # orders = Order.objects.filter(pk__in=pk_orders).order_by("is_buy", "datetime")
                orders = Order.objects.filter(
                    pk__in=pk_orders).order_by("datetime")
                data_list = list()
                for o in orders:
                    res = mylib_asset.order_process(o, user=o.user)
                    if res['status']:
                        data_list.append({
                            "commission": o.commission,
                            "val": o.val,
                            "num": o.num,
                            "datetime": str(o.datetime),
                            "is_buy": o.is_buy,
                            "stock__code": o.stock.code,
                            "stock__name": o.stock.name,
                        })
                    else:
                        raise Exception('OrderProcess of {} failed'.format(o))
                data = {
                    "status": True,
                    "message": msg,
                    "data": data_list,
                }
        except Exception as e:
            logger.error(e)
            data = {"status": False, "message": "{}".format(e), "data": {}}
        finally:
            logger.info(data)
            json_str = json.dumps(data, ensure_ascii=False, indent=2)
            response = HttpResponse(
                json_str,
                content_type='application/json; charset=UTF-8',
                status=None)
            return response
    elif request.method == "GET":
        data = {
            "status": False,
            "message": "Please use POST method",
            "data": {}
        }
        json_str = json.dumps(data, ensure_ascii=False, indent=2)
        response = HttpResponse(json_str,
                                content_type='application/json; charset=UTF-8',
                                status=None)
        return response
예제 #11
0
 def get_context_data(self, **kwargs):
     context = super().get_context_data(**kwargs)
     data = mylib_scraping.yf_detail(self.object.code)
     context[
         "current_val"] = data['data']['val'] if data['status'] else None
     context['svds'] = StockValueData.objects.filter(
         stock=context['stock'],
         date__gte=(date.today() -
                    relativedelta(months=6))).order_by('date')
     if context['svds'].count() > 0:
         df = mylib_analysis.prepare(context['svds'])
         # context['df_latest'] = df.iloc[-1]
         # context['df_check'] = mylib_analysis.check(df)
         context['df_trend'] = mylib_analysis.get_trend(df)
     context['sfds'] = StockFinancialData.objects.filter(
         stock=context['stock']).order_by('date')
     context['entry_form'] = EntryForm(
         initial={
             "user": self.request.user,
             "stock": context['stock'],
             "border_loss_cut": round(context["current_val"] * 0.9),
             "border_profit_determination": round(context["current_val"] *
                                                  1.1),
             "val_plan": round(context["current_val"]),
         })
     context["sads"] = StockAnalysisData.objects.filter(
         stock=context["stock"]).order_by('-date')[0:5]
     context["sbialert_form"] = SBIAlertForm(initial={"stock": self.object})
     context["sbialerts"] = SBIAlert.objects.filter(stock=self.object,
                                                    is_active=True)
     context['sfds'] = self.object.stockfinancialdata_set.all().order_by(
         '-date')
     # 日付とindex番号の紐付け
     date_list = dict()
     for i, svd in enumerate(context['svds']):
         date_list[svd.date.__str__()] = i
     # 売買注文のグラフ化
     svds_count = context['svds'].count()
     bos_detail = [None for i in range(svds_count)]
     sos_detail = [None for i in range(svds_count)]
     for o in self.object.order_set.all():
         order_date = str(o.datetime.date())
         if order_date in list(date_list.keys()):
             if o.is_buy:
                 bos_detail[date_list[
                     order_date]] = o.val * 10000 if self.object.is_trust else o.val
             else:
                 sos_detail[date_list[
                     order_date]] = o.val * 10000 if self.object.is_trust else o.val
     context["bos_detail"] = bos_detail
     context["sos_detail"] = sos_detail
     # 現在情報を取得
     overview = mylib_scraping.yf_detail(self.object.code)
     if overview['status']:
         context['overview'] = overview['data']
     # sads
     context['sads'] = StockAnalysisData.objects.filter(
         stock=context['stock'],
         date__gte=(date.today() -
                    relativedelta(months=6))).order_by('-date')
     # twitter
     twitter = mylib_twitter.Twitter()
     names = context['stock'].name.split("(株)")
     keyword_tweet = "{} {}".format(
         names[0] if names[0] not in ("(株)", "") else names[1],
         context['stock'].code)
     tweets = twitter.getTweets(keyword_tweet, 10)
     context['tweets'] = tweets['statuses'] if tweets else list()
     context['keyword_tweet'] = keyword_tweet
     # return
     return context
예제 #12
0
 def get_context_data(self, **kwargs):
     # 各種情報取得
     entry = self.get_object()
     orders_unlinked = Order.objects.filter(
         entry=None, stock=entry.stock).order_by('datetime')
     orders_linked = entry.order_set.all().order_by('datetime')
     edo = entry.date_open().date() if orders_linked.exists(
     ) else date.today()
     edc = entry.date_close().date(
     ) if entry.is_closed and not entry.is_plan else date.today()
     # sbialert
     sbialerts = SBIAlert.objects.filter(stock=entry.stock, is_active=True)
     sbialert_form = SBIAlertForm(initial={"stock": entry.stock})
     # days日のマージンでグラフ化範囲を指定
     days = 60
     od = edo - relativedelta(days=days)
     cd = edc + relativedelta(
         days=days) if entry.is_closed else date.today()
     svds = StockValueData.objects.filter(stock=entry.stock,
                                          date__gte=od,
                                          date__lte=cd).order_by('date')
     df = mylib_analysis.prepare(svds)
     # df_check = mylib_analysis.check(df)
     df_trend = mylib_analysis.get_trend(df)
     # グラフ化範囲のデータ数
     svds_count = svds.count()
     # 日付とindex番号の紐付け
     date_list = dict()
     for i, svd in enumerate(svds):
         date_list[svd.date.__str__()] = i
     # 売買注文のグラフ化
     bos_detail = [None for i in range(svds_count)]
     sos_detail = [None for i in range(svds_count)]
     for o in entry.order_set.all():
         order_date = str(o.datetime.date())
         if order_date in list(date_list.keys()):
             if o.is_buy:
                 bos_detail[date_list[
                     order_date]] = o.val * 10000 if entry.stock.is_trust else o.val
             else:
                 sos_detail[date_list[
                     order_date]] = o.val * 10000 if entry.stock.is_trust else o.val
     # graphの判定
     t = date.today()
     if (svds.count() > 0
             and svds.latest('date').date == t) or t.isoweekday() > 5:
         if t.isoweekday() <= 5:
             mylib_asset.register_stock_value_data_alt(entry.stock.code)
             svds = StockValueData.objects.filter(
                 stock=entry.stock, date__gte=od,
                 date__lte=cd).order_by('date')
         is_add_graph = False
     else:
         is_add_graph = True
     # 現在情報を取得
     overview_res = mylib_scraping.yf_detail(entry.stock.code)
     if overview_res['status']:
         overview = overview_res['data']
     else:
         svd_latest = StockValueData.objects.filter(
             stock=entry.stock).latest('date')
         overview = {
             "val": svd_latest.val_close,
             "val_high": svd_latest.val_high,
             "val_low": svd_latest.val_low,
             "val_open": svd_latest.val_open,
             "val_close": svd_latest.val_close,
             "turnover": svd_latest.turnover,
         }
     # OrderFormを追加
     order_form = OrderForm(
         initial={
             "user": self.request.user,
             "is_nisa": entry.stock.is_trust,
             "is_buy": True,
             "entry": entry,
             "commission": 0 if entry.stock.is_trust else None,
             "stock": entry.stock,
         })
     # sads
     sads = StockAnalysisData.objects.filter(stock=entry.stock,
                                             date__gte=od,
                                             date__lte=cd).order_by('-date')
     # twitter
     twitter = mylib_twitter.Twitter()
     names = entry.stock.name.split("(株)")
     keyword_tweet = "{} {}".format(
         names[0] if names[0] not in ("(株)", "") else names[1],
         entry.stock.code)
     tweets = twitter.getTweets(keyword_tweet, 10)
     tweets = tweets['statuses'] if tweets else list()
     # dividend_total
     dividend_total = entry.dividend_set.all().aggregate(val=Sum('val'),
                                                         tax=Sum('tax'))
     # output
     output = {
         "user": self.request.user,
         "entry": entry,
         "orders_unlinked": orders_unlinked,
         "orders_linked": orders_linked,
         "svds": svds,
         "bos_detail": bos_detail,
         "sos_detail": sos_detail,
         "od": od,
         "cd": cd,
         "df_trend": df_trend,
         "sbialert_form": sbialert_form,
         "sbialerts": sbialerts,
         "is_add_graph": is_add_graph,
         "overview": overview,
         "order_form": order_form,
         "sads": sads,
         "tweets": tweets,
         "keyword_tweet": keyword_tweet,
         "dividend_total": dividend_total,
         "dividend_count": entry.dividend_set.all().count(),
     }
     # res
     return output