def simulate_accumulation(series, portfolio=(0, 0), years=35, annual_inflow=25000, accumulation=N_80_RebalanceAccumulation): portfolio = Portfolio(portfolio[0], portfolio[1]) strategy = accumulation(portfolio).accumulate() strategy.send(None) annual = [] for _, change in zip(range(years), series): gains, _, _ = portfolio.adjust_returns(change) strategy.send(annual_inflow) annual.append(YearlyResults( returns = gains, withdraw_n = 0, withdraw_r = 0, withdraw_pct_cur = 0, withdraw_pct_orig = 0, portfolio_n = portfolio.value, portfolio_r = portfolio.real_value, portfolio_bonds = portfolio.bonds, portfolio_stocks = portfolio.stocks )) annual_inflow *= 1 + change.inflation return annual
def test_generate_trace_calculates_holdings_as_of_start_to_sum_to_a_million(self): portfolio = Portfolio([ ("BACK.L", 40), ("BACS.L", 60), ]) start_date = datetime(2016, 1, 1) end_date = datetime(2016, 1, 4) ticker1_price = 1 ticker1_frame = pd.DataFrame({ "Close": pd.Series( [ ticker1_price, 1.01, ], index=[ datetime(2016, 1, 1), datetime(2016, 1, 2), ] ) }) ticker2_price = 2 ticker2_frame = pd.DataFrame({ "Close": pd.Series( [ 2.1, ticker2_price, ], index=[ datetime(2015, 12, 31), datetime(2016, 1, 1), ] ) }) market_data = { "BACK.L": ticker1_frame, "BACS.L": ticker2_frame, } trace = portfolio.trace(market_data, start_date, end_date) expected_ticker1_holding = (10000 / ticker1_price) * 40 expected_ticker2_holding = (10000 / ticker2_price) * 60 self.assertEqual( trace.holdings, [ ("BACK.L", expected_ticker1_holding), ("BACS.L", expected_ticker2_holding), ] ) ticker1_value = expected_ticker1_holding * ticker1_price ticker2_value = expected_ticker2_holding * ticker2_price total_value = ticker1_value + ticker2_value self.assertEqual(total_value, 1000000) self.assertEqual(ticker1_value / total_value, 0.4) self.assertEqual(ticker2_value / total_value, 0.6)
def create_app(): app = Portfolio({ 'redis_host': redis_set["redis_host"], 'redis_port': redis_set["redis_port"] }) if with_static: app.wsgi_app = SharedDataMiddleware(app.wsgi_app, { '/static': os.path.join(os.path.dirname(__file__), 'static') }) return app
def __init__(self,commission=0.002,price_type='close',short=False,begin_equity=1000000,date="2015-11-01",output=True ): ''' Initializing the broker class :param commission: commission fee, default 0.002 :param price_type: vwap or close price or open price or other choices(close*0.5+open*0.5) :param short: True or False, True if shorting is allowed ''' # set default parameters self.commission = commission self.price = price_type self.short = short self.output = output # self.port = Portfolio(begin_equity=begin_equity, commission=commission) self.order_list = [] self.order_count = 0 self.trading_data = pd.DataFrame() self.trade_info = {} # two checking triggers self.execute_trigger = False self.update_trigger = False # daily recorder self.trade_amount = 0.0 self.trade_cost = 0.0 self.date = date # log self.trade_log = {}
def setUp(self): base = "GBP" leverage = 20 equity = Decimal("100000.00") risk_per_trade = Decimal("0.02") ticker = {} events = {} self.port = Portfolio( ticker, events, base=base, leverage=leverage, equity=equity, risk_per_trade=risk_per_trade )
def setUp(self): home_currency = "GBP" leverage = 20 equity = Decimal("100000.00") risk_per_trade = Decimal("0.02") ticker = TickerMock() events = {} self.port = Portfolio( ticker, events, home_currency=home_currency, leverage=leverage, equity=equity, risk_per_trade=risk_per_trade )
def read_portfolio(filename, **opts): ''' Read a stock portfolio file into a list of dictionaries with keys name, shares, and price. ''' with open(filename) as lines: portdicts = fileparse.parse_csv(lines, select=['name','shares','price'], types=[str,int,float], **opts) portfolio = [ Stock(**d) for d in portdicts ] return Portfolio(portfolio)
def test_buy_fail(self): p = Portfolio(balance=13.0) p.update(ticker='TICK', price=12.3) p.set_shares('TICK', 3.0) cont = Controller(p) success = cont.process_receipt(('TICK', 11.0, 2.0, 10.0)) self.assertFalse(success) # Trade failed
def portfolio_ticker_selection(): ticker_change = Portfolio() # Get temporary data from portfolio backend json ticker_change.update_backend_excel() # Get the Technical Analysis chart already made for the selected ticker ticker_change.get_ta_chart(bool_update=False)
def check_area_ytp(pickle_name): data = load(pickle_name) n_years = 15 house_cost = data.loc[0].value appreciation = 3.0 n_months = n_years * 12 dates = pd.date_range(data.loc[0].date, periods=n_months, freq="M") rent = Revenue("rent", "monthly payment", 0.011 * house_cost) # costs utilities = Cost("utilities", "hvac", 150) insurance = Cost("insurance", "full coverage", 100) property_tax = Cost("insurance", "full coverage", (house_cost * 0.019) / 12) mortgage = Mortgage(house_cost, 25000, dates, 3.0) # revenue revenues = [rent] costs = [utilities, insurance, property_tax] house = House(revenues, costs, mortgage, dates, appreciation) # house.summary() house.graph_net_profit() portfolio = Portfolio([house]) ytp = portfolio.get_years_to_positive(house) print("years till positive", ytp) exit(0) return ytp
def __init__(self): # Set False for forward testing. self.live_trading = True self.log_level = logging.DEBUG self.logger = self.setup_logger() self.exchanges = self.load_exchanges(self.logger) self.db_client = MongoClient( self.DB_URL, serverSelectionTimeoutMS=self.DB_TIMEOUT_MS) self.db_prices = self.db_client[self.DB_PRICES] self.db_other = self.db_client[self.DB_OTHER] self.check_db_connection() # Main event queue. self.events = queue.Queue(0) # Producer/consumer worker classes. self.data = Datahandler(self.exchanges, self.logger, self.db_prices, self.db_client) self.strategy = Strategy(self.exchanges, self.logger, self.db_prices, self.db_other, self.db_client) self.portfolio = Portfolio(self.exchanges, self.logger, self.db_other, self.db_client, self.strategy.models) self.broker = Broker(self.exchanges, self.logger, self.portfolio, self.db_other, self.db_client, self.live_trading) # Processing performance tracking variables. self.start_processing = None self.end_processing = None self.cycle_count = 0 self.run()
def test_compute_portfolio_value_return_cash_inflow(self): mock_log = [{ "date": dt.date(2020, 1, 1), "ticker": "CPALL.BK", "action": "B", "price": 69, "no.": 5 }, { "date": dt.date(2020, 1, 2), "ticker": "Cash", "action": "Deposit", "no.": 100000 }, { "date": dt.date(2020, 1, 2), "ticker": "CPALL.BK", "action": "S", "price": 70, "no.": 5 }] df_log = pd.DataFrame(mock_log) Port = Portfolio() Port.process_trade_log(df_log, initial_cash=0, end_date=dt.date(2020, 1, 3)) print(Port.tickers) dfp = Port.get_portfolio_value() print(dfp.to_string()) ## test correct local currency assert -20 < dfp.iloc[0]['cash'] < 0 assert -20 < dfp.iloc[0]['cash_bm'] < 0 ## test correct cash deposit logic assert dfp.iloc[-1]['cash_dep_bm'] == 100000 assert dfp.iloc[-1]['cash_dep'] == 100000 assert dfp.iloc[-1]['cash'] > 100000
def read_portfolio(filename): ''' Read a stock portfolio file into a list of dictionaries with keys name, shares, and price. ''' with open(filename, "rt") as f: portfolio_dict = parse_csv(f, select=["name", "shares", "price"], types=[str, int, float]) portfolio_classe = [ Stock(row["name"], row["shares"], row["price"]) for row in portfolio_dict ] return Portfolio(portfolio_classe)
def __init__(self, id, assets, initial_cash): ''' id: int, the identifier of the agent. assets: List of stocks and bonds to be traded. initial_cash: float, the number of cash the agent starts with. Generates an Agent instance with an empty portfolio; It only consists of `initial_cash` (all stocks have quantity 0.0). ''' self.id = id self.portfolio = Portfolio.empty_portfolio(assets) self.portfolio.set_cash_amount(initial_cash) self.pending_orders = [] self.traget_portfolio = None
def __init__(self, configuration, train_mode: bool): self.params = configuration self.log = self.params.log self.display = self.params.display self.memory = Memory(self.params) self.results = self.memory.results self.fcast_dict = self.params.fcast_file.dict self.log.info('Creating Environment') if 'seed' in self.params: np.random.seed(self.params.seed) else: np.random.seed(1) self.states = StatesCombiner(self.params) self.init_forecast(self.params.forecast_file, train_mode) self.portfolio = Portfolio(self.params, self.price_, self.forecast_, self.memory) # Create dict with functions linked to action names self.call_action = dict() for action in self.params.action: self.call_action[action] = getattr(self.portfolio, action) # Create another dict with the state methods so, we don't have to # call getattr and module load at each step self.state_class = dict() for module_param_name in self.params.state.keys(): # The extended classes are defined in the params file and must # start with the 'state_' string. module_name = 'State' + module_param_name module = importlib.import_module('state_classes') self.state_class[module_name] = getattr( getattr(module, module_name), 'update_state') self.init_environment(creation_time=True) self.log.info('Environment created')
def __init__( self, weightPath=None, # file path to previous weights (stored in results directory) funds=10000, # start with 10000 dollars featExtractor=Try1(), # define which feature extractor to use alpha=0.5, epsilon=0.05, # initial epsilon value gamma=0.90, # discount rate trainingDataBound=0.90, # define percentage of data to use for training stepsPerEpisode=288, # 3-day period rewardFunction=reward): # define the reward function for the agent self.featExtractor = featExtractor() self.portfolio = Portfolio(funds) if not weightPath: self.weightPath = "results/" + str(featExtractor)[11:] if os.path.isfile(self.weightPath): # set weights to the values in the given file if available with open(self.weightPath) as f: self.weights = pickle.load(f) else: # randomly initialize weights if they are not given by a file numFeatures = len( self.featExtractor.getFeatures( self.portfolio.getCurrentState(), "hold")) self.weights = np.random.randn(numFeatures) else: # randomly initialize weights if they are not given by a file self.weightPath = weightPath with open(weightPath) as f: self.weights = pickle.load(f) self.rewardFunction = rewardFunction self.trainingDataBound = trainingDataBound self.stepsPerEpisode = stepsPerEpisode self.discount = gamma self.epsilon = epsilon self.alpha = alpha self.episodes = []
def test_sell(self): p = Portfolio(balance=13.0) p.update(ticker='TICK', price=12.3) p.set_shares('TICK', 3.0) cont = Controller(p) success = cont.process_receipt(('TICK', 11.0, -2.0, 10.0)) eps = 1e-4 self.assertTrue(success) # Trade went through self.assertTrue( abs(25.0 - p.balance) < eps) # Balance updated correctly self.assertTrue( abs(1.0 - p.get_shares('TICK')) < eps) # Shares updated
def update_multi_asset_objects(trigger, finance, fund, period, div): """ Update sliders and asset revenue comparison graph when asset list changes """ finance = pd.read_json(finance) summary = pd.read_json(fund) ptf = Portfolio(finance=finance, summary=summary, period=period) if trigger in ['add', 'remove', 'period']: scaled = ptf.get_scaled_prices() figure = px.line(scaled, title='Ticker revenue comparison') figure.update_layout(yaxis_tickformat='%') div = [ dcc.Graph(id='all-ticker-graph', figure=figure), dcc.Slider(id='period-slider', min=1, max=20, marks={ 1: { 'label': '1 year' }, 5: { 'label': '5 years' }, 10: { 'label': '10 years' }, 20: { 'label': '20 years' } }, value=ptf.period), html.Div( id='sliders', children=[slider(i, ptf) for i in range(len(finance.columns))]) ] return div
def portfolio_selection(last_weight_list, fund_num, return_ret, riskcov_lr, adjust_thres, risk_thres): try: new_weight_list = Portfolio(last_weight_list, fund_num, return_ret, riskcov_lr, adjust_thres, risk_thres).asset_weight except: logger_handler.warning( module='backtest', file='backtest.py', content= "Portfolio optimization for params %s failed, allocation not changed." ) new_weight_list = last_weight_list return new_weight_list
class TestPortfolioRetrieve(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.r = RestManager() def setUp(self): if os.path.isfile("full.csv"): self.port = Portfolio("full.csv", retrieve=True) else: self.port = Portfolio(retrieve=True) def test_portfolio_retrieve_valid(self): self.assertTrue(self.port.is_valid(), msg='Invalid retrieved portfolio !') def test_portfolio_retrieve_sharpe(self): sharpe = self.port.get_sharpe() exp_sharpe = self.r.putRatio([12], [self.port.portfolioid], None, self.port.START_DATE, self.port.END_DATE, None) exp_sharpe = float( exp_sharpe[str(self.port.portfolioid)]['12']['value'].replace(',', '.')) diff = math.fabs(exp_sharpe - sharpe) self.assertLessEqual( diff, 1e-8, msg=f'exp: {exp_sharpe}, got: {sharpe}')
def update_assets(_1, _2, _3, period, finance, fund, cur_period, tick, *ws): """ Update portfolio when adding an asset, removing an asset or updating the weights/ period """ finance = pd.read_json(finance) summary = pd.read_json(fund) ptf = Portfolio(finance=finance, summary=summary, period=cur_period) changed_id = [p['prop_id'] for p in dash.callback_context.triggered][0] trigger = None if 'add' in changed_id: ptf.add(tick) trigger = 'add' elif 'remove' in changed_id: ptf.remove(tick) trigger = 'remove' elif 'update' in changed_id: ptf.update(weights=ws[0]) trigger = 'update' elif 'period' in changed_id: ptf.update(period=period) trigger = 'period' div = [ html.Div(id='portfolio-finance', children=ptf.finance.to_json(), style={'display': 'none'}), html.Div(id='portfolio-fund', children=ptf.summary.to_json(), style={'display': 'none'}), html.Div(id='portfolio-period', children=ptf.period, style={'display': 'none'}), html.Div(id='last_trigger', children=trigger, style={'display': 'none'}) ] return div
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: lines = fileparse.parse_csv(lines, select=['name', 'shares', 'price'], types=[str, int, float]) stocks = [Stock(row['name'], row['shares'], row['price']) for row in lines] # stocks = [] # for row in stocks: # stocks += stock.Stock(row['name'], row['shares'], row['price']) return Portfolio(stocks)
def random_runs(num_runs=1000): """ Base line random buy and hold a stock for a day to get idea if other cases are significant;y better """ test_file = "./data/intraday_datetimes_1min.pkl" stock = "AMZN" stocks = [stock] market = StockMarketDict(random_price=False, data_file=test_file) agent = AgentRandom(stocks=stocks) portfolio = Portfolio(cash=10000) # value_tracker is an ordered dictionary. Get last value as total gain % gains = [] for _ in range(num_runs): portfolio = Portfolio(cash=10000) executor = Executor(market=market, agent=agent, portfolio=portfolio, stocks=stocks, time=days) executor.run() gain = list(executor.value_tracker.values())[-1] gains.append(gain) return gains
def test_sell(self): p = Portfolio( buy_commission_rate=0.001, sell_commission_rate=0.0015, min_commission=5.0, round_lot=100) self.assertEqual((-10010.0, 10.0, 1000), p.buy(price=10.0, volume=1000)) p.update_before_trade(divide_rate=1.0) p.sell(price=11, volume=500) self.assertEqual(8.25, p.transaction_cost) self.assertEqual(9.0365, p.avg_price) self.assertEqual(11.0, p._price) self.assertEqual(500, p.volume) self.assertEqual(500, p.sellable) self.assertEqual(18.25, p.all_transaction_cost) p.sell(price=11, volume=500) self.assertEqual(16.5, p.transaction_cost) self.assertEqual(0, p.avg_price) self.assertEqual(11, p._price) self.assertEqual(0, p.volume) self.assertEqual(0, p.sellable) self.assertEqual(26.5, p.all_transaction_cost)
def portfolio_new_entry(): with Portfolio() as entry: # Get the equity list based on the transaction log list entry.get_equity_list() # Ask new ticker to user ticker = handler.ask_ticker_to_user() # Update data validation of ticker selection in Portfolio sheet with new ticker entry.update_ticker_selection_combo_box(new_ticker=ticker) # Show buy transaction form to user entry.transaction_entrybox("Buy") # Update complete portfolio sheet portfolio_update_all()
def test_sell_all_stock(self): p = Portfolio( buy_commission_rate=0.001, sell_commission_rate=0.0015, min_commission=5.0, round_lot=100) # sellable==0 , 无可卖 self.assertEqual((0.0, 10, 0), p._sell_all_stock(price=10)) self.assertEqual((-10010.0, 10.0, 1000), p._submit_order(side="buy", price=10.0, volume=1000)) p.update_before_trade(divide_rate=1.0) self.assertEqual((10983.5, 11, 1000), p._sell_all_stock(price=11)) self.assertEqual(16.5, p.transaction_cost) self.assertEqual(0, p.avg_price) self.assertEqual(0, p.volume) self.assertEqual(26.5, p.all_transaction_cost)
def read_portfolio(filename): ''' Read a stock portfolio file into a list of dictionaries with keys name, shares, and price. ''' with open(filename, 'rt') as file: portdicts = parse_csv(file, select=['name', 'shares', 'price'], types=[str, int, float]) portfolio = [ Stock(s['name'], s['shares'], s['price']) for s in portdicts ] return Portfolio(portfolio)
def setUp(self): self.portfolio = Portfolio({'USD': 100}) self.exchange_fee = 0.01 self.exchange_rates = { 'USD': { 'BTC': 0.1, 'ETH': 0.5 }, 'BTC': { 'ETH': 0.01, 'LTC': 20 }, 'ETH': {}, 'LTC': {}, 'XRP': {} }
def read_portfolio(file): """ portfolio = [] with open(filename, 'rt') as f: rows = csv.reader(f) headers = next(rows) for row in rows: holding = dict(zip(headers, row)) holding[headers[1]]=int(holding[headers[1]]) holding[headers[2]]=float(holding[headers[2]]) portfolio.append(holding) """ portdicts = parse_csv(file, select=None, types=[str, int, float], delimiter=',') portfolio = [ stock.Stock(d['name'],d['shares'],d['price']) for d in portdicts] return Portfolio(portfolio)
def test_liquidate(self): p = Portfolio(balance=13.0) p.update(ticker='TICK', price=12.3) p.set_shares('TICK', 3.0) cont = Controller(p) success = cont.process_receipt(('TICK', 11.0, -5.0, 10.0)) eps = 1e-4 updated_fee = cont._order_api._calculate_fee(11.0 * 3.0) self.assertTrue(success) # Trade went through self.assertTrue( abs(13.0 + (3 * 11.0) - updated_fee - p.balance) < eps) # Balance updated correctly self.assertTrue( abs(0.0 - p.get_shares('TICK')) < eps) # Shares updated self.assertTrue(abs(12.3 - p.get_price('TICK')) < eps) # Price not updated from slippage
def test_stock_should_be_deleted(): # given tickers = ["AMZN", "AAPL", "FB"] amounts = [10000, 50000, 30000] portfolio = Portfolio() portfolio.create_portfolio(tickers, amounts) portfolio.delete_stock_from_portfolio(ticker="FB") assert portfolio.total_amount_invested == 60000 assert portfolio.ASSETS == 2 assert round(sum(portfolio.weights)) == 1
def test_portfolio(self): """ Testing portfolio creation. initialisation and add stock. """ if DataHandler.check_portfolio_exists(): result = Portfolio() self.assertIsInstance(result.portfolio, dict) else: result = Portfolio() result.add_stock("AA", 10, 50, "2010-04-03") self.assertTrue(result.portfolio['AA'], True)
def handle(request): # parse request request_json = request.get_json(silent=True) request_args = request.args if request_json and 'gs_url' in request_json: gs_url = request_json['gs_url'] elif request_args and 'gs_url' in request_args: gs_url = request_args['gs_url'] else: print(traceback.format_exc()) raise ValueError("JSON is invalid, or missing a 'gs_url' property") p = Portfolio.from_gs(gs_url) res = {'gsURL': gs_url} res.update(p.get_summary()) res_js = json.dumps(res) return res_js, 200, {'ContentType': 'application/json'}
def __init__(self, n_days, n_steps_per_day, asset_config_path, agent_config_path): self.n_days = n_days self.n_steps_per_day = n_steps_per_day initial_shares_per_agent = 10 n_agents = AgentGenerator.n_agents(agent_config_path) print(n_agents) self.companies = CompanyGenerator.generate_companies(n_companies=10, n_sectors=3) self.tickers = [each.ticker for each in self.companies] # self.tickers = 'EQNR DNO AKER MHG NRS LSG'.split(' ') # self.companies = [] # for ticker in self.tickers: # comp = Company(ticker=ticker, # n_shares=initial_shares_per_agent * n_agents, # cash=100 * initial_shares_per_agent * n_agents, # yield_policy=0.10) # self.companies.append(comp) self.assets = [Stock(comp) for comp in self.companies] self.agents = AgentGenerator.generate(agent_config_path, self.assets, verbose=True) n_agents = len(self.agents) for agent in self.agents: for stock in self.assets: agent.portfolio.assets[stock] = initial_shares_per_agent self.cov_matrix = test.generate_corr_matrix(len(self.tickers), 2, 0.2) self.weights = np.ones(len(self.tickers)) self.weights = self.weights / self.weights.size self.book = Orderbook([], []) # self.assets = ... self.timestamp = Timestamp(0, 0) self.market_portfolio = Portfolio.empty_portfolio(self.assets) self.exchange = Exchange(self.agents, self.market_portfolio, n_steps_per_day) self.history = []
def test_stock_should_be_added(): # given tickers = ["AMZN", "AAPL", "FB"] amounts = [10000, 50000, 30000] portfolio = Portfolio() portfolio.create_portfolio(tickers, amounts) portfolio.add_stock_to_portfolio(ticker="GOOG", amount=25000) assert portfolio.total_amount_invested == 115000 assert portfolio.ASSETS == 4 assert round(sum(portfolio.weights)) == 1
def test_submit_order(self): p = Portfolio( buy_commission_rate=0.001, sell_commission_rate=0.0015, min_commission=5.0, round_lot=100) self.assertEqual((-10010.0, 10.0, 1000), p._submit_order(side="buy", price=10.0, volume=1000)) p.update_before_trade(divide_rate=1.0) self.assertEqual((5491.75, 11, 500), p._submit_order(side="sell", price=11, volume=500)) self.assertEqual(8.25, p.transaction_cost) self.assertEqual(9.0365, p.avg_price) self.assertEqual(500, p.volume) self.assertEqual(18.25, p.all_transaction_cost)
from portfolio import Portfolio p = Portfolio() print("Empty portfolio cost: {}".format(p.cost())) p.buy('IBM', 100, 176.48) print("With 100 IBM @ 176.48: {}".format(p.cost())) p.buy("HPQ", 100, 36.15) print("With 100 HPQ @ 36.15: {}".format(p.cost()))
def print_results(self): print 30 * '-' print 'Performance for Nonparametric Markowitz Portfolio:' print 30 * '-' Portfolio.print_results(self)
def print_results(self): print 30 * '-' print 'Results of expert pooling: ' print 30 * '-' print 'Weighting strategy: ', self.weighting_strategy Portfolio.print_results(self)
def test_empty(self): p = Portfolio() assert p.cost() == 0.0
#!/usr/bin/env python # -*- coding: utf-8 -*- from portfolio import Portfolio import pandas as pd time = [pd.Timestamp('2017-01-01 09:30:00'), pd.Timestamp('2017-01-01 09:31:00'), pd.Timestamp('2017-01-01 09:32:00')] portfolio = Portfolio() '''Cash''' '''Add cash''' portfolio.modify_cash(time[0], 1000) assert(portfolio.get_cash(time[0]) == 1000) '''Update portfolio value, then get portfolio value''' portfolio.update_portfolio_values(time[0]) assert(portfolio.get_porfolio_value(time[0]) == 1000) '''Removing cash''' old_cash_value = portfolio.get_cash(time[0]) portfolio.modify_cash(time[0], old_cash_value - 400) assert(portfolio.get_cash(time[0]) == 600) '''Out of bound indexing''' try: portfolio.get_porfolio_value(time[2])
@nav_menu("Contact Us") def contact(self): pass @nav_menu("My Account", order=2) class Hello(Portfolio): @nav_menu("Hello World Index", class_="Index", order=2, title="The People People") def index(self): pass @nav_menu(name="More About us") def about(self): pass app = Portfolio.init(__name__) #pprint.pprint(Portfolio._nav_menu_stack) exit() import functools import inspect from flask_classy import FlaskView from flask import Flask __menu__ = [] app = Flask(__name__)
def print_results(self): if self.verbose: print 30 * '-' print 'Performance for uniform constant rebalancing portfolio:' print 30 * '-' Portfolio.print_results(self)
for row in order_reader: date = dt.datetime(int(row[0]),int(row[1]), int(row[2]), 16) o = Order(action=row[4], date=date, tick=row[3], shares=row[5]) order_list.append(o) # order_list needs to be sorted. Otherwise the algorithm won't work. date_list = [x.date for x in order_list] date_list.sort() dt_start = date_list[0] dt_end = date_list[-1] tick_set = sets.Set([x.tick for x in order_list]) ls_symbols = ['$SPX'] while(tick_set): ls_symbols.append(tick_set.pop()) ldt_timestamps = du.getNYSEdays(dt_start, dt_end, dt_timeofday) all_stocks = get_tickdata(ls_symbols=ls_symbols, ldt_timestamps=ldt_timestamps) pf = Portfolio(equities=all_stocks, cash=cash, dates=ldt_timestamps, order_list=order_list) pf.sim() equity_col = ['buy', 'sell', 'close'] pf.csvwriter(csv_file=value_file, d=',', cash=False) print "Details of the Performance of the portfolio :" print "Data Range :", ldt_timestamps[0], "to", ldt_timestamps[-1] print "Sharpe Ratio of Fund :", pf.sharpe() print "Sharpe Ratio of $SPX :", pf.equities['$SPX'].sharpe() print "Total Return of Fund :", pf.totalrtn() print " Total Return of $SPX :", pf.equities['$SPX'].totalrtn() print "Standard Deviation of Fund :", pf.std() print " Standard Deviation of $SPX :", pf.equities['$SPX'].std() print "Average Daily Return of Fund :", pf.avg_dailyrtn() print "Average Daily Return of $SPX :", pf.equities['$SPX'].avg_dailyrtn() fig = plt.figure() ax = fig.add_subplot(111)
class StockData(object): # I need to re-factor this code. def __init__(self,stockdata_csv='rawdata/csv/allStocks.csv'): self.data = pd.read_csv(stockdata_csv, index_col=0) self.data.set_index(pd.to_datetime(self.data.index), inplace=True) self.portfolio = Portfolio(100000, pct_equity_risk=0.01) def graph_data(self,symbol='MMM'): fig = plt.figure() ax = self.data.plot(y=[symbol]) ax.set_ylabel('Open') plt.show() def calc_ewma_manual(self, symbol='MMM', l=0.1): timeSeries = self.data[symbol] for i in range(timeSeries.count()): if not np.isnan(timeSeries[i]): if i == 0: ewma = [timeSeries[i]] else: ewma.append(timeSeries[i]*l + (1-l)*ewma[i-1]) else: if i == 0: ewma = [np.min(timeSeries[:500])] else: ewma.append(ewma[i-1]) print(timeSeries[i], ewma[i]) return ewma def calc_ewma(self,symbol='MMM',alpha=0.1): com = (1-alpha)/alpha self.data[symbol + '_ewma'] = pd.ewma(self.data[symbol],com=com) def calc_ewma_residuals(self,symbol='MMM'): if not symbol + "_ewma" in self.data.columns: raise Exception("Error: Call .calc_ewma first.") self.data[symbol + "_ewma_res"] = self.data[symbol] - self.data[symbol + "_ewma"] window_size = 30 self.data[symbol + "_minus_ewma_res"] = self.data[symbol] - map(lambda x: 3*abs(x), pd.rolling_mean(self.data[symbol + '_ewma_res'],window_size, min_periods=0)) self.data[symbol + "_minus_ewma_res"] = pd.rolling_mean(self.data[symbol + "_minus_ewma_res"],window_size,min_periods=0) #def _movingaverage(self, interval, window_size): # window = np.ones(int(window_size)) / float(window_size) # return np.convolve(interval, window, 'same') #def calc_movingaverage(self,symbol='MMM',window_size=20): # self.data[symbol + "_ma"] = self._movingaverage(self.data[symbol],window_size) def calc_ma(self, symbol='MMM', window_size=20): self.data[symbol + "_ma_" + str(window_size)] = pd.rolling_mean(self.data[symbol], window_size, min_periods=0) def calc_moving_range(self,symbol='MMM',window_size=40): timeSeries = self.data[symbol] output = np.ones(window_size)*np.min(timeSeries[:500]) # set first 20 values equal to the min of the first 500 to avoid issues with nan for i in range(window_size-1,timeSeries.shape[0]-1): if not np.isnan(np.min(timeSeries[i-window_size:i])): output = np.append(output,np.max(timeSeries[i-window_size:i])-np.min(timeSeries[i-window_size:i])) else: output = np.append(output,output[i-1]) output2 = pd.Series(output, index=timeSeries.index) self.data[symbol + "_mrange"] = output2 window_size = 30 self.data[symbol + "_minus_mrange"] = pd.rolling_mean(self.data[symbol] - self.data[symbol + '_mrange'], window_size,min_periods=0) return output2 def calc_ma_stats(self,symbol='MMM',near_ma=20,far_ma=60): near_col_name = symbol + "_ma_" + str(near_ma) far_col_name = symbol + "_ma_" + str(far_ma) if not near_col_name in self.data.columns: self.calc_ma(symbol, near_ma) if not far_col_name in self.data.columns: self.calc_ma(symbol, far_ma) delta_col_name = symbol + "_ma_" + str(near_ma) + "-ma_" + str(far_ma) delta = self.data[near_col_name] - self.data[far_col_name] self.data[delta_col_name] = delta.round(1) for col_name in [near_col_name,far_col_name]: self.data[col_name + '_grad'] = pd.rolling_mean(np.gradient(self.data[col_name],100),10) def plot_crossovers(self,symbol='MMM',near_ma=20,far_ma=60): if not symbol in self.data.columns: raise Exception(symbol + " not found within the dataset") near_col_name = symbol + "_ma_" + str(near_ma) far_col_name = symbol + "_ma_" + str(far_ma) delta_col_name = symbol + "_ma_" + str(near_ma) + "-ma_" + str(far_ma) crossOverPts = self.data[delta_col_name][self.data[delta_col_name] == 0] ax = self.data[[symbol,near_col_name,far_col_name]].plot() for crossOverPoint in crossOverPts.index: ax.axvline(crossOverPoint,color='grey') # Plot the Gradient #self.data[col_name + '_grad'].plot(secondary_y=True) #Buy when the gradient of the near term moving average is positive and when it is crossing the long term average entry_points = self.data[symbol][(self.data[col_name+'_grad'] > 0) & (self.data[delta_col_name] == 0)] for entry_point in entry_points.index: ax.axvline(entry_point, color='red',linewidth=3) #self.data[symbol + '_entry'] = entry_points*np.ones(entry_points.shape[0]) plt.show() return crossOverPts def trade(self, symbol='MMM',near_ma=20,far_ma=60): if not symbol + '_ma_' + str(near_ma) in self.data.columns: raise Exception("Please run .calc_ma_stats first") #timeSeries = self.data[symbol].dropna() col_name = symbol + '_ma_' + str(near_ma) delta_col_name = symbol + "_ma_" + str(near_ma) + "-ma_" + str(far_ma) order_history = [] self.recent_max_list = [] self.stop_loss_list = [] holding_stock = False recent_max = 0 for i in range(self.data[symbol].shape[0]): entry_criteria = self.data[col_name +'_grad'][i] > 0 and self.data[delta_col_name][i] == 0 if recent_max < self.data[symbol][i] and not np.isnan(self.data[symbol][i]): recent_max = self.data[symbol][i] if not holding_stock: if entry_criteria and not np.isnan(self.data[symbol][i]): holding_stock = True purchase_price = self.data[symbol][i] purchase_date = self.data.index[i] recent_max = purchase_price delta_to_max = np.std(self.data[symbol + '_ewma_res'][i-50:i])*3 initial_stop_loss = purchase_price - delta_to_max # initial stop loss is minus_ewma_res self.stop_loss_list.append(initial_stop_loss) self.portfolio.buy_stock(symbol,purchase_price, initial_stop_loss) entry_criteria = False print(self.portfolio.current_holdings) #print("PURCHASE: "+ purchase_date.strftime('%m/%d/%y') + " " + str(purchase_price)) else: self.stop_loss_list.append(np.nan) else: if np.std(self.data[symbol + '_ewma_res'][i-50:i])*3 < delta_to_max: delta_to_max = np.std(self.data[symbol + '_ewma_res'][i-50:i])*3 # allow the delta from the max to get smaller not larger stop_loss = recent_max - delta_to_max exit_criteria = self.data[symbol][i] < stop_loss self.stop_loss_list.append(stop_loss) #exit_criteria = self.data[symbol][i] < self.data[symbol + '_minus_ewma_res'][i-1] #print(self.data.index[i].strftime('%m/%d/%y') + " " + str(self.data[symbol][i]) + " max: " + str(recent_max) + " Range: " + str(self.data[symbol + '_mrange'][i])) if exit_criteria and not np.isnan(self.data[symbol][i]): holding_stock = False #SELL! sell_price = self.data[symbol][i] sell_date = self.data.index[i] num_shares = self.portfolio.current_holdings[symbol] self.portfolio.sell_stock(symbol, sell_price) order_history.append((purchase_date, purchase_price, sell_date, sell_price, initial_stop_loss, num_shares, self.portfolio.cash_equity)) #print(" SELL: " + sell_date.strftime('%m/%d/%y') + " Price:" + str(sell_price) + " MAX:" + str(recent_max) + " Range:" + str(self.data[symbol + '_mrange'][i]) + " Delta:" + str(recent_max - self.data[symbol + '_mrange'][i])) purchase_price = np.nan sell_price = np.nan print(self.portfolio.current_holdings) exit_criteria = False #ax.axvline(self.data.index[i], color='blue') self.recent_max_list.append(recent_max) self.data[symbol + '_stop_loss'] = pd.Series(self.stop_loss_list, index=self.data.index) self.data[symbol + '_recent_max'] = pd.Series(self.recent_max_list,index=self.data.index) #self.data[symbol + '_recent_max_minus_mrange'] = self.data[symbol + '_recent_max'] - self.data[symbol + '_mrange'] order_history_df = pd.DataFrame(order_history, columns=['Purchase Date','Purchase Price','Sell Date','Sell Price','Stop Loss', 'Number of Shares','Total Cash Equity']) order_history_df['Symbol'] = symbol order_history_df['Profit_Loss_share'] = order_history_df['Sell Price'] - order_history_df['Purchase Price'] order_history_df['Risk'] = order_history_df['Purchase Price'] - order_history_df['Stop Loss'] order_history_df['Rmultiple'] = order_history_df['Profit_Loss_share'] / order_history_df['Risk'] if hasattr(self,'order_history'): self.order_history = pd.concat([self.order_history, order_history_df],ignore_index=True) else: self.order_history = order_history_df def calc_factors_trade(self, symbol='MMM'): self.calc_ma_stats(symbol, self.settings['near_ma'], self.settings['far_ma']) self.calc_ewma(symbol) self.calc_ewma_residuals(symbol) #output2 = self.calc_moving_range(symbol) self.trade(symbol, self.settings['near_ma'], self.settings['far_ma']) # Updates order history def backtest(self, symbol_list=['MMM','ACT'], near_ma=10, far_ma=90, save=False): self.symbol_list = symbol_list self.settings = {'near_ma': near_ma, 'far_ma': far_ma} for symbol in symbol_list: print("BackTesting " + symbol) self.calc_factors_trade(symbol) if save: try: self.order_history.to_csv('Order_History.csv') # Add numbering except IOError: print("IOError: Order History Not saved.") return self.calc_score() def show_symbol_columns(self,symbol='MMM'): for col in self.data.columns: if symbol in col: print(col) def plot_results(self, symbol_list): near_ma = self.settings['near_ma'] far_ma = self.settings['far_ma'] # ax = self.data[[symbol, symbol + '_minus_ewma_res',symbol + '_recent_max', symbol + '_stop_loss']].plot() for symbol in symbol_list: print("Plotting for " + symbol) ax = self.data[[symbol, symbol + '_ma_' + str(near_ma), symbol + '_ma_' + str(far_ma), symbol + '_stop_loss']].plot() symbol_order_history = self.order_history[self.order_history['Symbol']==symbol] for row in symbol_order_history.iterrows(): try: ax.axvline(row[1]['Purchase Date'], color='red', linewidth=2) ax.axvline(row[1]['Sell Date'], color='green', linewidth=2) except KeyError: print("KeyError: No entries found for item.") print(symbol_order_history) # fig = plt.figure() def calc_score(self,plot_histo=True): # symbol = self.sd.order_history_symbol if plot_histo and self.order_history.shape[0] >= 0: # Need to have at least one row plt.hist(self.order_history['Rmultiple']) expectancy = self.order_history['Rmultiple'].mean() RstdDev = self.order_history['Rmultiple'].std() SQN = expectancy / RstdDev scoresNumbers = list(map(lambda x: round(x, 3), [expectancy, RstdDev, SQN])) near_ma = self.settings['near_ma'] far_ma = self.settings['far_ma'] scores = ['-'.join(self.symbol_list), near_ma, far_ma, scoresNumbers[0], scoresNumbers[1], scoresNumbers[2]] columns = ['Symbols', 'near_ma', 'far_ma', 'Expectancy', 'R-StdDev', 'SQN'] a = zip(columns, scores) # scoresDict = {} # for i in range(len(columns)): # scoresDict[columns[i]] = scores[i] scoresDict = {k: v for k, v in a} self.score = pd.DataFrame(data=scoresDict, index=[0]) return self.score
def __init__(self,stockdata_csv='rawdata/csv/allStocks.csv'): self.data = pd.read_csv(stockdata_csv, index_col=0) self.data.set_index(pd.to_datetime(self.data.index), inplace=True) self.portfolio = Portfolio(100000, pct_equity_risk=0.01)
def print_results(self): print 30 * '-' print 'Performance for RMR:' print 30 * '-' Portfolio.print_results(self)
def print_results(self): print 30 * '-' print 'Performance for uniform constant rebalancing portfolio:' print 30 * '-' Portfolio.print_results(self) print self.b_history[-1]
def print_results(self): print 30 * '-' print 'Performance for uniform buy and hold strategy:' print 30 * '-' Portfolio.print_results(self)
def print_results(self): if self.verbose: print 30 * '-' print 'Performance for OLMAR:' print 30 * '-' Portfolio.print_results(self)
class TestPortfolio(unittest.TestCase): def setUp(self): base = "GBP" leverage = 20 equity = Decimal("100000.00") risk_per_trade = Decimal("0.02") ticker = {} events = {} self.port = Portfolio( ticker, events, base=base, leverage=leverage, equity=equity, risk_per_trade=risk_per_trade ) def test_add_position_long(self): position_type = "long" market = "GBP/USD" units = Decimal("2000") exposure = Decimal("2000.00") bid = Decimal("1.51770") ask = Decimal("1.51819") self.port.add_new_position( position_type, market, units, exposure, bid, ask ) ps = self.port.positions[market] self.assertEquals(ps.position_type, position_type) self.assertEquals(ps.market, market) self.assertEquals(ps.units, units) self.assertEquals(ps.exposure, exposure) self.assertEquals(ps.avg_price, ask) self.assertEquals(ps.cur_price, bid) def test_add_position_short(self): position_type = "short" market = "GBP/USD" units = Decimal("2000") exposure = Decimal("2000.00") bid = Decimal("1.51770") ask = Decimal("1.51819") self.port.add_new_position( position_type, market, units, exposure, bid, ask ) ps = self.port.positions[market] self.assertEquals(ps.position_type, position_type) self.assertEquals(ps.market, market) self.assertEquals(ps.units, units) self.assertEquals(ps.exposure, exposure) self.assertEquals(ps.avg_price, bid) self.assertEquals(ps.cur_price, ask) def test_add_position_units_long(self): position_type = "long" market = "GBP/USD" units = Decimal("2000") exposure = Decimal("2000.00") bid = Decimal("1.51770") ask = Decimal("1.51819") # Test for no position market = "EUR/USD" apu = self.port.add_position_units( market, units, exposure, bid, ask ) self.assertFalse(apu) # Add a position and test for real position market = "GBP/USD" self.port.add_new_position( position_type, market, units, exposure, bid, ask ) ps = self.port.positions[market] # Test for addition of units bid = Decimal("1.51878") ask = Decimal("1.51928") apu = self.port.add_position_units( market, units, exposure, bid, ask ) self.assertTrue(apu) self.assertEqual(ps.avg_price, Decimal("1.518735")) def test_add_position_units_short(self): position_type = "short" market = "GBP/USD" units = Decimal("2000") exposure = Decimal("2000.00") bid = Decimal("1.51770") ask = Decimal("1.51819") # Test for no position market = "EUR/USD" apu = self.port.add_position_units( market, units, exposure, bid, ask ) self.assertFalse(apu) # Add a position and test for real position market = "GBP/USD" self.port.add_new_position( position_type, market, units, exposure, bid, ask ) ps = self.port.positions[market] # Test for addition of units bid = Decimal("1.51878") ask = Decimal("1.51928") apu = self.port.add_position_units( market, units, exposure, bid, ask ) self.assertTrue(apu) self.assertEqual(ps.avg_price, Decimal("1.51824")) def test_remove_position_units_long(self): position_type = "long" units = Decimal("2000") exposure = Decimal("2000.00") bid = Decimal("1.51770") ask = Decimal("1.51819") # Test for no position market = "EUR/USD" apu = self.port.remove_position_units( market, units, bid, ask ) self.assertFalse(apu) # Add a position and then add units to it market = "GBP/USD" self.port.add_new_position( position_type, market, units, exposure, bid, ask ) ps = self.port.positions[market] bid = Decimal("1.51878") ask = Decimal("1.51928") add_units = 8000 add_exposure = Decimal(str(add_units)) apu = self.port.add_position_units( market, add_units, add_exposure, bid, ask ) self.assertEqual(ps.units, 10000) self.assertEqual(ps.exposure, Decimal("10000.00")) self.assertEqual(ps.avg_price, Decimal("1.519062")) # Test removal of (some) of the units bid = Decimal("1.52017") ask = Decimal("1.52134") remove_units = 3000 rpu = self.port.remove_position_units( market, remove_units, bid, ask ) self.assertTrue(rpu) self.assertEqual(ps.units, 7000) self.assertEqual(ps.exposure, Decimal("7000.00")) self.assertEqual(ps.profit_base, Decimal("2.19054")) self.assertEqual(self.port.balance, Decimal("100002.19")) def test_remove_position_units_short(self): position_type = "short" units = Decimal("2000") exposure = Decimal("2000.00") bid = Decimal("1.51770") ask = Decimal("1.51819") # Test for no position market = "EUR/USD" apu = self.port.remove_position_units( market, units, bid, ask ) self.assertFalse(apu) # Add a position and then add units to it market = "GBP/USD" self.port.add_new_position( position_type, market, units, exposure, bid, ask ) ps = self.port.positions[market] bid = Decimal("1.51878") ask = Decimal("1.51928") add_units = 8000 add_exposure = Decimal(str(add_units)) apu = self.port.add_position_units( market, add_units, add_exposure, bid, ask ) self.assertEqual(ps.units, 10000) self.assertEqual(ps.exposure, Decimal("10000.00")) self.assertEqual(ps.avg_price, Decimal("1.518564")) # Test removal of (some) of the units bid = Decimal("1.52017") ask = Decimal("1.52134") remove_units = 3000 rpu = self.port.remove_position_units( market, remove_units, bid, ask ) self.assertTrue(rpu) self.assertEqual(ps.units, 7000) self.assertEqual(ps.exposure, Decimal("7000.00")) self.assertEqual(ps.profit_base, Decimal("-5.48201")) self.assertEqual(self.port.balance, Decimal("99994.52")) def test_close_position_long(self): position_type = "long" units = Decimal("2000") exposure = Decimal("2000.00") bid = Decimal("1.51770") ask = Decimal("1.51819") # Test for no position market = "EUR/USD" cp = self.port.close_position( market, bid, ask ) self.assertFalse(cp) # Add a position and then close it # Will lose money on the spread market = "GBP/USD" self.port.add_new_position( position_type, market, units, exposure, bid, ask ) ps = self.port.positions[market] cp = self.port.close_position( market, bid, ask ) self.assertTrue(cp) self.assertRaises(ps) # Key doesn't exist self.assertEqual(self.port.balance, Decimal("99999.35")) # Add 2000, add another 8000, remove 3000 and then # close the position. Balance should be as expected # for a multi-leg transaction. self.port.add_new_position( position_type, market, units, exposure, bid, ask ) ps = self.port.positions[market] # Add 8000 units bid = Decimal("1.51878") ask = Decimal("1.51928") add_units = 8000 add_exposure = Decimal(str(add_units)) apu = self.port.add_position_units( market, add_units, add_exposure, bid, ask ) self.assertEqual(ps.units, 10000) self.assertEqual(ps.exposure, Decimal("10000.00")) self.assertEqual(ps.avg_price, Decimal("1.519062")) # Remove 3000 units bid = Decimal("1.52017") ask = Decimal("1.52134") remove_units = 3000 rpu = self.port.remove_position_units( market, remove_units, bid, ask ) self.assertEqual(ps.units, 7000) self.assertEqual(ps.exposure, Decimal("7000.00")) self.assertEqual(ps.profit_base, Decimal("2.19054")) self.assertEqual(self.port.balance, Decimal("100001.54")) # Close the position cp = self.port.close_position( market, bid, ask ) self.assertTrue(cp) self.assertRaises(ps) # Key doesn't exist self.assertEqual(self.port.balance, Decimal("100006.65")) def test_close_position_short(self): position_type = "short" units = Decimal("2000") exposure = Decimal("2000.00") bid = Decimal("1.51770") ask = Decimal("1.51819") # Test for no position market = "EUR/USD" cp = self.port.close_position( market, bid, ask ) self.assertFalse(cp) # Add a position and then close it # Will lose money on the spread market = "GBP/USD" self.port.add_new_position( position_type, market, units, exposure, bid, ask ) ps = self.port.positions[market] cp = self.port.close_position( market, bid, ask ) self.assertTrue(cp) self.assertRaises(ps) # Key doesn't exist self.assertEqual(self.port.balance, Decimal("99999.35")) # Add 2000, add another 8000, remove 3000 and then # close the position. Balance should be as expected # for a multi-leg transaction. self.port.add_new_position( position_type, market, units, exposure, bid, ask ) ps = self.port.positions[market] # Add 8000 units bid = Decimal("1.51878") ask = Decimal("1.51928") add_units = 8000 add_exposure = Decimal(str(add_units)) apu = self.port.add_position_units( market, add_units, add_exposure, bid, ask ) self.assertEqual(ps.units, 10000) self.assertEqual(ps.exposure, Decimal("10000.00")) self.assertEqual(ps.avg_price, Decimal("1.518564")) # Remove 3000 units bid = Decimal("1.52017") ask = Decimal("1.52134") remove_units = 3000 rpu = self.port.remove_position_units( market, remove_units, bid, ask ) self.assertEqual(ps.units, 7000) self.assertEqual(ps.exposure, Decimal("7000.00")) self.assertEqual(ps.profit_base, Decimal("-5.48201")) self.assertEqual(self.port.balance, Decimal("99993.87")) # Close the position cp = self.port.close_position( market, bid, ask ) self.assertTrue(cp) self.assertRaises(ps) # Key doesn't exist self.assertEqual(self.port.balance, Decimal("99981.08"))
for row in order_reader: date = dt.datetime(int(row[0]),int(row[1]), int(row[2]), 16) o = Order(action=row[4], date=date, tick=row[3], shares=row[5]) order_list.append(o) # order_list needs to be sorted. Otherwise the algorithm won't work. date_list = [x.date for x in order_list] date_list.sort() dt_start = date_list[0] dt_end = date_list[-1] tick_set = sets.Set([x.tick for x in order_list]) ls_symbols = ['$SPX'] while(tick_set): ls_symbols.append(tick_set.pop()) ldt_timestamps = du.getNYSEdays(dt_start, dt_end, dt_timeofday) all_stocks = get_tickdata(ls_symbols=ls_symbols, ldt_timestamps=ldt_timestamps) pf = Portfolio(equities=all_stocks, cash=cash, dates=ldt_timestamps, order_list=order_list) pf.sim() equity_col = ['buy', 'sell', 'close'] pf.csvwriter(csv_file=value_file, d=',', cash=False) print "Details of the Performance of the portfolio :" print "Data Range :", ldt_timestamps[0], "to", ldt_timestamps[-1] print "Sharpe Ratio of Fund :", pf.sharpe() print "Sortino Ratio of Fund :", pf.sortino() print "Sharpe Ratio of $SPX :", pf.equities['$SPX'].sharpe() print "Total Return of Fund :", pf.totalrtn() print " Total Return of $SPX :", pf.equities['$SPX'].totalrtn() print "Standard Deviation of Fund :", pf.std() print " Standard Deviation of $SPX :", pf.equities['$SPX'].std() print "Average Daily Return of Fund :", pf.avg_dailyrtn() print "Average Daily Return of $SPX :", pf.equities['$SPX'].avg_dailyrtn() fig = plt.figure()
def main(): ''' testing developed parts ''' assetNames = ["SPY", "IEF", "SHY", "IEV", "EPP", "LQD"] assetList = AssetList(assetNames) myPort = Portfolio(assetList) myPort.setStartingCapital(10000) momentumFilter = MomentumFilter([120, 135, 150]) myPort.setTechnicalSignal(momentumFilter) myPort.setAllocationSystem(EqualWeightSystem()) myPort.calculatePerformance() #myPort.printSharpe() myPort.printNumberOfShares() #myPort.printTrades() momentumRange = range(10, 300, 5) momentumSharpes = [0.0] * len(momentumRange) momentumReturns = [0.0] * len(momentumRange) momentumStds = [0.0] * len(momentumRange) #Analyzing momentum system i=0 for m in momentumRange: print "m = {0}\n".format(m) momentumFilter.updatePeriod([m]) myPort.setTechnicalSignal(momentumFilter) myPort.updateAllocation() myPort.calculatePerformance() momentumSharpes[i] = myPort.getSharpe() momentumReturns[i] = myPort.getReturn() momentumStds[i] = myPort.getStd() i += 1 plt.figure(1) plt.plot(momentumSharpes) plt.show() plt.figure(2) plt.plot(momentumReturns) plt.show() plt.figure(3) plt.plot(momentumStds) plt.show()
def test_buy_two_stock(self): p = Portfolio() p.buy('IBM',100, 176.48) p.buy('HPQ',100, 36.15) self.assertEqual(p.cost(),21263.0)
class TestPortfolio(unittest.TestCase): def setUp(self): home_currency = "GBP" leverage = 20 equity = Decimal("100000.00") risk_per_trade = Decimal("0.02") ticker = TickerMock() events = {} self.port = Portfolio( ticker, events, home_currency=home_currency, leverage=leverage, equity=equity, risk_per_trade=risk_per_trade ) def test_add_position_long(self): position_type = "long" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] self.assertEquals(ps.position_type, position_type) self.assertEquals(ps.currency_pair, currency_pair) self.assertEquals(ps.units, units) self.assertEquals(ps.avg_price, ticker.prices[currency_pair]["ask"]) self.assertEquals(ps.cur_price, ticker.prices[currency_pair]["bid"]) def test_add_position_short(self): position_type = "short" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] self.assertEquals(ps.position_type, position_type) self.assertEquals(ps.currency_pair, currency_pair) self.assertEquals(ps.units, units) self.assertEquals(ps.avg_price, ticker.prices[currency_pair]["bid"]) self.assertEquals(ps.cur_price, ticker.prices[currency_pair]["ask"]) def test_add_position_units_long(self): position_type = "long" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.add_position_units( alt_currency_pair, units ) self.assertFalse(apu) # Add a position and test for real position self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") apu = self.port.add_position_units( currency_pair, units ) self.assertTrue(apu) self.assertEqual(ps.avg_price, Decimal("1.511385")) def test_add_position_units_short(self): position_type = "short" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.add_position_units( alt_currency_pair, units ) self.assertFalse(apu) # Add a position and test for real position self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") apu = self.port.add_position_units( currency_pair, units ) self.assertTrue(apu) self.assertEqual(ps.avg_price, Decimal("1.51103")) def test_remove_position_units_long(self): position_type = "long" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.remove_position_units( alt_currency_pair, units ) self.assertFalse(apu) # Add a position and then add units to it self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") add_units = Decimal("8000") apu = self.port.add_position_units( currency_pair, add_units ) self.assertEqual(ps.units, 10000) self.assertEqual(ps.avg_price, Decimal("1.516122")) # Test removal of (some) of the units ticker.prices["GBPUSD"]["bid"] = Decimal("1.52017") ticker.prices["GBPUSD"]["ask"] = Decimal("1.52134") ticker.prices["USDGBP"]["bid"] = Decimal("0.65782") ticker.prices["USDGBP"]["ask"] = Decimal("0.65732") remove_units = Decimal("3000") rpu = self.port.remove_position_units( currency_pair, remove_units ) self.assertTrue(rpu) self.assertEqual(ps.units, Decimal("7000")) self.assertEqual(self.port.balance, Decimal("100007.99")) def test_remove_position_units_short(self): position_type = "short" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.remove_position_units( alt_currency_pair, units ) self.assertFalse(apu) # Add a position and then add units to it self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") add_units = Decimal("8000") apu = self.port.add_position_units( currency_pair, add_units ) self.assertEqual(ps.units, 10000) self.assertEqual(ps.avg_price, Decimal("1.51568")) # Test removal of (some) of the units ticker.prices["GBPUSD"]["bid"] = Decimal("1.52017") ticker.prices["GBPUSD"]["ask"] = Decimal("1.52134") ticker.prices["USDGBP"]["bid"] = Decimal("0.65782") ticker.prices["USDGBP"]["ask"] = Decimal("0.65732") remove_units = Decimal("3000") rpu = self.port.remove_position_units( currency_pair, remove_units ) self.assertTrue(rpu) self.assertEqual(ps.units, Decimal("7000")) self.assertEqual(self.port.balance, Decimal("99988.83")) def test_close_position_long(self): position_type = "long" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.remove_position_units( alt_currency_pair, units ) self.assertFalse(apu) # Add a position and then add units to it self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") add_units = Decimal("8000") apu = self.port.add_position_units( currency_pair, add_units ) self.assertEqual(ps.units, 10000) self.assertEqual(ps.avg_price, Decimal("1.516122")) # Test removal of (some) of the units ticker.prices["GBPUSD"]["bid"] = Decimal("1.52017") ticker.prices["GBPUSD"]["ask"] = Decimal("1.52134") ticker.prices["USDGBP"]["bid"] = Decimal("0.65782") ticker.prices["USDGBP"]["ask"] = Decimal("0.65732") remove_units = Decimal("3000") rpu = self.port.remove_position_units( currency_pair, remove_units ) self.assertTrue(rpu) self.assertEqual(ps.units, Decimal("7000")) self.assertEqual(self.port.balance, Decimal("100007.99")) # Close the position cp = self.port.close_position(currency_pair) self.assertTrue(cp) self.assertRaises(ps) # Key doesn't exist self.assertEqual(self.port.balance, Decimal("100026.63")) def test_close_position_short(self): position_type = "short" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.remove_position_units( alt_currency_pair, units ) self.assertFalse(apu) # Add a position and then add units to it self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") add_units = Decimal("8000") apu = self.port.add_position_units( currency_pair, add_units ) self.assertEqual(ps.units, 10000) self.assertEqual(ps.avg_price, Decimal("1.51568")) # Test removal of (some) of the units ticker.prices["GBPUSD"]["bid"] = Decimal("1.52017") ticker.prices["GBPUSD"]["ask"] = Decimal("1.52134") ticker.prices["USDGBP"]["bid"] = Decimal("0.65782") ticker.prices["USDGBP"]["ask"] = Decimal("0.65732") remove_units = Decimal("3000") rpu = self.port.remove_position_units( currency_pair, remove_units ) self.assertTrue(rpu) self.assertEqual(ps.units, Decimal("7000")) self.assertEqual(self.port.balance, Decimal("99988.83")) # Close the position cp = self.port.close_position(currency_pair) self.assertTrue(cp) self.assertRaises(ps) # Key doesn't exist self.assertEqual(self.port.balance, Decimal("99962.77"))
def test_empty(self): p = Portfolio() self.assertEqual(p.cost(),0.1)
def test_buy_two_stock(self): p = Portfolio() p.buy('IBM',100, 176.48) p.buy('HPQ',100, 36.15) assert p.cost() == 21263.0
def test_buy_one_stock(self): p = Portfolio() p.buy('IBM',100, 176.48) self.assertEqual(p.cost(),17648.0)
def test_buy_one_stock(self): p = Portfolio() p.buy('IBM',100, 176.48) assert p.cost() == 17648.0
def test_generate_trace_generates_frame(self): portfolio = Portfolio([ ("BACK.L", 40), ("BACS.L", 60), ]) start_date = datetime(2016, 1, 1) end_date = datetime(2016, 1, 4) ticker1_frame = pd.DataFrame({ "Close": pd.Series( [ 1, 1.01, 1.02, 1.03, 1.04, ], index=[ datetime(2016, 1, 1), datetime(2016, 1, 2), datetime(2016, 1, 3), datetime(2016, 1, 4), datetime(2016, 1, 5), ] ) }) ticker2_frame = pd.DataFrame({ "Close": pd.Series( [ 2.1, 2, 1.9, 1.8, 1.7, ], index=[ datetime(2015, 12, 31), datetime(2016, 1, 1), datetime(2016, 1, 2), datetime(2016, 1, 3), datetime(2016, 1, 4), ] ) }) market_data = { "BACK.L": ticker1_frame, "BACS.L": ticker2_frame, } trace = portfolio.trace(market_data, start_date, end_date) expected_ticker1_holding = (10000 / 1) * 40 expected_ticker2_holding = (10000 / 2) * 60 expected_frame = pd.DataFrame({ "Close": pd.Series( [ expected_ticker1_holding * 1 + expected_ticker2_holding * 2, expected_ticker1_holding * 1.01 + expected_ticker2_holding * 1.9, expected_ticker1_holding * 1.02 + expected_ticker2_holding * 1.8, expected_ticker1_holding * 1.03 + expected_ticker2_holding * 1.7, ], index=[ datetime(2016, 1, 1), datetime(2016, 1, 2), datetime(2016, 1, 3), datetime(2016, 1, 4), ] ) }) self.assertTrue((trace.frame == expected_frame).all()["Close"])