def check_analysis(self, name, start_date, end_date, symbols, v_cr, v_adr, v_sddr, v_sr, v_allocs): print name allocs, cr, adr, sddr, sr = optimize_portfolio(sd=start_date, ed=end_date, syms=symbols, gen_plot=False) np.testing.assert_almost_equal([v_cr, v_adr, v_sddr, v_sr], [cr, adr, sddr, sr], 5) np.testing.assert_almost_equal(v_allocs, allocs, 5) print allocs print sr
def _run_test(self, params, results): start_date = params['start_date'] end_date = params['end_date'] symbols = params['symbols'] allocations, \ cumulative_return, \ average_daily_return, \ volatility, \ sharpe_ratio = optimization.optimize_portfolio(sd=start_date, ed=end_date, syms=symbols, gen_plot=False) self.assertAlmostEqual(np.sum(allocations), 1.0, delta=1e-8, msg="Allocations do not sum to 1.0") self.assertTrue(np.allclose(allocations, results['allocations']), msg="Incorrect allocations {}, expected to be {}".format(allocations, results['allocations'])) self.assertAlmostEqual(cumulative_return, results['cumulative_return'], delta=1e-5, msg="Incorrect cumulative return {}, expected to be {}".format( cumulative_return, results['cumulative_return'])) self.assertAlmostEqual(average_daily_return, results['average_daily_return'], delta=1e-5, msg="Incorrect avg. daily return {}, expected to be {}".format( average_daily_return, results['average_daily_return'])) self.assertAlmostEqual(volatility, results['volatility'], delta=1e-5, msg="Incorrect volatility {}, expected to be {}".format( volatility, results['volatility'])) self.assertAlmostEqual(sharpe_ratio, results['sharpe_ratio'], delta=1e-5, msg="Incorrect sharpe ratio {}, expected to be {}".format( sharpe_ratio, results['sharpe_ratio']))
def test_example1(self): start_date = dt.datetime(2010,01,01) end_date = dt.datetime(2010,12,31) symbols = ['GOOG', 'AAPL', 'GLD', 'XOM'] start_val = 1000000 risk_free_rate = 0.0 sample_freq = 252.0 # Assess the portfolio allocations, cr, adr, sddr, sr = o.optimize_portfolio(sd = start_date, ed = end_date, syms = symbols, gen_plot = False) self.assertAlmostEqual(0.360090826885, cr, 3, "Cumulative Return {} is incorrect".format(cr), delta=None) self.assertAlmostEqual(2.00401501102, sr, 3, "Sharpe Ratio {} is incorrect".format(sr), delta=None) self.assertAlmostEqual(0.00127710312803, adr, 5, "Avg Daily Return {} is incorrect".format(adr), delta=None) self.assertAlmostEqual(0.0101163831312, sddr, 5, "Volatility (stdev of daily returns) {} is incorrect".format(sddr), delta=None)
def test_example4(self): start_date = dt.datetime(2005,12,01) end_date = dt.datetime(2006,05,31) symbols = ['YHOO', 'HPQ', 'GLD', 'HNZ'] start_val = 1000000 risk_free_rate = 0.0 sample_freq = 252.0 # Assess the portfolio allocations, cr, adr, sddr, sr = o.optimize_portfolio(sd = start_date, ed = end_date, syms = symbols, gen_plot = False) self.assertAlmostEqual(0.229471589743, cr, 3, "Cumulative Return {} is incorrect".format(cr), delta=None) self.assertAlmostEqual(3.2334265871, sr, 3, "Sharpe Ratio {} is incorrect".format(sr), delta=None) self.assertAlmostEqual(0.00171589132005, adr, 5, "Avg Daily Return {} is incorrect".format(adr), delta=None) self.assertAlmostEqual(0.00842416845541, sddr, 5, "Volatility (stdev of daily returns) {} is incorrect".format(sddr), delta=None)
def test_example3(self): start_date = dt.datetime(2004,12,01) end_date = dt.datetime(2006,05,31) symbols = ['YHOO', 'XOM', 'GLD', 'HNZ'] start_val = 1000000 risk_free_rate = 0.0 sample_freq = 252.0 # Assess the portfolio allocations, cr, adr, sddr, sr = o.optimize_portfolio(sd = start_date, ed = end_date, syms = symbols, gen_plot = False) self.assertAlmostEqual(0.315973959221, cr, 3, "Cumulative Return {} is incorrect".format(cr), delta=None) self.assertAlmostEqual(1.5178365773, sr, 3, "Sharpe Ratio {} is incorrect".format(sr), delta=None) self.assertAlmostEqual(0.000762170576913, adr, 5, "Avg Daily Return {} is incorrect".format(adr), delta=None) self.assertAlmostEqual(0.00797126844855, sddr, 5, "Volatility (stdev of daily returns) {} is incorrect".format(sddr), delta=None)
def test_example2(self): start_date = dt.datetime(2004,01,01) end_date = dt.datetime(2006,01,01) symbols = ['AXP', 'HPQ', 'IBM', 'HNZ'] start_val = 1000000 risk_free_rate = 0.0 sample_freq = 252.0 # Assess the portfolio allocations, cr, adr, sddr, sr = o.optimize_portfolio(sd = start_date, ed = end_date, syms = symbols, gen_plot = False) self.assertAlmostEqual(0.255021425162, cr, 3, "Cumulative Return {} is incorrect".format(cr), delta=None) self.assertAlmostEqual(0.842697383626, sr, 3, "Sharpe Ratio {} is incorrect".format(sr), delta=None) self.assertAlmostEqual(0.000494944887734, adr, 5, "Avg Daily Return {} is incorrect".format(adr), delta=None) self.assertAlmostEqual(0.0093236393828, sddr, 5, "Volatility (stdev of daily returns) {} is incorrect".format(sddr), delta=None)
def test_example3(self): start_date = dt.datetime(2004, 12, 01) end_date = dt.datetime(2006, 05, 31) symbols = ['YHOO', 'XOM', 'GLD', 'HNZ'] start_val = 1000000 risk_free_rate = 0.0 sample_freq = 252.0 # Assess the portfolio allocations, cr, adr, sddr, sr = o.optimize_portfolio(sd=start_date, ed=end_date, syms=symbols, gen_plot=False) self.assertAlmostEqual(0.315973959221, cr, 3, "Cumulative Return {} is incorrect".format(cr), delta=None) self.assertAlmostEqual(1.5178365773, sr, 3, "Sharpe Ratio {} is incorrect".format(sr), delta=None) self.assertAlmostEqual(0.000762170576913, adr, 5, "Avg Daily Return {} is incorrect".format(adr), delta=None) self.assertAlmostEqual( 0.00797126844855, sddr, 5, "Volatility (stdev of daily returns) {} is incorrect".format(sddr), delta=None)
def test_example1(self): start_date = dt.datetime(2010, 01, 01) end_date = dt.datetime(2010, 12, 31) symbols = ['GOOG', 'AAPL', 'GLD', 'XOM'] start_val = 1000000 risk_free_rate = 0.0 sample_freq = 252.0 # Assess the portfolio allocations, cr, adr, sddr, sr = o.optimize_portfolio(sd=start_date, ed=end_date, syms=symbols, gen_plot=False) self.assertAlmostEqual(0.360090826885, cr, 3, "Cumulative Return {} is incorrect".format(cr), delta=None) self.assertAlmostEqual(2.00401501102, sr, 3, "Sharpe Ratio {} is incorrect".format(sr), delta=None) self.assertAlmostEqual(0.00127710312803, adr, 5, "Avg Daily Return {} is incorrect".format(adr), delta=None) self.assertAlmostEqual( 0.0101163831312, sddr, 5, "Volatility (stdev of daily returns) {} is incorrect".format(sddr), delta=None)
def test_example2(self): start_date = dt.datetime(2004, 01, 01) end_date = dt.datetime(2006, 01, 01) symbols = ['AXP', 'HPQ', 'IBM', 'HNZ'] start_val = 1000000 risk_free_rate = 0.0 sample_freq = 252.0 # Assess the portfolio allocations, cr, adr, sddr, sr = o.optimize_portfolio(sd=start_date, ed=end_date, syms=symbols, gen_plot=False) self.assertAlmostEqual(0.255021425162, cr, 3, "Cumulative Return {} is incorrect".format(cr), delta=None) self.assertAlmostEqual(0.842697383626, sr, 3, "Sharpe Ratio {} is incorrect".format(sr), delta=None) self.assertAlmostEqual(0.000494944887734, adr, 5, "Avg Daily Return {} is incorrect".format(adr), delta=None) self.assertAlmostEqual( 0.0093236393828, sddr, 5, "Volatility (stdev of daily returns) {} is incorrect".format(sddr), delta=None)
def test_example4(self): start_date = dt.datetime(2005, 12, 01) end_date = dt.datetime(2006, 05, 31) symbols = ['YHOO', 'HPQ', 'GLD', 'HNZ'] start_val = 1000000 risk_free_rate = 0.0 sample_freq = 252.0 # Assess the portfolio allocations, cr, adr, sddr, sr = o.optimize_portfolio(sd=start_date, ed=end_date, syms=symbols, gen_plot=False) self.assertAlmostEqual(0.229471589743, cr, 3, "Cumulative Return {} is incorrect".format(cr), delta=None) self.assertAlmostEqual(3.2334265871, sr, 3, "Sharpe Ratio {} is incorrect".format(sr), delta=None) self.assertAlmostEqual(0.00171589132005, adr, 5, "Avg Daily Return {} is incorrect".format(adr), delta=None) self.assertAlmostEqual( 0.00842416845541, sddr, 5, "Volatility (stdev of daily returns) {} is incorrect".format(sddr), delta=None)
sma_bb_ratio = np.array( OSEBX.get_sma_bb_ratios(promising_stocks) ) #np.concatenate((OSEBX.get_sma_bb_ratios(requested_stocks), np.zeros((1,6))[0]))# # Get historic stock covariances cov_matrix = OSEBX.get_stock_covariances(returns) # filter = OSEBX.filter(requested_stocks, [stock for stock, prob in promising_stocks]) # Generate optimization problem P, q, G, h, A, b, means, stds = opt.generate_ProblemMatrices( returns, cov_matrix, sma_bb_ratio, rho, phi, kappa) # Solve optimization problem optimized_portfolio = opt.optimize_portfolio(OSEBX, promising_stocks, P, q, G, h, A, b, means, stds, sma_bb_ratio, mu) stock_algorithms.trade(OSEBX, my_portfolio, optimized_portfolio, 'historic', run_no) # OSEBX.fetch_benchmark(run_no) # if run_no == 10 or run_no == 20 or run_no == 30 or run_no == 40: plot(my_portfolio.earnings, OSEBX.benchmark, run_no) # # run_no += 1 # OSEBX.fetch_stock_data(requested_stocks, run_no, 'historic', N) #
def _run_test(self, params, results): # the margins below are taken from grade_optimization.py abs_margins = dict( sum_to_one=0.02, alloc_range=0.02, alloc_match=0.1, sddr_match=0.05) # absolute margin of error for each component start_date = params['start_date'] end_date = params['end_date'] symbols = params['symbols'] start_time = time() allocations, \ cumulative_return, \ average_daily_return, \ volatility, \ sharpe_ratio = optimization.optimize_portfolio(sd=start_date, ed=end_date, syms=symbols, gen_plot=False) end_time = time() function_runtime = end_time - start_time # check runtime < 5 seconds # ======================================= self.assertLessEqual( function_runtime, 5, msg="Runtime violation, expected < 5.0s, runtime was {:1.3f} s". format(end_time - start_time)) # check volatility # ======================================= self.assertLessEqual( (volatility / results['volatility']) - 1, abs_margins['sddr_match'], msg="Sddr too large: {:1.6f} (expected < {:1.6f} + {:1.6f})". format(volatility, results['volatility'], results['volatility'] * abs_margins['sddr_match'])) # check that sddr is not significantly less than expected, this would be the case if the student answers are # wrong or you are calculating sddr incorrectly. OR you found a global minimum below what other students have # ======================================= # Note I was able to slightly beat the grade_optimization.py volatility slightly using a nifty trick so I # created results "min_student_volatility" as well to capture this. The testcase below will error if you beat # either the latest students volatility, if provided, or the benchmark volatility if there it is not a testcase # from the grade_optimization.py test_volatility = results['volatility'] if 'min_student_volatility' in results: test_volatility = results['min_student_volatility'] self.assertGreaterEqual( volatility + 1e-8, # add small delta to account for floating point errors test_volatility, msg= "WARNING: your Volatility {} is less than the expected minimum {}, Verify your code and notify your classmates on Reddit" .format(volatility, test_volatility)) # check allocation sum is ~1.0 # ======================================= self.assertLessEqual( abs(sum(allocations) - 1), abs_margins['sum_to_one'], msg="sum of allocations: {:1.5f} (expected: 1.0)".format( sum(allocations))) # check allocations are within tolerance # ======================================= # This loops through each symbol and errors if the allocation is out range for symbol, alloc in zip(symbols, allocations): self.assertLessEqual( alloc, 1 + abs_margins['alloc_range'], msg="{} - allocation out of range: {:1.5f} (expected [0.0, 1.0)" .format(symbol, alloc)) self.assertGreaterEqual( alloc, -1 * abs_margins['alloc_range'], msg="{} - allocation out of range: {:1.5f} (expected [0.0, 1.0)" .format(symbol, alloc))
def t_generator(*args, **kwargs): def t(self): self.assertAlmostEqual(*args, **kwargs) return t def range_generator(value): def t(self): self.assertGreaterEqual(value, -0.02) self.assertLessEqual(value, 1.02) return t for name, test in tests.iteritems(): allocations, cr, adr, sddr, sr = opt.optimize_portfolio( sd = test['args']['start_date'], ed = test['args']['end_date'], syms = test['args']['symbols'], gen_plot = False, ) t = t_generator(cr, test['results']['cumulative_return'], places=4) setattr(TestMCP2, "test_{0}_cumulative_return".format(name), t) t = t_generator(adr, test['results']['adr'], places=4) setattr(TestMCP2, "test_{0}_adr".format(name), t) t = t_generator(sddr, test['results']['volatility'], places=4) setattr(TestMCP2, "test_{0}_volatility".format(name), t) t = t_generator(sr, test['results']['sharpe'], places=4) setattr(TestMCP2, "test_{0}_sharpe_ratio".format(name), t)
def portfolio_page(): if request.method=='GET': return render_template('portfolio.html') else: app_quantfy.vars={} # This is a dictionary # Define the variables. This is a local variable, but in Flask it will be passed to the plot route I guess app_quantfy.vars['sym'] = request.form['sym'].upper().strip(';').split(';') # 'sym' should be defined in html file as name if (app_quantfy.vars['sym'][0]=='') : # sym is a list delimited by ; return render_template('portfolio.html',error_sym='<font size="3" color="red" > Provide at least one ticker symbol </font>') if len(request.form['start_date'])!=0: # Here start and end date are keys are coming even if they are empty try: app_quantfy.vars['start_date']=dt.datetime.strptime(request.form['start_date'],'%m/%d/%Y') except ValueError: return render_template('portfolio.html',error_start_date='<font size="3" color="red" > Wrong date format </font>') else: # Take 1 years ago of the current date app_quantfy.vars['start_date']=dt.datetime.today()-dt.timedelta(days=365) # This does not give the accurate 5 years if len(request.form['end_date'])!=0: try: app_quantfy.vars['end_date']=dt.datetime.strptime(request.form['end_date'],'%m/%d/%Y') except ValueError: return render_template('portfolio.html',error_end_date='<font size="3" color="red" > Wrong date format </font>') else: # Take today as the default date app_quantfy.vars['end_date']=dt.datetime.today() #print app_quantfy.vars if 'bench_sym' in request.form: app_quantfy.vars['bench_sym']=request.form['bench_sym'] else: app_quantfy.vars['bench_sym']='SPY' symbols=list(app_quantfy.vars['sym']); # Create a new list as we are doing insert operation next symbols.insert(0,app_quantfy.vars['bench_sym']); # Insert the default symbol in the symbols list # Here just get the data for the 'Adj. Close' full_data=[(sym, apicall_data.get_data_from_quandl(symbol=sym, features=['Adj. Close'], start_dt=app_quantfy.vars['start_date'],end_dt=app_quantfy.vars['end_date']) ) for sym in symbols] # Convert this to required format df_all_sym=util.get_data(full_data) app_quantfy.vars['guess_alloc']=request.form['guess_alloc'].strip(';').split(';') app_quantfy.vars['start_value']=float(request.form['start_value']); # It has a default value if len(app_quantfy.vars['guess_alloc']) !=0 and (app_quantfy.vars['guess_alloc'][0]!='') : # app_quantfy.vars['guess_alloc'] is a list because of the strip function # print app_quantfy.vars['guess_alloc'] # print len(app_quantfy.vars['guess_alloc']) app_quantfy.vars['guess_alloc']=[float(i) for i in app_quantfy.vars['guess_alloc']] try: assert len(app_quantfy.vars['guess_alloc'])==len(app_quantfy.vars['sym']) except AssertionError: return render_template('portfolio.html',error_alloc='<font size="3" color="red" > Number of allocations should be same as symbols </font>') # Sum should be equal to one print app_quantfy.vars['guess_alloc'] try: assert abs(sum(app_quantfy.vars['guess_alloc'])-1.0)<=1e-5 # Sometimes the rounding does not work correctly except AssertionError: return render_template('portfolio.html',error_alloc='<font size="3" color="red" > Sum should be 1 </font>') else: # Generate random numbers allocs=np.random.random(len(app_quantfy.vars['sym'])) allocs /=allocs.sum() app_quantfy.vars['guess_alloc']=allocs #print allocs cr,adr,sddr,sr,ev,normalized_plot_df=optimization.access_portfolio(df_all_sym, app_quantfy.vars['bench_sym'], app_quantfy.vars['guess_alloc'], sv=app_quantfy.vars['start_value']) #print cr,adr,sddr,sr,ev param_not_opt=pd.DataFrame([cr,adr,sddr,sr,ev],index=['Cumulative Return','Average Daily Return','Stand. Deviation Daily return', 'Sharpe Ratio','End value'], columns=['Unoptimized']) script_not_opt_table,div_not_opt_table=convert_pd_bokeh_html(param_not_opt) # print normalized_plot_df.head() hover=HoverTool( tooltips=[ ("Portfolio",'$y') ] ) TOOLS='pan,wheel_zoom,box_zoom,reset,save,box_select,crosshair' not_opt_p = figure(width=900, height=500, x_axis_type="datetime",tools=[TOOLS,hover]) colors=['blue','red','green','#cc3300'] for (i,ftr) in enumerate(normalized_plot_df): not_opt_p.line(normalized_plot_df.index,normalized_plot_df[ftr],legend=ftr,color=colors[i],line_width=2) #not_opt_p.line(normalized_plot_df) not_opt_p.title.text = "Un-optimized portfolio" not_opt_p.legend.location = "top_left" not_opt_p.xaxis.axis_label = 'Date' not_opt_p.yaxis.axis_label = 'Relative portfolio value' tab_not_opt=Panel(child=not_opt_p,title='Un-optimized portfolio') # script_not_opt, div_not_opt=components(not_opt_p) # print script_not_opt,div_not_opt # Now run optimized cr,adr,sddr,sr,ev,normalized_plot_df,optimal_alloc=optimization.optimize_portfolio(df_all_sym,app_quantfy.vars['bench_sym'], app_quantfy.vars['start_value']) # print cr,adr,sddr,sr,ev,optimal_alloc # print normalized_plot_df.head() hover=HoverTool( tooltips=[ ("Portfolio",'$y') ] ) opt_p = figure(width=900, height=500, x_axis_type="datetime",tools=[TOOLS,hover]) for (i,ftr) in enumerate(normalized_plot_df): opt_p.line(normalized_plot_df.index,normalized_plot_df[ftr],legend=ftr,color=colors[i],line_width=2) # print normalized_plot_df opt_p.title.text = "Optimized portfolio value" opt_p.legend.location = "top_left" opt_p.xaxis.axis_label = 'Date' opt_p.yaxis.axis_label = 'Relative portfolio value' tab_opt=Panel(child=opt_p,title='Optimized portfolio') tabs=Tabs(tabs=[tab_not_opt,tab_opt]) script_opt, div_opt=components(tabs) param_opt=pd.DataFrame([cr,adr,sddr,sr,ev],index=['Cummulative Return','Additive Daily Return','Stand. Deviation Daily return', 'Sharpe Ratio','End value'], columns=['Optimized']) all_params=param_not_opt.join(param_opt) script_opt_table,div_opt_table=convert_pd_bokeh_html(all_params) alloc_df=pd.DataFrame([app_quantfy.vars['guess_alloc'],list(optimal_alloc)],index=['Random/Guess allocations','Optimized allocations'],columns=app_quantfy.vars['sym']) #str_opt_alloc='Optimal allocations: '+', '.join([str(i) for i in optimal_alloc]) script_alloc_df,div_alloc_df=convert_pd_bokeh_html(alloc_df) # script_not_opt_table=script_not_opt_table,div_not_opt_table=div_not_opt_table, return render_template('portfolio.html',script_opt_table=script_opt_table, div_opt_table=div_opt_table, script_alloc_df=script_alloc_df,div_alloc_df=div_alloc_df, script_opt=script_opt,plot_opt=div_opt )
return t def range_generator(value): def t(self): self.assertGreaterEqual(value, -0.02) self.assertLessEqual(value, 1.02) return t for name, test in tests.iteritems(): allocations, cr, adr, sddr, sr = opt.optimize_portfolio( sd=test['args']['start_date'], ed=test['args']['end_date'], syms=test['args']['symbols'], gen_plot=False, ) t = t_generator(cr, test['results']['cumulative_return'], places=4) setattr(TestMCP2, "test_{0}_cumulative_return".format(name), t) t = t_generator(adr, test['results']['adr'], places=4) setattr(TestMCP2, "test_{0}_adr".format(name), t) t = t_generator(sddr, test['results']['volatility'], places=4) setattr(TestMCP2, "test_{0}_volatility".format(name), t) t = t_generator(sr, test['results']['sharpe'], places=4) setattr(TestMCP2, "test_{0}_sharpe_ratio".format(name), t)