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)
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))
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)
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
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)
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
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
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
def current_val(self): data = mylib_scraping.yf_detail(self.code) return data['data']['val'] if data['status'] else self.latest_val()
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
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
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