def run_batch(start_id, end_id, space_type='Office', saving_target=2, cached_weather=True, batch_report=False, use_default_benchmark_data=True, save_portfolio_results=True): # Conditionally generate the benchmark stats for the porfolio if use_default_benchmark_data: df_user_bench_stats_e, df_user_bench_stats_f = None, None else: # Initialize a portfolio instance s_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) data_path = s_path + '/Data/' p = portfolio.Portfolio('Test') p.read_raw_data_from_xlsx(data_path + 'portfolio.xlsx') # 1 ~ electricity; 2 ~ fossil fuel dict_raw_electricity = p.get_portfolio_raw_data_by_spaceType_and_utilityType( space_type, utility_type=1) dict_raw_fossil_fuel = p.get_portfolio_raw_data_by_spaceType_and_utilityType( space_type, utility_type=2) df_user_bench_stats_e = p.generate_benchmark_stats_wrapper( dict_raw_electricity, cached_weather) df_user_bench_stats_f = p.generate_benchmark_stats_wrapper( dict_raw_fossil_fuel, cached_weather) v_single_buildings = [] v_single_building_reports = [] for i in range(start_id, end_id + 1): print('--------------------------------------------------') print('Analyzing building ' + str(i)) single_building = run_single( bldg_id=i, saving_target=saving_target, cached_weather=cached_weather, use_default_benchmark_data=use_default_benchmark_data, df_user_bench_stats_e=df_user_bench_stats_e, df_user_bench_stats_f=df_user_bench_stats_f)[1] v_single_buildings.append(single_building) if batch_report: report_path = os.path.dirname( os.path.dirname(os.path.realpath(__file__))) + '/outputs/' portfolio_out = portfolio.Portfolio('Sample Portfolio') portfolio_out.prepare_portfolio_report_data(v_single_buildings, report_path, save_portfolio_results) report_portfolio = report.Report(portfolio=portfolio_out) report_portfolio.generate_portfolio_report(report_path)
def test_MutualFund(self): testPortfolio = portfolio.Portfolio() abece = portfolio.MutualFund("ABC") testPortfolio.buyMutualFund(81.8, abece) testPortfolio.sellMutualFund("ABC", 80.8) amount = testPortfolio.mutualfunds["ABC"] self.assertEqual(amount, 1)
def test_sellstock(self): testPortfolio = portfolio.Portfolio() thy = portfolio.Stock(10, "THYAO") testPortfolio.buyStock(23, thy) testPortfolio.sellStock("THYAO", 18) amount = testPortfolio.stocks["THYAO"] self.assertEqual(amount, 5)
def test_buystock(self): testPortfolio = portfolio.Portfolio() thy = portfolio.Stock(10, "THYAO") testPortfolio.buyStock(23, thy) amount = testPortfolio.stocks["THYAO"] self.assertEqual(amount, 23) self.assertEqual(-230, testPortfolio.cash)
def create(bot, update, args): """Creates a portfolio for the user.""" # Open db connection mgclient = MongoClient() db = mgclient.user_db # Create database for user information portfolio_db = db.portfolios # Create table for portfolio data username = update.message.from_user.__dict__['username'] # Check if user already has a portfolio with the same name if db.portfolios.find_one({ 'owner': update.message.from_user.__dict__['id'], 'name': args[0].title() }): update.message.reply_text( 'You already have a portfolio with that name!') return False # Create the portfolio using user ID and portfolio name new_portfolio = p.Portfolio(update.message.from_user.__dict__['id'], args[0].title()) # Insert the class into the mongodb database db.portfolios.insert(new_portfolio.__dict__) update.message.reply_text(f'@{username}, your portfolio was created!', quote=False) # Close db connection mgclient.close() return True
def main(): config = multiconfigparser.ConfigParserMultiOpt() stocks_config = multiconfigparser.ConfigParserMultiOpt() args = parse_args() portfolio = port.Portfolio() # read config files config.read(args.config) stocks_config.read(args.portfolio_config) # verify that config file is correct # merge options from cli and config verify_stock_keys(stocks_config) merge_config(config, args) portfolio.populate(stocks_config, args) portfolio.gen_graphs(args.independent_graphs, args.width, args.height, args.timezone) # print to the screen render_engine = Renderer(args.rounding_mode, portfolio) render_engine.render() return
def setUp(self): """ Create portfolio object to be used for the remainder of UTs. """ self.startingCapital = 1000000 self.maxCapitalToUse = 0.5 self.maxCapitalToUsePerTrade = 0.5 self.portfolioObj = portfolio.Portfolio(self.startingCapital, self.maxCapitalToUse, self.maxCapitalToUsePerTrade)
def read_portfolio(filename): ''' Read a stock portfolio file into a list of dictionaries with keys name, shares, and price. ''' with open(filename) as lines: portdict = fileparse.parse_csv(lines, select=['name', 'shares', 'price'], types=[str, int, float]) return portfolio.Portfolio([stock.Stock(**port) for port in portdict])
def read_portfolio(filename): with open(filename, "rt") as infile: portfolios = fileparse.parse_csv(infile, select=["name", "shares", "price"], types=[str, int, float]) portfolios = [ stock.Stock(d["name"], d["shares"], d["price"]) for d in portfolios ] return portfolio.Portfolio(portfolios)
def testUpdatePortfolio(self): """Test the ability to update option values for a position in the portfolio. """ startingCapital = 1000000 maxCapitalToUse = 0.5 maxCapitalToUsePerTrade = 0.5 portfolioObj = portfolio.Portfolio(self.startingCapital, self.maxCapitalToUse, self.maxCapitalToUsePerTrade) # Get an option chain from the CSV. # Create CsvData class object. dataProvider = 'iVolatility' directory = '/Users/msantoro/PycharmProjects/Backtester/marketData/iVolatility/SPX/SPX_2011_2017' filename = 'RawIV_5day_sample.csv' chunkSize = 10000 eventQueue = queue.Queue() csvObj = csvData.CsvData(directory, filename, dataProvider, eventQueue, chunkSize) # Get the first option chain. firstOptionChainValid = csvObj.getOptionChain() queueObj = eventQueue.get(False) firstOptionChainData = queueObj.getData() # Choose two of the options in the first option chain to create a strangle; using first expiration. putObj = firstOptionChainData[217] # -0.172245 delta put callObj = firstOptionChainData[248] # 0.154042 delta call # Create strangle an add to portfolio. orderQuantity = 1 strangleObj = strangle.Strangle(orderQuantity, callObj, putObj, "SELL") # Create signal event. event = signalEvent.SignalEvent() event.createEvent(strangleObj) # Create portfolio onSignal event, which adds the position to the portfolio. portfolioObj.onSignal(event) # Next, get the prices for the next day (1/4/11) and update the portfolio values. newOptionChainValid = csvObj.getOptionChain() tickEvent = eventQueue.get(False) # Update portfolio values. portfolioObj.updatePortfolio(tickEvent) # Check that the new portfolio values are correct (e.g., buying power, total delta, total gamma, etc). self.assertAlmostEqual(portfolioObj.getTotalBuyingPower(), 28950.0) self.assertAlmostEqual(portfolioObj.getVega(), 1.303171) self.assertAlmostEqual(portfolioObj.getDelta(), -0.018826) self.assertAlmostEqual(portfolioObj.getGamma(), 0.012173) self.assertAlmostEqual(portfolioObj.getTheta(), -0.583284) self.assertAlmostEqual(portfolioObj.getNetLiq(), 1000060.0)
def createPortfolio(): a = [] for ticker in stocks_n_transactions: s = portfolio.Stock(ticker) for k in stocks_n_transactions[ticker]: t = stocks_n_transactions[ticker][k] s.addTransaction(t['price'], t['ttype'], t['num'], t['date']) a.append(s) p = portfolio.Portfolio('Test') for stock in a: p.addStock(stock) return p
def run(self): self.t0 = time.time() # 回测起始时间 event_queue = queue.Queue() # 创建事件队列 #event_queue = queue.PriorityQueue() # 优先队列,用于FILL实时回填 # 初始化行情数据、持仓列表、交易策略、交易记录 bars = data.HistoricDataHandler(event_queue, self.ContextInfo) port = portfolio.Portfolio(event_queue, self.ContextInfo, bars) order = ordertype.Order(event_queue, bars, port) # 提供便捷的交易函数,不涉及主循环 stg = self.Strategy(event_queue, self.ContextInfo, bars, port, order) brok = broker.SimulatedExecution(event_queue, self.ContextInfo, bars, port) stg.initialize() # 策略初始化函数 print("[Initialized]Time:", time.time() - self.t0) # 初始化耗时 # 事件驱动主循环 while True: bars.update_bars() # 获取新数据 if bars.continue_backtest: port.update_portfolios() # 更新持仓列表 brok.update_temp_pos() # 更新broker的当前持仓(实盘不需要) else: break # 数据处理完毕,跳出外循环 while True: # 处理新数据 try: event = event_queue.get(False) # 获取事件队列 except queue.Empty: # 事件队列为空,跳出内循环 break else: # 处理新事件 if event is not None: #print(event.type) if event.type == 'MARKET': # 基于数据生成市场事件 stg.handlebar(event) elif event.type == 'ORDER': # 基于策略生成委托事件 brok.execute_order(event) elif event.type == 'FILL': # 基于成交生成回报事件 port.update_fill(event) # 回测结束,保存持仓及交易记录 self.portfolios = port self.broker = brok print("[Backtest Finished]Time:", time.time() - self.t0) # 回测累计耗时
def portfolio_port_test(): """ test of 'lifo' queuing by adding and removing a position. """ p1 = position.Position(symbol="AAPL", id="1110", qty=1000, price=185.25, multiplier=1., fee=7.0, total_amt=185250., trans_date=1053605468.54) p2 = position.Position(symbol="AAPL", id="1111", qty=1500, price=184.00, multiplier=1., fee=7.0, total_amt=276000., trans_date=1054202245.63) p3 = position.Position(symbol="GOOG", id="1112", qty=2000, price=286.00, multiplier=1., fee=7.0, total_amt=572000., trans_date=1055902486.22) h = portfolio.Holding() h.add_to(p1) h.add_to(p2) h2 = portfolio.Holding() h2.add_to(p3) portf = portfolio.Portfolio(name="Test Portfolio", holdings=[h, h2]) print dir(portf) print portf.holdings print portf.pprint assert len(portf.holdings) == 2 assert portf.holdings["GOOG"].symbol == "GOOG" return
def __init__(self, strategy_label, enter_signal, exit_signal, risk_cap, starting_cash, chart_functions, chart_functions_new, symbol_blacklist, trading_symbols, trading_start, trading_end, trading_type, trading_commission, always_plot): self.strategy_label = strategy_label p = re.compile('(\s\s*)') self.enter_signal = p.sub(' ', enter_signal) self.exit_signal = p.sub(' ', exit_signal) self.risk_cap = p.sub(' ', risk_cap) self.starting_cash = starting_cash self.chart_functions = chart_functions self.chart_functions_new = chart_functions_new self.trading_start = util.convert_to_datetime(trading_start) self.trading_end = util.convert_to_datetime(trading_end) symbol_start = self.trading_start - datetime.timedelta(100) self.trading_symbols = sl.SymbolList(trading_symbols, symbol_blacklist, symbol_start, self.trading_end) self.trading_symbols_label = trading_symbols #self.trading_start = datetime.strptime(trading_start, "%Y%M%d") #self.trading_end = datetime.strptime(trading_end, "%Y%M%d") self.trading_type = trading_type self.trading_commission = trading_commission self.always_plot = always_plot self.daterange = util.date_range(self.trading_start, self.trading_end) print self.daterange # Portfolio to manage the trading transactions of the strategy self.portfolio = portfolio.Portfolio(self.starting_cash, self.trading_start, self.trading_commission) # time series used to store when we are in or out of the market self.in_n_out = None self.trading_days = None # dictionary with time series of computed indicators # time series to store the performance of the current trading strategy self.performance_index = {} self.stock_chart = {} self.indicators = {}
def main(): with open("symbolsPruned", "r", newline="\n") as file: symbols = file.read().strip().split("\n") percentages = [] exchange.init(symbols, period=500, historyDays=algorithms.KIPPslowDays) for run in range(500): # Select a set of 5 random symbols from the entire set selectedSymbols = random.sample(symbols, 10) # print(selectedSymbols) period = random.randint(30, 500) exchange.reset(period) p = portfolio.Portfolio(3000) for i in range(period): if (i % 5) == 0: p.fund(150) exchange.openMarket() algorithms.KIPP(selectedSymbols, p) value = p.value() exchange.closeMarket() closeRatio = value / p.investment percentageYr = math.log(closeRatio) * 252 / period / math.log(2) percentages.append(percentageYr * 100) print( "{:3} ended with gain of ${:10.2f} with ${:10.2f} invested at {:6.1f}% {:6.1f}%(yr)" .format(run, value - p.investment, p.investment, (closeRatio - 1) * 100, percentageYr * 100)) print(st.describe(percentages)) pyplot.hist(percentages, density=True, bins=50) mn, mx = pyplot.xlim() kde_xs = numpy.linspace(mn, mx, 301) kde = st.gaussian_kde(percentages) pyplot.plot(kde_xs, kde.pdf(kde_xs)) pyplot.xlabel("Percentage (yr)") pyplot.ylabel("Probability") pyplot.xlim(min(percentages), max(percentages)) pyplot.show()
def main(): # Initialize Variables (Imports) m = money.Money() port = portfolio.Portfolio(m) wl = watch_list.Watch_List() # Main Text Display m.print_funds() option = input(display) while True: if option == '1': port.main() elif option == '2': m.money_main() elif option == '3': wl.main() elif option == '4': ipt = input("Would you like to see your current portfolio? (Y/N) ").upper() if ipt == 'Y': port.print_portfolio() ipt = input("Would you like to see your current watch list? (Y/N) ").upper() if ipt == 'Y': wl.print_wl() stock_ipt = input("Please type the ticker symbol of a stock. ").upper() try: print('\nCurrent Ticker Symbol: ' + str(stock_ipt).upper()) stock.Stock(stock_ipt).stock_main() except (AttributeError, IndexError, KeyError) as e: print("\n" + str(stock_ipt) + ' is not a valid ticker symbol in Yahoo Finance ' 'or the given ticker symbol is not supported by the yfinance API.') elif option == '5': google_search_keyword() elif option == 'gui': gui.main(m, port, wl) elif option == 'quit': return m.print_funds() option = input(display)
def run_batch(start_id, end_id, saving_target=2, cached_weather=True, batch_report=False): v_single_buildings = [] v_single_building_reports = [] for i in range(start_id, end_id + 1): print('--------------------------------------------------') print('Analyzing building ' + str(i)) single_building = run_single(bldg_id=i, saving_target=saving_target, use_default_benchmark_data=True, cached_weather=cached_weather)[1] v_single_buildings.append(single_building) if batch_report: report_path = os.path.dirname( os.path.dirname(os.path.realpath(__file__))) + '/outputs/' portfolio_out = portfolio.Portfolio('Sample Portfolio') portfolio_out.prepare_portfolio_report_data(v_single_buildings, report_path) report_portfolio = report.Report(portfolio=portfolio_out) report_portfolio.generate_portfolio_report(report_path)
def run_single(bldg_id=1, saving_target=2, anio=3, r=4, space_type='Office', cached_weather=True, write_fim=True, write_model=True, return_data=False, use_default_benchmark_data=True, df_user_bench_stats_e=None, df_user_bench_stats_f=None): # Set paths s_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) data_path = s_path + '/Data/' report_path = s_path + '/outputs/' # Create an outputs directoty if there isn't one. if not os.path.exists(report_path): os.makedirs(report_path) # Initialize a portfolio instance p = portfolio.Portfolio('Test') # p.read_raw_data_from_xlsx(data_path + 'portfolio.xlsx') p.read_raw_data_from_xlsx(data_path + 'portfolio.xlsx') # Get building data from the portfolio building_id = bldg_id building_info = p.get_building_info_by_id(building_id) if (building_info == None): return False, None else: building_test = building.Building(building_id, *building_info, saving_target) # Get utility data from portfolio df_raw_electricity = p.get_utility_by_building_id_and_energy_type( building_ID=building_id, energy_type=1, anio=anio) df_raw_fossil_fuel = p.get_utility_by_building_id_and_energy_type( building_ID=building_id, energy_type=2, anio=anio) df_raw_utility_e = df_raw_electricity df_raw_utility_f = df_raw_fossil_fuel utility_test_e = utility.Utility('electricity', df_raw_utility_e) utility_test_f = utility.Utility('fossil fuel', df_raw_utility_f) building_test.add_utility(utility_test_e, utility_test_f) weather_test_e = weather.Weather(building_test.coord) weather_test_f = weather.Weather(building_test.coord) building_test.add_weather(cached_weather, weather_test_e, weather_test_f) # Fit inverse model and benchmark has_fit = building_test.fit_inverse_model() # Continue only if there is at least one change-point model fit. if has_fit: if (use_default_benchmark_data): building_test.benchmark() building_test.ee_assess() else: # Note: the benchmark data sets are generated from the portfolio spreadsheet. # 1 ~ electricity; 2 ~ fossil fuel dict_raw_electricity = p.get_portfolio_raw_data_by_spaceType_and_utilityType( space_type, utility_type=1) dict_raw_fossil_fuel = p.get_portfolio_raw_data_by_spaceType_and_utilityType( space_type, utility_type=2) # Generate the benchmark stats from the user provided data in the portfolio spreadsheet if df_user_bench_stats_e is None: df_user_bench_stats_e = p.generate_benchmark_stats_wrapper( dict_raw_electricity, cached_weather) if df_user_bench_stats_f is None: df_user_bench_stats_f = p.generate_benchmark_stats_wrapper( dict_raw_fossil_fuel, cached_weather) building_test.benchmark( use_default=False, df_benchmark_stats_electricity=df_user_bench_stats_e, df_benchmark_stats_fossil_fuel=df_user_bench_stats_f) building_test.ee_assess( use_default=False, df_benchmark_stats_electricity=df_user_bench_stats_e, df_benchmark_stats_fossil_fuel=df_user_bench_stats_f) building_test.calculate_savings() building_test.plot_savings() building_test.disaggregate_consumption_wrapper() # Output to files # Save FIM to csv #if (hasattr(building_test, 'FIM_table_e')): #if write_model: building_test.coeff_out_e.to_csv(report_path + 'bldg_' + str(building_test.bldg_id) + "_Electricity Coeffs_out.csv") #if write_fim: building_test.FIM_table_e.to_csv(report_path + 'bldg_' + str(building_test.bldg_id) + "_Electricity FIM_recommendations.csv") #if (hasattr(building_test, 'FIM_table_f')): #if write_model: building_test.coeff_out_f.to_csv(report_path + 'bldg_' + str(building_test.bldg_id) + "_Fossil Fuel Coeffs_out.csv") #if write_fim: building_test.FIM_table_f.to_csv(report_path + 'bldg_' + str(building_test.bldg_id) + "_Fossil Fuel FIM_recommendations.csv") if r == 1: # Generate static HTML report report_building = report.Report(building=building_test) report_building.generate_building_report_beta(report_path) return True, building_test else: cont = 0
def run_backtest(self): print '\n#################################################' print 'Backtest strategy:', self.strategy_label print '#################################################' print print 'enter_signal: ', self.enter_signal print 'exit_signal : ', self.exit_signal print 'risk_cap : ', self.risk_cap print # -------------------------------------------------------- def update_dictionary(dictionary, indicator_name, indicator_value): try: dictionary[indicator_name] except: dictionary[indicator_name] = time_series.TimeSeries( self.trading_days, []) dictionary[indicator_name].data.append(indicator_value) p_index_accum = 0 p_index_hold_accum = 0 #localtime = time.strftime('%Y%m%d', time.localtime()) localtime = datetime.date.today() self.p_index = {} # dictionary to store all securities that have a signal today self.has_enter_signal = {} self.has_exit_signal = {} self.has_risk_cap_signal = {} # -------------------------------------------------------- for my_security in self.trading_symbols.components.keys(): # shortcut security = self.trading_symbols.components[my_security] # initialize portfolio for strategy (in backtest mode we only deal with one symbol) purchase = 0 self.portfolio = portfolio.Portfolio(float(self.starting_cash), self.trading_start, self.trading_commission) # initialize portfolio for hold self.portfolio_hold = portfolio.Portfolio( float(self.starting_cash), self.trading_start, self.trading_commission) # days when we have data available self.trading_days = [ d for d in self.daterange if d in security.close.times ] # time series used to store when we are in or out of the market self.in_n_out = time_series.TimeSeries(self.trading_days, []) # start with empty dictionaries for the current symbol "my_security" self.performance_index = {} self.charts = {} self.stock_chart = {} self.indicators = {} in_market = False enter_market = False leave_market = False security_had_enter_signal = False # parse 'chart_functions' input string to find out what we should plot chart_sections = string.split(self.chart_functions, ';') chart_panels = {} chart_panels['stock_chart'] = string.split(chart_sections[0], ':') if len(chart_sections) > 1: chart_panels['indicators'] = string.split( chart_sections[1], ':') # begin: loop over trading days for date in self.trading_days: # --------------------------------------------------------- def rsi(exp_m_avg_len): if len(security.close.data) > exp_m_avg_len: ts = security.close.rsi(date, date, exp_m_avg_len) if len(ts.data) > 0: rsi_value = ts.data[0] else: rsi_value = 100 return rsi_value # --------------------------------------------------------- def mfi(m_avg_len): ts = security.close.mfi(security.high, security.low, security.close, security.volume, date, date, m_avg_len) return ts.data[0] # --------------------------------------------------------- def l_b_band(bb_len, num_stdev=2): upper, m_avg, lower = security.close.b_bands( date, date, bb_len, num_stdev) return lower.data[0] # --------------------------------------------------------- def u_b_band(bb_len, num_stdev=2): upper, m_avg, lower = security.close.b_bands( date, date, bb_len, num_stdev) return upper.data[0] # --------------------------------------------------------- def c_b_band(bb_len, num_stdev=2): upper, m_avg, lower = security.close.b_bands( date, date, bb_len, num_stdev) return m_avg.data[0] # --------------------------------------------------------- def fsto_k(periods): low = security.low.low(date, date, periods) high = security.high.high(date, date, periods) fsto_k = 100 if len(low.data) > 0 and len(high.data) > 0: sto = security.close.fsto_k(low, high, date, date, periods) fsto_k = sto.data[0] return fsto_k # --------------------------------------------------------- def fsto_d(periods, m_avg): dstart = datetime.strptime( date, "%Y%M%d") - timedelta(days=periods) #date_start = dstart.strftime("%Y%m%d") print date_start, date, periods low = security.low.low(date_start, date, periods) high = security.high.high(date_start, date, periods) fsto_k = security.close.fsto_k(low, high, date_start, date, periods) fsto_d = fsto_k.m_avg(date, date, m_avg) return fsto_d[0] # --------------------------------------------------------- def close_monotonous_up(symbol_name, range_hist_len): try: my_security = self.trading_symbols.components[ symbol_name] except: print 'Error: Symbol ', symbol_name, ' is not available' return my_security.close.monotonous_up( date, range_hist_len) # --------------------------------------------------------- def close_monotonous_down(symbol_name, range_hist_len): try: my_security = self.trading_symbols.components[ symbol_name] except: print 'Error: Symbol ', symbol_name, ' is not available' return my_security.close.monotonous_down( date, range_hist_len) # --------------------------------------------------------- def mfi_hist_spread(mfi_periods, hist_len): end_index = self.trading_days.index(date) start_index = end_index - hist_len if start_index >= 0: mfi_hist = security.close.mfi( security.high, security.low, security.close, security.volume, self.trading_days[start_index], date, mfi_periods) return mfi_hist.historic_spread(date, hist_len) # --------------------------------------------------------- def close_m_avg_up(my_symbol, m_avg, hist_len): m_avg_symbol = symbol.Symbol(my_symbol, self.trading_days[0], self.trading_days[-1]) end_index = self.trading_days.index(date) start_index = end_index - max([m_avg, hist_len]) if start_index >= 0: close_m_avg = m_avg_symbol.close.m_avg( self.trading_days[start_index], date, m_avg) return close_m_avg.monotonous_up(date, hist_len) # --------------------------------------------------------- def roc(hist_len): end_index = self.trading_days.index(date) start_index = end_index - hist_len if start_index >= 0: return security.close.roc(date, hist_len) # --------------------------------------------------------- def roc_s(my_symbol, hist_len): my_symbol = symbol.Symbol(my_symbol, self.trading_days[0], self.trading_days[-1]) end_index = self.trading_days.index(date) start_index = end_index - hist_len if start_index >= 0: return my_symbol.close.roc(date, hist_len) # --------------------------------------------------------- def d_m_avg(m_avg_len): ts = security.close.derivative_m_avg(date, date, m_avg_len) return ts.data[0] # --------------------------------------------------------- def d_m_avg_s(my_symbol, m_avg_len): start_date = datetime.strptime( self.trading_days[0], "%Y%M%d") - timedelta(days=300) mysymbol = symbol.Symbol(my_symbol, start_date, self.trading_days[-1]) ts = mysymbol.close.derivative_m_avg(date, date, m_avg_len) return ts.data[0] # --------------------------------------------------------- open = security.open.data[security.open.get_index(date)] high = security.high.data[security.high.get_index(date)] low = security.low.data[security.low.get_index(date)] close = security.close.data[security.close.get_index(date)] volume = security.volume.data[security.volume.get_index(date)] if sc.verbose: print date, 'open : ', open print date, 'high : ', high print date, 'low : ', low print date, 'close : ', close print date, 'volume: ', volume # --------------------------------------------------------- # compute market_cap in billions, set mcap to zero if only N/A is given market_cap = security.extra['market_cap'] if market_cap[-1] == 'B': mcap = float(market_cap.strip(market_cap[-1])) elif market_cap[-1] == 'M': mcap = float(market_cap.strip(market_cap[-1])) / 1000.0 else: mcap = 0 transaction_date = date transaction_price = float(open) # --------------------------------------------------------- # portfolio with steady hold if date == self.trading_days[0]: num_shares_hold = int( (float(self.portfolio_hold.cash) - float(self.trading_commission)) / transaction_price) self.portfolio_hold.add_security(security, transaction_price, num_shares_hold, transaction_date) if date == self.trading_days[-1]: self.portfolio_hold.delete_security( security, transaction_price, num_shares_hold, transaction_date) # --------------------------------------------------------- if enter_market: num_shares = int( (float(self.portfolio.cash) - float(self.trading_commission)) / transaction_price) self.portfolio.add_security(security, transaction_price, num_shares, transaction_date) if sc.verbose: self.portfolio.print_holdings(date) in_market = True enter_market = False purchase = float(open) if sc.verbose: print date, 'transaction_price: ', transaction_price # --------------------------------------------------------- if in_market and not leave_market: self.in_n_out.data.append(1) else: self.in_n_out.data.append(0) # --------------------------------------------------------- if leave_market: in_market = False leave_market = False self.portfolio.delete_security(security, transaction_price, num_shares, transaction_date) if sc.verbose: self.portfolio.print_holdings(date) if sc.verbose: print date, 'transaction_price: ', transaction_price # --------------------------------------------------------- if eval(self.enter_signal): security_had_enter_signal = True if not in_market: enter_market = True if sc.verbose: print '%s - %-4s -' % (date, security.symbol) \ + '------------------------> enter signal' # for query mode store securities that have an enter_signal today if localtime == date: signal_msg = '%-4s (%-18s) ' % (security.symbol, security.extra['name']) signal_msg += '- price: ' + security.extra['price'] + \ ' change: ' + security.extra['change'] + \ ' volume: ' + security.extra['volume'] + '\n' self.has_enter_signal[security.symbol] = signal_msg if eval(self.risk_cap): if in_market: leave_market = True if sc.verbose: print '%s - %-4s -' % (date, security.symbol) \ + '------------------------> risk cap. exiting' # for query mode store securities that have an risk_cap_signal today if localtime == date: signal_msg = '%-4s (%-18s) ' % (security.symbol, security.extra['name']) signal_msg += '- price: ' + security.extra['price'] + \ ' change: ' + security.extra['change'] + \ ' volume: ' + security.extra['volume'] + '\n' self.has_risk_cap_signal[security.symbol] = signal_msg if eval(self.exit_signal): if in_market: leave_market = True if sc.verbose: print '%s - %-4s -' % (date, security.symbol) \ + '------------------------> exit signal' # for query mode store securities that have an exit_signal today if localtime == date: signal_msg = '%-4s (%-18s) ' % (security.symbol, security.extra['name']) signal_msg += '- price: ' + security.extra['price'] + \ ' change: ' + security.extra['change'] + \ ' volume: ' + security.extra['volume'] + '\n' self.has_exit_signal[security.symbol] = signal_msg # compute and store chart functions for chart in chart_panels['stock_chart']: update_dictionary(self.stock_chart, chart, eval(chart)) if len(chart_sections) > 1: for chart in chart_panels['indicators']: update_dictionary(self.indicators, chart, eval(chart)) # also store stock_close/stock_open and p_index for all charts update_dictionary(self.stock_chart, 'close', close) update_dictionary(self.stock_chart, 'open', open) performance_index = self.portfolio.evaluate_assets( date) / float(self.starting_cash) update_dictionary(self.performance_index, 'p_index', performance_index) # new chart_functions syntax # chart_sections_new = string.split(self.chart_functions_new, '|') # sindex = 0 # self.plot_panels = {} # for section in chart_sections_new: # sindex += 1 # chart_plots = string.split(section, '%') # for plot in chart_plots: # plot_s = plot.strip(' ') # plot_function = plot_s[0:-2] # update_dictionary(self.plot_panels, str( (sindex, plot_s) ) , eval(plot_function)) # update_dictionary(self.plot_panels, str((0,'p_index:b')), performance_index) # update_dictionary(self.plot_panels, str((1,'close:b')), close) # update_dictionary(self.plot_panels, str((1,'open:b')), open) if sc.verbose: print date, 'performance index:', \ self.performance_index[ 'p_index' ].data[-1] print date, \ 'enter_market:', enter_market, \ 'leave_market:', leave_market, \ 'in_market:', in_market # end: loop over trading days p_index_data = self.performance_index['p_index'].data[-1] p_index = "%5.3f" % p_index_data p_index_accum += p_index_data p_index_hold_data = self.portfolio_hold.evaluate_assets( self.trading_days[-1]) / float(self.starting_cash) p_index_hold = "%5.3f" % p_index_hold_data p_index_hold_accum += p_index_hold_data # --------------------------------------------------------- if self.portfolio.transactions > 0: days_in_market = reduce(lambda x, y: x + y, self.in_n_out.data) trading_days = len(self.trading_days) tp_index = "%6.3f" % (trading_days / days_in_market * (p_index_data - 1.0)) print '%-7s - performance indices: %s / %s / %s - transactions: %s' \ % (security.symbol, p_index, p_index_hold, tp_index, self.portfolio.transactions) self.p_index[security.symbol] = [ self.portfolio.transactions, p_index, p_index_hold, tp_index ] if (security_had_enter_signal or self.always_plot): sym_chart = trading_chart.TradingChart(security, self) filename = security.symbol.ljust(4,'_') + '.' \ + self.strategy_label + '_' + str(p_index) + '.png' sym_chart.savefig(filename) # accumulated performance index # --------------------------------------------------------- print 'accumulated performance index: ', \ p_index_accum/len(self.trading_symbols.components.keys()), ' / ', \ p_index_hold_accum/len(self.trading_symbols.components.keys()) print '\n---------------------[ Top 20 ]---------------------' items = self.p_index.items() #items.sort(key=lambda x: x[1][0], reverse=True) items.sort(key=lambda x: x[1], reverse=True) rank = 0 print 'symbol transactions strategy hold normalized' for key, value in items: rank += 1 if rank <= 20: print '%-7s : %3s %s %s %s' % ( key, value[0], value[1], value[2], value[3])
from dateutil import relativedelta from itertools import islice import time # custom modules import params import portfolio import optimize as op import numpy as np import pandas from cvxopt import matrix # get the portfolio parameters port_params = params.get_portfolio_params(index=10) # instantiate the porfolio object port = portfolio.Portfolio(port_params, proxy={"http": "http://proxy.jpmchase.net:8443"}) dates = port.get_trading_dates() start = datetime(1998, 1, 1) end = datetime(1998, 12, 1) portvalue = port.get_portfolio_historic_position_values() #print port.get_portfolio_historic_position_values().to_string() ''' bench = port.get_benchmark_weights().ix[datetime(1990,02,01)] print print print portvalue = port.get_portfolio_historic_position_values().dropna()
def __init__(self, df, symbols, window_size): self.df = df self.window_size = window_size self.my_portfolio = portfolio.Portfolio(budget, symbols)
import dash_core_components as dcc import dash_html_components as html from dash.dependencies import Input, Output, State import plotly.express as px import pandas as pd import portfolio import datetime import dash_table import csv external_stylesheets = ['https://codepen.io/chridd`yp/pen/bWLwgP.css'] app = dash.Dash(__name__, external_stylesheets=external_stylesheets) port_df = pd.read_csv('my_portfolio.csv') my_portfolio = portfolio.Portfolio() app.layout = html.Div(children=[ html.H1(children='Stock Portfolio'), html.Div(id='flavor_txt', children=[] ), html.Div(id='alo_txt', children=[] ), html.Div(id='ROI', children=[]
def __init__(self): self.fulldf=portfolio.Portfolio() self.portfolio=self.fulldf.getDataFrame()[["PortfolioVal","PnL"]] self.calculateDrawdown()
def test_cash(self): testPortfolio = portfolio.Portfolio() testPortfolio.addCash(1000) testPortfolio.withdrawCash(750) self.assertEqual(250, testPortfolio.cash)
def main(): with open("symbolsPruned", "r", newline="\n") as file: symbols = file.read().strip().split("\n") period = 500 exchange.init(symbols, period=period, historyDays=algorithms.KIPPslowDays) p = portfolio.Portfolio(3000) dataDates = [] dataOpen = [] dataHigh = [] dataLow = [] dataClose = [] dailyProfit = [0] dailyPercent = [0] dailyMovement = [0] for i in range(period): if (i % 5) == 0: p.fund(150) exchange.openMarket() print(exchange.today) dataDates.append(pandas.to_datetime(exchange.today)) dataOpen.append(p.value(time="open")) dataLow.append(p.value(time="low")) algorithms.KIPP(symbols, p) dataClose.append(p.value(time="close")) dataHigh.append(p.value(time="high")) dailyProfit.append(dataClose[-1] - p.investment) dailyMovement.append(dailyProfit[-1] - dailyProfit[-2]) dailyPercent.append((dailyMovement[-1] / p.value()) * 100) print("Closed with movement of ${:5.2f}".format(dailyMovement[-1])) exchange.closeMarket() closeRatio = dataClose[-1] / p.investment percentageYr = math.log(closeRatio) * 252 / period / math.log(2) gains = dataClose[-1] print("Ended with gain of ${:.2f} with ${:.2f} invested at {:.1f}% {:.1f}%(yr)".format( gains, p.investment, (closeRatio - 1) * 100, percentageYr * 100)) data = { "Open": dataOpen, "High": dataHigh, "Low": dataLow, "Close": dataClose} data = pandas.DataFrame(data=data, index=dataDates) mplfinance.plot(data, type='line', mav=(10, 100)) _, (subplot1, subplot2, subplot3) = pyplot.subplots(nrows=3, sharex=True) subplot1.plot(dailyProfit) subplot1.set_title("Profit") subplot1.set_ylabel("$") subplot2.plot(dailyPercent) subplot2.set_title("Percent") subplot2.set_ylabel("%") subplot3.plot(dailyMovement) subplot3.set_title("Daily Movement") subplot3.set_ylabel("$") pyplot.xlabel("Time") pyplot.show()
def testPortfolioWithExpirationManagement(self): """Put on a strangle; update portfolio values, and then manage the strangle when the daysBeforeClosing threshold has been met. """ # Create portfolio object. portfolioObj = portfolio.Portfolio(self.startingCapital, self.maxCapitalToUse, self.maxCapitalToUsePerTrade) # Set up date / time formats. local = pytz.timezone('US/Eastern') # Convert time zone of data 'US/Eastern' to UTC time. expDate = datetime.datetime.strptime("02/20/18", "%m/%d/%y") expDate = local.localize(expDate, is_dst=None) expDate = expDate.astimezone(pytz.utc) # Convert time zone of data 'US/Eastern' to UTC time. curDate = datetime.datetime.strptime("02/02/18", "%m/%d/%y") curDate = local.localize(curDate, is_dst=None) curDate = curDate.astimezone(pytz.utc) # Add first position to the portfolio. putOpt = put.Put('SPX', 2690, 0.15, expDate, underlyingPrice=2786.24, bidPrice=7.45, askPrice=7.45, optionSymbol="01", tradePrice=7.45, dateTime=curDate) callOpt = call.Call('SPX', 2855, -0.15, expDate, underlyingPrice=2786.24, bidPrice=5.20, askPrice=5.20, optionSymbol="02", tradePrice=5.20, dateTime=curDate) # Create Strangle. orderQuantity = 1 daysBeforeClosing = 5 strangleObj = strangle.Strangle(orderQuantity, callOpt, putOpt, "SELL", daysBeforeClosing) # Create signal event. event = signalEvent.SignalEvent() event.createEvent(strangleObj) # Create portfolio onSignal event, which adds the position to the portfolio. portfolioObj.onSignal(event) # Check that the position was added to the portfolio. self.assertEqual(len(portfolioObj.getPositions()), 1) # Change the time to be within five days from the DTE, which should cause the position to be closed / deleted # from the portfolio. curDate = datetime.datetime.strptime("02/19/18", "%m/%d/%y") curDate = local.localize(curDate, is_dst=None) curDate = curDate.astimezone(pytz.utc) newOptionObjs = [] putOpt = put.Put('SPX', 2690, 0.15, expDate, underlyingPrice=2786.24, bidPrice=7.45, askPrice=7.45, optionSymbol="01", tradePrice=7.45, dateTime=curDate) newOptionObjs.append(putOpt) callOpt = call.Call('SPX', 2855, -0.15, expDate, underlyingPrice=2786.24, bidPrice=5.20, askPrice=5.20, optionSymbol="02", tradePrice=5.20, dateTime=curDate) newOptionObjs.append(callOpt) newEvent = tickEvent.TickEvent() newEvent.createEvent(newOptionObjs) portfolioObj.updatePortfolio(newEvent) # Check that the position was managed / deleted from the portfolio. self.assertEqual(len(portfolioObj.getPositions()), 0)
def run(self): global haveKeyring app = appGlobal.getApp() while self.running: self.freshStart = False now = datetime.datetime.now() #print "Check for new stock data at %s" % now.strftime("%Y-%m-%d %H:%M:%S") # Determine the cutoff date for downloading new stock data # If before 7pm EST then go back to 7pm EST of the previous day # Go back by one day until we hit a week day # Then zero out H:M:S cutoffTime = datetime.datetime.utcnow() - datetime.timedelta( hours=5) if cutoffTime.hour < 19: cutoffTime -= datetime.timedelta(days=1) while cutoffTime.weekday() >= 5: cutoffTime -= datetime.timedelta(days=1) cutoffTime = datetime.datetime(cutoffTime.year, cutoffTime.month, cutoffTime.day, 0, 0, 0) # Load all portfolios # Build list of tickers, update stock data names = self.prefs.getPortfolios() tickers = [] max = len(names) tickerPorts = {} ports = {} for name in names: p = portfolio.Portfolio(name) p.readFromDb() ports[name] = p # Auto update if app.prefs.getBackgroundImport() and haveKeyring: # Import once every 20 hours diff = now - app.prefs.getLastBackgroundImport() #print "time since last auto import", diff if diff > datetime.timedelta(hours=20): print "Background import transactions at %s" % now.strftime( "%Y-%m-%d %H:%M:%S") for name, p in ports.items(): if not self.running: break if p.isBrokerage( ) and p.brokerage != "" and p.username != "" and p.account != "": # check for password and brokerage brokerage = app.plugins.getBrokerage(p.brokerage) if not brokerage: continue try: password = keyring.get_password( "Icarra-ofx-" + name, p.username) if not password: continue except: haveKeyring = False continue print "import from", name # Get ofx data, update if not empty # It may be an error string, in which case it's ignored ofx = getOfx(p.username, password, brokerage, p.account) if ofx != "": (numNew, numOld, newTickers) = p.updateFromFile(ofx, app) if numNew > 0 or newTickers: p.portPrefs.setDirty(True) print "imported" # Update time only if not aborted if self.running: app.prefs.setLastBackgroundImport() # Build list of tickers for name, p in ports.items(): pTickers = p.getTickers(includeAllocation=True) for ticker in pTickers: if ticker in ["__CASH__", "__COBMINED__"]: continue # Add to tickerPorts map if ticker in tickerPorts: tickerPorts[ticker].append(p) else: tickerPorts[ticker] = [p] # Add to list of tickers if not ticker in tickers: tickers.append(ticker) # Remove tickers that do not need to be updated for ticker in tickers[:]: # Check if we do not have data after the cutoffTime last = self.stockData.getLastDate(ticker) if 0 and last and last >= cutoffTime: tickers.remove(ticker) continue # Check if we tried downloading within one hour lastDownload = self.stockData.getLastDownload(ticker) if lastDownload and datetime.datetime.now( ) - lastDownload < datetime.timedelta(hours=1): tickers.remove(ticker) continue portsToUpdate = {} self.tickersToImport = len(tickers) # Lump all tickers that are less than 2 weeks old into one request updateNow = [] for ticker in tickers[:]: lastDownload = self.stockData.getLastDownload(ticker) if lastDownload and datetime.datetime.now( ) - lastDownload < datetime.timedelta(days=14): updateNow.append(ticker) tickers.remove(ticker) continue # Download the 2 week lump 10 tickers at a time while updateNow and self.running: downloadPart = updateNow[0:10] updateNow = updateNow[10:] try: new = self.stockData.updateStocks(downloadPart) appGlobal.setConnected(True) except Exception, e: print traceback.format_exc() appGlobal.setFailConnected(True) return for ticker in downloadPart: self.tickerCount += 1 if new: for p in tickerPorts[ticker]: portsToUpdate[p.name] = True # Update each remaining ticker while still running for ticker in tickers: if self.running: try: new = self.stockData.updateStocks([ticker]) appGlobal.setConnected(True) except Exception, e: print traceback.format_exc() appGlobal.setFailConnected(True) return if new: for p in tickerPorts[ticker]: # Add 3 for every port if not p.name in portsToUpdate: if app.prefs.getBackgroundRebuild(): self.tickersToImport += 3 portsToUpdate[p.name] = True self.tickerCount += 1
def testPortfolioPositionRemoveManagement(self): """Test that we can remove a managed position from the portfolio without affecting any of the other positions in the portfolio. """ # Create portfolio object. portfolioObj = portfolio.Portfolio(self.startingCapital, self.maxCapitalToUse, self.maxCapitalToUsePerTrade) # Add first position to the portfolio. putOpt = put.Put('SPX', 2690, 0.15, 34, underlyingPrice=2786.24, bidPrice=7.45, askPrice=7.45, optionSymbol="01", tradePrice=7.45) callOpt = call.Call('SPX', 2855, -0.15, 34, underlyingPrice=2786.24, bidPrice=5.20, askPrice=5.20, optionSymbol="02", tradePrice=5.20) # Create Strangle. orderQuantity = 1 profitTargetPercent = 0.5 strangleObj = strangle.Strangle( orderQuantity, callOpt, putOpt, "SELL", profitTargetPercent=profitTargetPercent) # Create signal event. event = signalEvent.SignalEvent() event.createEvent(strangleObj) # Create portfolio onSignal event, which adds the position to the portfolio. portfolioObj.onSignal(event) # Add second position to the portfolio. putOpt = put.Put('AAPL', 140, 0.15, 34, underlyingPrice=150, bidPrice=5.15, askPrice=5.15, optionSymbol="03", tradePrice=5.15) callOpt = call.Call('APPL', 160, -0.15, 34, underlyingPrice=150, bidPrice=3.20, askPrice=3.20, optionSymbol="04", tradePrice=3.20) strangleObj = strangle.Strangle( orderQuantity, callOpt, putOpt, "SELL", profitTargetPercent=profitTargetPercent) # Create signal event. event = signalEvent.SignalEvent() event.createEvent(strangleObj) # Create portfolio onSignal event, which adds the position to the portfolio. portfolioObj.onSignal(event) # Add a third position to the portfolio. putOpt = put.Put('SPY', 240, 0.15, 34, underlyingPrice=280, bidPrice=4.15, askPrice=4.15, optionSymbol="05", tradePrice=4.15) callOpt = call.Call('SPY', 300, -0.15, 34, underlyingPrice=280, bidPrice=2.20, askPrice=2.20, optionSymbol="06", tradePrice=2.20) strangleObj = strangle.Strangle( orderQuantity, callOpt, putOpt, "SELL", profitTargetPercent=profitTargetPercent) # Create signal event. event = signalEvent.SignalEvent() event.createEvent(strangleObj) # Create portfolio onSignal event, which adds the position to the portfolio. portfolioObj.onSignal(event) # For the second position in the portfolio, make the option prices less than 50% of the trade price, which # should cause the position to be closed / deleted from the portfolio. newOptionObjs = [] putOpt = put.Put('SPX', 2690, 0.15, 34, underlyingPrice=2786.24, bidPrice=7.45, askPrice=7.45, optionSymbol="01", tradePrice=7.45) newOptionObjs.append(putOpt) callOpt = call.Call('SPX', 2855, -0.15, 34, underlyingPrice=2786.24, bidPrice=5.20, askPrice=5.20, optionSymbol="02", tradePrice=5.20) newOptionObjs.append(callOpt) putOpt = put.Put('AAPL', 140, 0.15, 34, underlyingPrice=150, bidPrice=2.15, askPrice=2.15, optionSymbol="03") newOptionObjs.append(putOpt) callOpt = call.Call('APPL', 160, -0.15, 34, underlyingPrice=150, bidPrice=1.20, askPrice=1.20, optionSymbol="04") newOptionObjs.append(callOpt) putOpt = put.Put('SPY', 240, 0.15, 34, underlyingPrice=280, bidPrice=4.15, askPrice=4.15, optionSymbol="05", tradePrice=4.15) newOptionObjs.append(putOpt) callOpt = call.Call('SPY', 300, -0.15, 34, underlyingPrice=280, bidPrice=2.20, askPrice=2.20, optionSymbol="06", tradePrice=2.20) newOptionObjs.append(callOpt) newEvent = tickEvent.TickEvent() newEvent.createEvent(newOptionObjs) portfolioObj.updatePortfolio(newEvent) # Check that the first position is the SPX position, and the second position is the SPY position, i.e., the # AAPL position should have been managed / removed. positions = portfolioObj.getPositions() callPos0 = positions[0].getCallOption() callPos1 = positions[1].getCallOption() self.assertEqual(callPos0.getUnderlyingTicker(), 'SPX') self.assertEqual(callPos1.getUnderlyingTicker(), 'SPY') self.assertEqual(len(positions), 2)
def main(): df = pd.read_csv(open('./test/transtest.csv'), comment="***") bought_filter = lambda x: str(x).startswith("Bought") sold_filter = lambda x: str(x).startswith("Sold") boughts = df['DESCRIPTION'].map(bought_filter) solds = df['DESCRIPTION'].map(sold_filter) # Allow the fees to be summed by replacing nans with 0.0s fee_cols = ["COMMISSION", "REG FEE"] for col in fee_cols: df[col].replace(np.nan, 0.0) dff = df[(boughts) | (solds)] port = portfolio.Portfolio(name="TD Ameritrade - BMP") # Loop through each Symbol as a holding symbs = np.asarray(dff['SYMBOL'].unique(), dtype='S50') for symb in symbs: # Filter for current symbol dff_symb = dff[dff['SYMBOL'] == symb] hld = portfolio.Holding() # Populate a holding with all positions for tran in dff_symb.iterrows(): tran_data = tran[1] if tran_data['DESCRIPTION'].startswith("Bought"): side = "BUY" elif tran_data['DESCRIPTION'].startswith("Sold"): side = "SELL" else: side = "UNKNOWN" p = position.Position(symbol=tran_data['SYMBOL'], id=tran_data['TRANSACTION ID'], description=tran_data['DESCRIPTION'], trans_date=tran_data['DATE'], qty=tran_data['QUANTITY'], price=tran_data['PRICE'], fee=tran_data['COMMISSION'] + tran_data['REG FEE'], total_amt=tran_data['AMOUNT'], side=side) if side == "BUY": print "Adding %s to Portfolio" % p hld.add_to(p) elif side == "SELL" and hasattr(hld, "positions"): print "Removing %s from Portfolio" % p hld.remove_from(p) else: print "Adding short position %s to Portfolio" % p hld.add_to(p) port.add_holding(hld) port.pprint() #if tran['DESCRIPTION'].startswith("Bought") # port.add_to(Position(transaction[''])) return port
import portfolio starting_cash = 10000 start_date = "2019-01-01" end_date = "2019-06-01" tradeable_sercurities = [] stategy = "" myportolio = portfolio.Portfolio(starting_cash)