def __init__(self, acctNum):
        # Initialize Questrade Instance
        if path.exists("./access_token.yml"):
            #print("first try in questrade")
            self.qtrade = Questrade(token_yaml='./access_token.yml')
            try:
                acct_list = self.qtrade.get_account_id()
                #print(acctNum in acct_list)
                assert acctNum in acct_list
            except:
                #print("first if statement")
                self.qtrade.refresh_access_token(from_yaml=True)
                self.qtrade = Questrade(token_yaml='./access_token.yml')
                try:
                    assert acctNum in self.qtrade.get_account_id()
                except:
                    #print("yml file removed!")
                    remove("./access_token.yml")
                    # get new access code
                    access_code = new_access_code()
                    self.qtrade = Questrade(access_code=access_code)
        else:
            #print("no yml file exist")
            access_code = new_access_code()
            self.qtrade = Questrade(access_code=access_code)
            try:
                accts_list = self.qtrade.get_account_id()
            except:
                while not isinstance(accts_list, list):
                    #print("in while loop")
                    access_code = new_access_code()
                    self.qtrade = Questrade(access_code=access_code)

        self.acctNum = acctNum
예제 #2
0
def test_refresh_token_non_yaml(mock_get):
    """This function tests the refresh token method without yaml use."""
    qtrade = Questrade(token_yaml="access_token.yml")
    qtrade.refresh_access_token()
    assert set(qtrade.access_token.keys()) == set(
        ["access_token", "api_server", "expires_in", "refresh_token", "token_type"]
    )
    assert qtrade.access_token["api_server"] == "https://questrade.api"
예제 #3
0
def test_refresh_token_non_yaml(mock_get):
    """This function tests the refresh token method.
    """
    qtrade = Questrade(token_yaml='access_token.yml')
    qtrade.refresh_access_token(from_yaml=False)
    assert set(qtrade.access_token.keys()) == set(['access_token', 'api_server', 'expires_in',
                                                   'refresh_token', 'token_type'])
    assert qtrade.access_token['api_server'] == 'https://questrade.api'
예제 #4
0
def test_get_historical_data(mock_get):
    """This function tests the get historical data method."""
    qtrade = Questrade(token_yaml="access_token.yml")
    historical_data = qtrade.get_historical_data("XYZ", "2018-08-01", "2018-08-02", "OneDay")
    assert len(historical_data) == 2
    assert len(historical_data[0]) == 8
    assert len(historical_data[1]) == 8
    assert historical_data[0]["start"] == "2018-08-01T01:00:00.000000-04:00"
    assert historical_data[1]["start"] == "2018-08-02T00:00:00.000000-04:00"
예제 #5
0
def test_get_access_token(mock_get):
    """This function tests the get access token method.
    """
    qtrade = Questrade(access_code='hunter2')
    assert set(qtrade.access_token.keys()) == set(['access_token', 'api_server', 'expires_in',
                                                   'refresh_token', 'token_type'])
    with pytest.raises(Exception) as e_info:
        _ = Questrade(access_code='hunter3')
        assert str(e_info.value) == 'Token type was not provided.'
예제 #6
0
def test_get_access_token(mock_get):
    """This function tests the get access token method."""
    qtrade = Questrade(access_code="hunter2")
    assert set(qtrade.access_token.keys()) == set(
        ["access_token", "api_server", "expires_in", "refresh_token", "token_type"]
    )
    with pytest.raises(Exception) as e_info:
        _ = Questrade(access_code="hunter3")
        assert str(e_info.value) == "Token type was not provided."
예제 #7
0
def test_get_historical_data(mock_get):
    """This function tests the get historical data method.
    """
    qtrade = Questrade(token_yaml='access_token.yml')
    historical_data = qtrade.get_historical_data('XYZ', '2018-08-01', '2018-08-02', 'OneDay')
    assert len(historical_data) == 2
    assert len(historical_data[0]) == 8
    assert len(historical_data[1]) == 8
    assert historical_data[0]['start'] == '2018-08-01T01:00:00.000000-04:00'
    assert historical_data[1]['start'] == '2018-08-02T00:00:00.000000-04:00'
예제 #8
0
def test_get_activity(mock_get):
    """This function tests the get account activities method."""
    qtrade = Questrade(token_yaml="access_token.yml")
    activities = qtrade.get_account_activities(123, "2018-08-07", "2018-08-10")
    assert activities[0]["action"] == "Buy"
    assert activities[0]["tradeDate"] == "2018-08-07T00:00:00.000000-04:00"
    assert len(activities) == 1
    assert len(activities[0]) == 14

    with pytest.raises(Exception):
        _ = qtrade.get_account_activities(987, "2018-08-07", "2018-08-10")
예제 #9
0
def test_get_activity(mock_get):
    """This function tests the get account activities method.
    """
    qtrade = Questrade(token_yaml='access_token.yml')
    activities = qtrade.get_account_activities(123, '2018-08-07', '2018-08-10')
    assert activities[0]['action'] == 'Buy'
    assert activities[0]['tradeDate'] == '2018-08-07T00:00:00.000000-04:00'
    assert len(activities) == 1
    assert len(activities[0]) == 14

    with pytest.raises(Exception):
        _ = qtrade.get_account_activities(987, '2018-08-07', '2018-08-10')
예제 #10
0
def get_cash_info(qt: Questrade, acct: int) -> str:
    bal_response = qt._send_message('get',
                                    'accounts/' + str(acct) + '/balances')
    temp = qt._send_message('get', 'accounts/' + str(acct) + '/positions')
    print(temp)
    try:
        cash = round(bal_response['perCurrencyBalances'][0]['cash'], 2)
    except Exception:
        raise Exception
    result = '{F2}Cash{F1}: $'
    result += '{:.2f}'.format(cash)
    result += '{/F}'
    return result
예제 #11
0
def test_get_ticker_information(mock_get):
    """This function tests the get ticker information method."""
    qtrade = Questrade(token_yaml="access_token.yml")
    ticker_info_single = qtrade.ticker_information("XYZ")
    assert len(ticker_info_single) == 34
    assert ticker_info_single["symbol"] == "XYZ"
    assert ticker_info_single["marketCap"] == 275784564

    ticker_info_multiple = qtrade.ticker_information(["XYZ", "ABC"])
    assert len(ticker_info_multiple) == 2
    assert len(ticker_info_multiple[0]) == 34
    assert len(ticker_info_multiple[1]) == 34
    assert ticker_info_multiple[0]["symbol"] == "XYZ"
예제 #12
0
 def __init__(self, db=False, qtrade=False, ib=False):
     self.sql = SqlMapper()
     self.ib = IB()
     self.binance = Client()
     if qtrade:
         self.qtrade = Questrade(
             token_yaml=
             'C:/Users/haseab/Desktop/Python/PycharmProjects/FAB/local/Workers/access_token.yml',
             save_yaml=True)
         print('Connected to Questrade API')
     if db:
         self.conn = self.sql.connect_psql()
     if ib:
         print(self.ib.connect('127.0.0.1', 7496, 104))
예제 #13
0
def test_get_positions(mock_get):
    """This function tests the get account positions method."""
    qtrade = Questrade(token_yaml="access_token.yml")
    positions = qtrade.get_account_positions(123)
    assert positions[0]["symbol"] == "XYZ"
    assert positions[1]["symbol"] == "ABC"
    assert positions[0]["currentMarketValue"] == 3120
    assert positions[1]["currentMarketValue"] == 4000
    assert len(positions) == 2
    assert len(positions[0]) == 12
    assert len(positions[1]) == 12

    with pytest.raises(Exception):
        _ = qtrade.get_account_positions(987)
예제 #14
0
def test_get_ticker_information(mock_get):
    """This function tests the get ticker information method.
    """
    qtrade = Questrade(token_yaml='access_token.yml')
    ticker_info_single = qtrade.ticker_information('XYZ')
    assert len(ticker_info_single) == 34
    assert ticker_info_single['symbol'] == 'XYZ'
    assert ticker_info_single['marketCap'] == 275784564

    ticker_info_multiple = qtrade.ticker_information(['XYZ', 'ABC'])
    assert len(ticker_info_multiple) == 2
    assert len(ticker_info_multiple[0]) == 34
    assert len(ticker_info_multiple[1]) == 34
    assert ticker_info_multiple[0]['symbol'] == 'XYZ'
예제 #15
0
def test_get_balances(mock_get):
    """This function tests the get account balances method."""
    qtrade = Questrade(token_yaml="access_token.yml")
    balances = qtrade.get_account_balances(123)
    assert len(balances) == 4
    assert list(balances.keys()) == [
        "perCurrencyBalances",
        "combinedBalances",
        "sodPerCurrencyBalances",
        "sodCombinedBalances",
    ]

    with pytest.raises(Exception):
        _ = qtrade.get_account_positions(987)
예제 #16
0
def test_get_quote(mock_get):
    """This function tests the get quote method."""
    qtrade = Questrade(token_yaml="access_token.yml")
    quote_single = qtrade.get_quote("XYZ")
    assert len(quote_single) == 21
    assert quote_single["high52w"] == 25.00
    assert quote_single["symbolId"] == 1234567

    quote_multiple = qtrade.get_quote(["XYZ", "ABC"])
    assert len(quote_multiple) == 2
    assert len(quote_multiple[0]) == 21
    assert len(quote_multiple[1]) == 21
    assert quote_multiple[0]["high52w"] == 25.00
    assert quote_multiple[1]["high52w"] == 25.00
예제 #17
0
def test_get_quote(mock_get):
    """This function tests the get quote method.
    """
    qtrade = Questrade(token_yaml='access_token.yml')
    quote_single = qtrade.get_quote('XYZ')
    assert len(quote_single) == 21
    assert quote_single['high52w'] == 25.00
    assert quote_single['symbolId'] == 1234567

    quote_multiple = qtrade.get_quote(['XYZ', 'ABC'])
    assert len(quote_multiple) == 2
    assert len(quote_multiple[0]) == 21
    assert len(quote_multiple[1]) == 21
    assert quote_multiple[0]['high52w'] == 25.00
    assert quote_multiple[1]['high52w'] == 25.00
예제 #18
0
파일: temp.py 프로젝트: ikubetoomuzik/qt
def get_cash_info(qt: Questrade, acct: int) -> str:
    bal_response = qt._send_message('get', 'accounts/' + str(acct) + '/balances')
    out_csv_with_timestamp(CASH_OUTPUT, bal_response['perCurrencyBalances'].copy());
    # temp = qt._send_message('get', 'accounts/' + str(acct) + '/positions')
    # print(temp);
    try:
        cash = round(bal_response['perCurrencyBalances'][0]['cash'], 2);
    except Exception:
        raise Exception;
    return F"{{F2}}Cash{{F1}}: ${cash:.2f}{{/F}}";
예제 #19
0
def test_init_via_yaml():
    """This function tests when the class is initiated via yaml file.
    """
    qtrade = Questrade(token_yaml='access_token.yml')
    assert set(qtrade.access_token.keys()) == set(['access_token', 'api_server', 'expires_in',
                                                   'refresh_token', 'token_type'])
    assert qtrade.access_token['access_token'] == 'hunter2'
    assert qtrade.access_token['api_server'] == 'www.api_url.com'
    assert qtrade.access_token['expires_in'] == 1234
    assert qtrade.access_token['refresh_token'] == 'hunter2'
    assert qtrade.access_token['token_type'] == 'Bearer'
예제 #20
0
def test_init_via_yaml():
    """This function tests when the class is initiated via yaml file."""
    qtrade = Questrade(token_yaml="access_token.yml")
    assert set(qtrade.access_token.keys()) == set(
        ["access_token", "api_server", "expires_in", "refresh_token", "token_type"]
    )
    assert qtrade.access_token["access_token"] == "hunter2"
    assert qtrade.access_token["api_server"] == "http://www.api_url.com"
    assert qtrade.access_token["expires_in"] == 1234
    assert qtrade.access_token["refresh_token"] == "hunter2"
    assert qtrade.access_token["token_type"] == "Bearer"
예제 #21
0
class QuestradeClient:
    TICKER = "SPY"

    def __init__(self, token_yaml):
        self.yaml_path = token_yaml
        self.client = Questrade(token_yaml=token_yaml)
        self.refresh_access_token()

    def refresh_access_token(self):
        self.client.refresh_access_token(from_yaml=True,
                                         yaml_path=self.yaml_path)

    def get_nope(self):
        call_option_filters = []
        put_option_filters = []
        chain = self.client.get_option_chain(self.TICKER)
        quote = self.client.get_quote(self.TICKER)
        underlying_id = quote["symbolId"]

        for optionChain in chain["optionChain"]:
            exp_date = optionChain["expiryDate"]
            call_option_filters.append({
                "optionType": "Call",
                "expiryDate": exp_date,
                "underlyingId": underlying_id,
            })
            put_option_filters.append({
                "optionType": "Put",
                "expiryDate": exp_date,
                "underlyingId": underlying_id,
            })

        call_option_quotes = self.client.get_option_quotes(
            call_option_filters, [])
        put_option_quotes = self.client.get_option_quotes(
            put_option_filters, [])

        total_call_delta = sum(
            map(lambda q: q["volume"] * q["delta"],
                call_option_quotes["optionQuotes"]))
        total_put_delta = sum(
            map(lambda q: q["volume"] * q["delta"],
                put_option_quotes["optionQuotes"]))

        try:
            nope = (
                (total_call_delta + total_put_delta) * 10000) / quote["volume"]
        except ZeroDivisionError:
            curr_dt = datetime.now().strftime("%Y-%m-%d at %H:%M:%S")
            with open("logs/errors.txt", "a") as f:
                f.write(f'No volume data on {quote["symbol"]} | {curr_dt}\n')
            return [0, 0]

        return [nope, quote["lastTradePrice"]]
예제 #22
0
파일: temp.py 프로젝트: ikubetoomuzik/qt
def gen_string():
    # Defining the token location.
    access_info = getenv('HOME') + '/.config/questrade/access_token.yml';
    # Start the link using loaded conf.
    qt = Questrade(token_yaml=access_info);
    # we try up to three times to make requests.
    for _ in range(3):
        try:
            # Only have one account so we grab first entry.
            acct = qt.get_account_id()[0];
            # Get the info for all positions held.
            positions = get_position_info(qt, acct);
            # Get the specific cash balance info.
            cash = get_cash_info(qt, acct);
            break;
        except:
            # If the initial request fails then we refresh and try again.
            qt.refresh_access_token();
            # Save our newly generated token for next time.
            qt.save_token_to_yaml(yaml_path=access_info);
            continue;
    # then we print the result
    print(positions + cash, end = '');
예제 #23
0
import json
from datetime import date
from qtrade import Questrade
from decimal import Decimal
from forex_python.converter import CurrencyRates
import mysql.connector
from mysql.connector import Error
import config

#---connect to questrade
qtrade = Questrade(token_yaml='/home/ec2-user/token.yaml')
qtrade.refresh_access_token(from_yaml=True)
account_ids = qtrade.get_account_id()
positions = []
#---/connect to questrade

#----Connect to DB
db = mysql.connector.connect(host=config.DATABASE_CONFIG['host'],
                             user=config.DATABASE_CONFIG['user'],
                             passwd=config.DATABASE_CONFIG['password'],
                             database=config.DATABASE_CONFIG['database'])
mycursor = db.cursor()
#----/Connect to DB

#----Get info from Questrade

for account in account_ids:
    print(account)
    temp = qtrade.get_account_positions(account_id=account)
    positions = positions + temp
#----/Get info from Questrade
예제 #24
0
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
from qtrade import Questrade
from twilio.rest import Client
from pyeasyga import pyeasyga  # Genetic algorithms
import numpy as np
import random
import collections
import json
from datetime import date

with open('keys.json') as f:
    setting_keys = json.load(f)

try:
    qtrade = Questrade(access_code=setting_keys['access_code'])
except:
    qtrade = Questrade(token_yaml='./access_token.yml')
    qtrade.refresh_access_token(from_yaml=True)

portfolio_target = {
    'XEC.TO': 0.05,
    'XEF.TO': 0.175,
    'ZAG.TO': 0.10,
    'ZLB.TO': 0.25,
    'ZSP.TO': 0.275,
    'XMU.TO': 0.15
}

yearly_withdrawal = 0.04  # 4 pecent
from qtrade import Questrade

from utils import qtrade_date_range, dates_of_interest, account_activity

st.title("My Questrade Dashboard")

# Authenticate
st.write("Welcome! Let's start by authenticating you and your account.")
qtrade_token = "qtrade_token"
overwrite_token = st.text_input(
    "Should we look somewhere other than 'qtrade_token'?")
if overwrite_token:
    qtrade_token = overwrite_token
st.write(f"Looking for a qtrade token in env variable: {qtrade_token}")
try:
    qtrade = Questrade(access_code=os.getenv(qtrade_token))
    aapl, amzn = qtrade.ticker_information(["AAPL", "AMZN"])
    st.write("Authorization sucessful via qtrade_token")
except:
    try:
        qtrade = Questrade(token_yaml="access_token.yml")
        aapl, amzn = qtrade.ticker_information(["AAPL", "AMZN"])
        st.write("Authorization sucessful via access_token")
    except:
        try:
            qtrade.refresh_access_token(
                from_yaml=True, yaml_path="access_token.yml"
            )  # When Qtrade refreshes token, it kills the old credentials
            aapl, amzn = qtrade.ticker_information(["AAPL", "AMZN"])
            st.write("Authorization sucessful via refreshed access_token")
        except:
class QuestradeBot:
    def __init__(self, acctNum):
        # Initialize Questrade Instance
        if path.exists("./access_token.yml"):
            #print("first try in questrade")
            self.qtrade = Questrade(token_yaml='./access_token.yml')
            try:
                acct_list = self.qtrade.get_account_id()
                #print(acctNum in acct_list)
                assert acctNum in acct_list
            except:
                #print("first if statement")
                self.qtrade.refresh_access_token(from_yaml=True)
                self.qtrade = Questrade(token_yaml='./access_token.yml')
                try:
                    assert acctNum in self.qtrade.get_account_id()
                except:
                    #print("yml file removed!")
                    remove("./access_token.yml")
                    # get new access code
                    access_code = new_access_code()
                    self.qtrade = Questrade(access_code=access_code)
        else:
            #print("no yml file exist")
            access_code = new_access_code()
            self.qtrade = Questrade(access_code=access_code)
            try:
                accts_list = self.qtrade.get_account_id()
            except:
                while not isinstance(accts_list, list):
                    #print("in while loop")
                    access_code = new_access_code()
                    self.qtrade = Questrade(access_code=access_code)

        self.acctNum = acctNum

    def get_acct_id(self):
        return self.qtrade.get_account_id()

    def get_ticker_info(self, symbol: str):
        return self.qtrade.ticker_information(symbol)

    def get_acct_positions(self):
        return self.qtrade.get_account_positions(self.acctNum)

    def _get_account_activities(self):
        return self.qtrade.get_account_activities(self.acctNum)

    def get_usd_total_equity(self):
        balance = self.get_account_balance_summary()
        return balance.loc['USD', 'Total_Equity']

    def get_usd_total_mv(self):
        balance = self.get_account_balance_summary()
        return balance.loc['USD', 'Market_Value']

    def get_cad_total_equity(self):
        balance = self.get_account_balance_summary()
        return balance.loc['CAD', 'Total_Equity']

    def get_cad_total_mv(self):
        balance = self.get_account_balance_summary()
        return balance.loc['CAD', 'Market_Value']

    def get_usd_total_cost(self):
        positions = self.get_acct_positions()
        total_cost = 0
        for pos in positions:
            curr_cost = pos['totalCost']
            total_cost += curr_cost
        return total_cost

    def get_account_balance_summary(self):
        bal = self.qtrade.get_account_balances(self.acctNum)

        data = {
            'Currency': [],
            'Cash': [],
            'Market_Value': [],
            'Total_Equity': [],
            'Cash (%)': [],
            'Investment (%)': []
        }

        for x in bal['perCurrencyBalances']:
            data['Currency'].append(x['currency'])
            data['Cash'].append(x['cash'])
            data['Market_Value'].append(x['marketValue'])
            data['Total_Equity'].append(x['totalEquity'])
            if x['totalEquity'] != 0:
                data['Cash (%)'].append(
                    round(100 * x['cash'] / x['totalEquity'], 2))
                data['Investment (%)'].append(
                    round(100 * x['marketValue'] / x['totalEquity'], 2))
            else:
                data['Cash (%)'].append(0)
                data['Investment (%)'].append(0)

        df = pd.DataFrame(data)
        df.set_index('Currency', inplace=True)
        #print(tabulate(df, headers='keys'))
        return df

    def get_investment_summary(self):
        # p&l
        position_data = {
            'Symbol': [],
            'Description': [],
            'Currency': [],
            'Quantities': [],
            'Market Value': [],
            'Return (%)': [],
            'Portfolio (%)': []
        }
        total_market_value = self.get_usd_total_mv()
        total_costs = 0
        positions = self.qtrade.get_account_positions(self.acctNum)
        for position in positions:
            # handle daily execution for closeQuantity
            if position['openQuantity'] != 0:
                symbol = position['symbol']
                description = self.qtrade.ticker_information(
                    symbol)['description']
                qty = position['openQuantity']
                cmv = position['currentMarketValue']
                currency = self.qtrade.ticker_information(symbol)['currency']
                cost = position['totalCost']
                change = round(100 * (cmv - cost) / cost, 2)

                total_costs = total_costs + cost
                position_data['Symbol'].append(symbol)
                position_data['Description'].append(description)
                position_data['Currency'].append(currency)
                position_data['Quantities'].append(qty)
                position_data['Market Value'].append(cmv)
                position_data['Return (%)'].append(change)
                position_data['Portfolio (%)'].append(
                    round(100 * (cmv / total_market_value), 2))

        portfolio = pd.DataFrame(position_data)
        portfolio.set_index('Symbol', inplace=True)
        #portfolio.index.name = None
        #print(tabulate(portfolio))
        return portfolio

    def get_historical_dividend_income(self, period):
        # identify the first date for creation
        endDate = dt.date.today().strftime("%Y-%m-%d")
        startDate = dt.date.today() - dt.timedelta(days=period)
        dtrange = pd.date_range(startDate, endDate, freq='d')
        months = pd.Series(dtrange.month)
        starts, ends = months.ne(months.shift(1)), months.ne(months.shift(-1))
        startEndDates = pd.DataFrame({
            'month_starting_date':
            dtrange[starts].strftime('%Y-%m-%d'),
            'month_ending_date':
            dtrange[ends].strftime('%Y-%m-%d')
        })
        dateList = startEndDates.values.tolist()

        output = {}
        total_div_earned = 0

        for date in dateList:
            start = date[0]
            end = date[1]
            activities = self.qtrade.get_account_activities(
                self.acctNum, start, end)
            monthly_div = 0
            for activity in activities:
                if activity['type'] == 'Dividends':
                    monthly_div = monthly_div + activity['netAmount']
            output[dt.datetime.strptime(
                start, "%Y-%m-%d").strftime("%Y-%m")] = monthly_div
            total_div_earned = total_div_earned + monthly_div

        monthly_div_df = pd.DataFrame.from_dict(
            output, orient='index', columns=['Monthly_Dividend_Income'])

        return monthly_div_df

    def _monthly_return(self, assets):
        monthly_prices = pd.DataFrame()
        for asset in assets:
            monthly_prices[asset] = yf.download(asset,
                                                start=dt.datetime(2018, 1, 1),
                                                end=dt.datetime.today(),
                                                interval='1mo',
                                                progress=False)['Adj Close']

        monthly_returns = monthly_prices.pct_change()
        monthly_returns.dropna(inplace=True)

        return monthly_returns

    def _cumulative_returns(self, assets, weights):
        prices = pd.DataFrame()

        for symbol in assets:
            prices[symbol] = yf.download(symbol,
                                         start=dt.datetime(2018, 1, 1),
                                         end=dt.datetime.today(),
                                         interval='1mo',
                                         progress=False)['Adj Close']

        prices.dropna(inplace=True)
        monthly_returns = prices.pct_change()
        monthly_returns = monthly_returns.shift(-1)
        monthly_returns['port'] = monthly_returns.dot(weights)
        cum_returns = np.exp(np.log1p(monthly_returns['port']).cumsum())[:-1]
        return cum_returns

    def _cagr(self, assets, weights):
        cum_ret = self._cumulative_returns(assets, weights)
        first_value = cum_ret[0]
        last_value = cum_ret[-1]
        years = len(cum_ret.index) / 12
        cagr = (last_value / first_value)**(1 / years) - 1
        return cagr

    def _mdd(self, assets, weights):
        cum_ret = self._cumulative_returns(assets, weights)
        previous_peaks = cum_ret.cummax()
        drawdown = (cum_ret - previous_peaks) / previous_peaks
        port_mdd = drawdown.min()
        return port_mdd

    def calculate_portfolio_performance(self):

        BM_assets = ['SPY', 'IEF']
        BM_weights = np.array([0.6, 0.4])

        BM_cagr = round(self._cagr(BM_assets, BM_weights) * 100, 2)
        BM_mdd = round(self._mdd(BM_assets, BM_weights) * 100, 2)

        investments = self.get_investment_summary()

        port_assets = list(investments.index)
        port_weights = np.array(list(investments['Portfolio (%)'] / 100))
        port_cagr = round(self._cagr(port_assets, port_weights) * 100, 2)
        port_mdd = round(self._mdd(port_assets, port_weights) * 100, 2)

        stat = {
            'Portfolio': ['BenchMark', 'CurrentPortfolio'],
            'CAGR (%)': [BM_cagr, port_cagr],
            'MDD (%)': [BM_mdd, port_mdd]
        }

        stat_df = pd.DataFrame(stat)
        stat_df.set_index('Portfolio', inplace=True)

        return stat_df

    def strategy_allocation(self):
        # cash allocation
        # total equity - cash = allocatable amount
        total_equity = self.get_usd_total_equity()
        total_mv = self.get_usd_total_mv()
        curr_cash = total_equity - total_mv
        print(curr_cash)
        target_cash = total_equity * (self.cash_rate / 100)

        if target_cash < curr_cash:
            # invest more from curr_cash
            invest_amount = curr_cash - target_cash
            print("invest more from curr_cash")

        else:
            # sell some from investment to increase curr_cash
            new_market_value = total_mv - (target_cash - curr_cash)
            print("sell some from investment to increase curr_cash")
예제 #27
0
 def __init__(self, token_yaml):
     self.yaml_path = token_yaml
     self.client = Questrade(token_yaml=token_yaml)
     self.refresh_access_token()
예제 #28
0
def test_get_option_chain(mock_get):
    """This function tests the get historical data method."""
    qtrade = Questrade(token_yaml="access_token.yml")
    option_chain_data = qtrade.get_option_chain("XYZ")
    assert len(option_chain_data) == 1
    assert len(option_chain_data["options"]) == 1
예제 #29
0
def test_get_account_id(mock_get):
    """This function tests the account ID function.
    """
    qtrade = Questrade(token_yaml='access_token.yml')
    acct_id = qtrade.get_account_id()
    assert acct_id == [123, 456]
예제 #30
0
def test_init_via_incomplete_yaml():
    """This function tests when the class is initiated via incomplete yaml file.
    """
    with pytest.raises(Exception) as e_info:
        _ = Questrade(token_yaml='access_token.yml')
        assert str(e_info.value) == 'Refresh token was not provided.'