def price_notification(): # TODO 監視対象企業が30社の場合に描画している図が多いという警告が出たのでなおす # RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure` # ) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`). # fig = plt.figure() for brand in BrandRepo().select_all_brand(): code = brand.code name = brand.name file_path = f'temp/{code}_candle.png' prices = BrandRepo().select_prices(code) data = { 'date': list(map(lambda p: p.date, prices)), 'open': list(map(lambda p: p.open, prices)), 'high': list(map(lambda p: p.high, prices)), 'low': list(map(lambda p: p.low, prices)), 'close': list(map(lambda p: p.close, prices)) } df = pd.DataFrame(data).set_index("date") fig = plt.figure() ax = plt.subplot() xdate = [x.date() for x in df.index] # Timestamp -> datetime ohlc = np.vstack((date2num(xdate), df.values.T)).T # datetime -> float candlestick_ohlc(ax, ohlc, width=0.7, colorup='g', colordown='r') ax.grid() # グリッド表示 register_matplotlib_converters() ax.set_xlim(df.index[0].date(), df.index[-1].date()) # x軸の範囲 fig.autofmt_xdate() # x軸のオートフォーマット plt.savefig(file_path) slack_comment(f'{code} {name} ローソク足チャート') time.sleep(10) slack_file_upload(file_path) time.sleep(10) os.remove(file_path)
def save_stock(): def crawl(code): time.sleep(30) return map(lambda l: Price(code, l[0].to_pydatetime(), l[1], l[2], l[3], l[4], l[5], l[6]), crawl_stock(code).values.tolist()) print("save stock start") # TODO 一旦全レコード分メモリ展開するのは直す BrandRepo().insert_stocks( reduce(add, list(map(lambda brand: list(crawl(brand.code)), list(BrandRepo().select_all_brand()))))) print("save stock end")
def make_price_df(brands): df = pd.DataFrame(columns=[ 'code', 'date', 'open', 'high', 'low', 'close', 'golden_cross', 'dead_cross' ]).set_index(['code', 'date']) for brand in brands: code = brand.code prices = BrandRepo().select_prices(code) data = { 'code': list(map(lambda p: p.code, prices)), 'date': list(map(lambda p: p.date, prices)), 'open': list(map(lambda p: p.open, prices)), 'high': list(map(lambda p: p.high, prices)), 'low': list(map(lambda p: p.low, prices)), 'close': list(map(lambda p: p.close, prices)) } brand_df = pd.DataFrame(data).set_index(['code', 'date']) sma_5 = brand_df.groupby(level='code')['close'].rolling( window=5).mean() sma_25 = brand_df.groupby(level='code')['close'].rolling( window=25).mean() sma_5_over_25 = sma_5 > sma_25 cross = sma_5_over_25 != sma_5_over_25.shift(1) golden_cross = cross & (sma_5_over_25 == True) dead_cross = cross & (sma_5_over_25 == False) brand_df['sma_5'] = brand_df.groupby( level='code')['close'].rolling(window=5).mean().values brand_df['sma_25'] = brand_df.groupby( level='code')['close'].rolling(window=25).mean().values brand_df['sma_5_over_25'] = sma_5_over_25.values brand_df['golden_cross'] = golden_cross.values brand_df['dead_cross'] = dead_cross.values df = df.append(brand_df[25:], sort=True) return df
def new_brand_notification(): df = pd.DataFrame(list( map( lambda new_brand: (new_brand.code, new_brand.format_date(), new_brand.name), BrandRepo().select_new_brand_recently())), columns=["code", "date", "name"]) slack_comment("新株情報\n" + str(df))
def brand_notification(): df = pd.DataFrame( list( map( lambda brand: (brand.code, brand.name, brand.short_name, brand. market, brand.sector, brand.unit), BrandRepo().select_all_brand())), columns=["code", "name", "short_name", "market", "sector", "unit"]) slack_comment("監視対象株\n" + str(df))
def sync_brand(): def read_brand_codes(filepath): with open(filepath) as f: return filter(lambda code: code != '', map(lambda code: code.strip(), f.read().split("\n"))) def crawl_brands(new_codes): for new_code in new_codes: brand = get_brand(new_code) print(brand) yield Brand(brand[0], brand[1], brand[2], brand[3], brand[5], brand[4]) time.sleep(30) print("sync brand start") target_codes_set = set(read_brand_codes("brand_list.txt")) saved_codes_set = set(map(lambda brand: brand.code, BrandRepo().select_all_brand())) new_codes = filter(lambda target_code: target_code not in saved_codes_set, target_codes_set) del_codes = filter(lambda saved_code: saved_code not in target_codes_set, saved_codes_set) BrandRepo().insert_brands(list(crawl_brands(new_codes))) BrandRepo().delete_brand_by_codes(list(del_codes)) print("sync brand end")
def save_newbrand(): BrandRepo().insert_new_brands(list(map( lambda new_brand: NewBrand(new_brand[0], new_brand[1].strftime('%Y/%m/%d'), new_brand[2]), get_new_brands2())))
def simulate(): def make_price_df(brands): df = pd.DataFrame(columns=[ 'code', 'date', 'open', 'high', 'low', 'close', 'golden_cross', 'dead_cross' ]).set_index(['code', 'date']) for brand in brands: code = brand.code prices = BrandRepo().select_prices(code) data = { 'code': list(map(lambda p: p.code, prices)), 'date': list(map(lambda p: p.date, prices)), 'open': list(map(lambda p: p.open, prices)), 'high': list(map(lambda p: p.high, prices)), 'low': list(map(lambda p: p.low, prices)), 'close': list(map(lambda p: p.close, prices)) } brand_df = pd.DataFrame(data).set_index(['code', 'date']) sma_5 = brand_df.groupby(level='code')['close'].rolling( window=5).mean() sma_25 = brand_df.groupby(level='code')['close'].rolling( window=25).mean() sma_5_over_25 = sma_5 > sma_25 cross = sma_5_over_25 != sma_5_over_25.shift(1) golden_cross = cross & (sma_5_over_25 == True) dead_cross = cross & (sma_5_over_25 == False) brand_df['sma_5'] = brand_df.groupby( level='code')['close'].rolling(window=5).mean().values brand_df['sma_25'] = brand_df.groupby( level='code')['close'].rolling(window=25).mean().values brand_df['sma_5_over_25'] = sma_5_over_25.values brand_df['golden_cross'] = golden_cross.values brand_df['dead_cross'] = dead_cross.values df = df.append(brand_df[25:], sort=True) return df def trade_func(brands, date, portfolio): orders = [] # Dead crossが発生していて持っている株があれば売る for brand in brands: code = brand.code if date in price_df.loc[code].index and price_df.loc[code, date].dead_cross \ and code in portfolio.stocks: print("sell") orders.append( SellMarketOrder(code, portfolio.stocks[code].current_count)) # 保有していない株でgolden crossが発生していたら買う if brand in brands: code = brand.code unit = brand.unit if date in price_df.loc[code].index and price_df.loc[code, date].golden_cross \ and code not in portfolio.stocks: print("buy") orders.append(BuyMarketOrderAsPossible(code, unit)) return orders def get_open_price_func(code, date): return price_df.loc[code, date].open def get_close_price_func(code, date): return price_df.loc[code, date].close def current_price(d): # 本日(d)の損益などを記録 current_total_price = portfolio.calc_current_total_price( lambda code, date: get_close_price_func(code, date), d) return current_total_price, current_total_price - portfolio.amount_of_investment total_price_list.append(current_total_price) profit_or_loss_list.append(current_total_price - portfolio.amount_of_investment) def simulate(portfolio, df): def execute_order(d, orders): # 本日(d)において注文(orders)をすべて執行する for order in orders: executions.append( order.execute(d, portfolio, get_open_price_func)) orders = [] total_price_list = [] profit_or_loss_list = [] executions = [] for current_date in date_range: # シミュレーション execute_order(current_date, orders) total_price, profit_or_loss = current_price(current_date) total_price_list.append(total_price) profit_or_loss_list.append(profit_or_loss) orders = trade_func(brand_list, current_date, portfolio) return total_price_list, profit_or_loss_list, executions portfolio = Portfolio(10000000) brand_list = list(BrandRepo().select_all_brand()) price_df = make_price_df(brand_list) date_range = [ pdate.to_pydatetime().date() for pdate in tse_date_range( price_df.sort_values(by='date', ascending=True).head( 1).index.get_level_values('date')[0], price_df.sort_values(by='date', ascending=False).head( 1).index.get_level_values('date')[0]) ] total_price_list, profit_or_loss_list, executions = simulate( portfolio, price_df) profit_df = pd.DataFrame({ 'date': date_range, 'profit_or_loss': profit_or_loss_list }).set_index('date') save_dataframe(profit_df, 'temp/simulate.png') execution_str = "" for execution in executions: execution_str += str(execution) + "\n" slack_comment(execution_str) slack_file_upload('temp/simulate.png')
class TestBrandRepo(TestCase): def __init__(self, *args, **kwargs): super(TestBrandRepo, self).__init__(*args, **kwargs) self.brandRepo = BrandRepo() BrandRepo() BrandRepo() BrandRepo() def test(self): print("Test BrandRepo start") self.brandRepo.setup() # 一旦全削除 self.brandRepo.delete_all() self.checkBrand() self.checkNewBrand() print("Test BrandRepo end") def checkBrand(self): print("Test Brand start") brands1 = [ Brand(code="3382", name="セブン&アイ・ホールディングス", short_name="セブン&アイ", market="東証1", sector="小売業", unit=100), Brand(code="4755", name="楽天", short_name="楽天", market="東証1", sector="サービス業", unit=100), Brand(code="6861", name="キーエンス", short_name="キーエンス", market="東証1", sector="電気機器", unit=100) ] self.brandRepo.insert_brands(brands1) self.brandRepo.insert_brands(brands1) brands2 = [ Brand(code="6752", name="パナソニック", short_name="パナソニック", market="東証1", sector="電気機器", unit=100), Brand(code="6861", name="キーエンス", short_name="キーエンス", market="東証1", sector="電気機器", unit=100) ] self.brandRepo.insert_brands(brands2) print("Test Brand end") def checkNewBrand(self): this_year1 = datetime.now() this_year2 = this_year1 + timedelta(days=1) this_year3 = this_year2 + timedelta(days=1) last_year1 = this_year1 - timedelta(days=365) last_year2 = last_year1 + timedelta(days=1) two_years_ago1 = this_year1 - timedelta(days=730) print("Test newBrand start") newBrands1 = [ NewBrand("3000", this_year1.strftime('%Y/%m/%d'), "会社A"), NewBrand("3001", this_year2.strftime('%Y/%m/%d'), "会社B"), NewBrand("3002", this_year3.strftime('%Y/%m/%d'), "会社C"), NewBrand("3003", last_year1.strftime('%Y/%m/%d'), "会社D") ] self.brandRepo.insert_new_brands(newBrands1) self.brandRepo.insert_new_brands(newBrands1) newBrands2 = [ NewBrand("3002", this_year3.strftime('%Y/%m/%d'), "会社C"), NewBrand("3003", last_year1.strftime('%Y/%m/%d'), "会社D"), NewBrand("3004", last_year2.strftime('%Y/%m/%d'), "会社E"), NewBrand("3005", two_years_ago1.strftime('%Y/%m/%d'), "会社F") ] self.brandRepo.insert_new_brands(newBrands2) dic = dict( list( map(lambda newBrand: (newBrand.code, newBrand), self.brandRepo.select_new_brand_recently()))) self.assertTrue("3000" in dic) self.assertTrue( dic["3000"].format_date() == this_year1.strftime('%Y/%m/%d')) self.assertTrue("3001" in dic) self.assertTrue( dic["3001"].format_date() == this_year2.strftime('%Y/%m/%d')) self.assertTrue("3002" in dic) self.assertTrue( dic["3002"].format_date() == this_year3.strftime('%Y/%m/%d')) self.assertTrue("3003" in dic) self.assertTrue( dic["3003"].format_date() == last_year1.strftime('%Y/%m/%d')) self.assertTrue("3004" in dic) self.assertTrue( dic["3004"].format_date() == last_year2.strftime('%Y/%m/%d')) self.assertFalse("3005" in dic) print("Test newBrand end")
def __init__(self, *args, **kwargs): super(TestBrandRepo, self).__init__(*args, **kwargs) self.brandRepo = BrandRepo() BrandRepo() BrandRepo() BrandRepo()