示例#1
0
def get_historical_fundamentals(ticker: str, d: date,
                                manager: CollectionManager):
    """
    Gets all of the fundamental data for a ticker before some date and after
    :param ticker: stock ticker
    :param d: date
    :param manager: collection manager for the fundamentals database
    :return: past fundamentals, announcement dates, and future (test) fundamentals
    """
    current_day = dt(d.year, d.month, d.day)
    allTickersFundamentals = manager.find({
        'ticker': ticker,
        'date': {
            '$lte': current_day
        }
    }).sort_values('date')
    test = manager.find({
        'ticker': ticker,
        'date': {
            '$gte': current_day
        }
    }).sort_values('date')

    return allTickersFundamentals[features], [
        announce.date()
        for announce in allTickersFundamentals['date'].tolist()
    ], test
    def __init__(self,
                 start,
                 capital,
                 model,
                 loss,
                 p=0.015,
                 sharePer=0.5,
                 stop='2018-02-05'):
        self.manager = CollectionManager('5Y_technicals', 'AlgoTradingDB')

        self.dates = self.manager.dates()
        self.startIndex = self.dates.index(start) + 1
        self.stop = stop
        self.stopIndex = self.dates.index(stop)

        self.suggestor = SectorSuggestor(self.startIndex)
        self.suggestor.build_sector_NN()

        self.sectorModels = {}
        self.portfolio = {}

        self.loss = loss
        self.model = model
        self.p = p
        self.sharePer = sharePer
        self.startDate = date
        self.startingCapital = capital
示例#3
0
def calculate_performance(ticker, dates1: list, dates2: list):
    """
    Gets how much the stock has changed since the last
    quarter reportings.
    :param ticker: stock ticker
    :param date1: beginining of the quarter
    :param date2: end of the quarter
    :return: percent change in stock price
    """
    ticker = ticker.lower()
    manager = CollectionManager('5Y_technicals', 'AlgoTradingDB')

    prices = manager.find({'ticker': ticker})
    dates = [
        dt.strptime(priceDate, '%Y-%m-%d').date()
        for priceDate in prices['date']
    ]

    pricesStart = [
        prices[prices['date'] == str(d1)]['vwap'].values[0]
        for d1 in get_next_trading_day(dates, dates1)
    ]
    pricesEnd = [
        prices[prices['date'] == str(d2)]['vwap'].values[0]
        for d2 in get_next_trading_day(dates, dates2)
    ]
    manager.close()

    performances = [((p[0] - p[1]) / p[0])
                    for p in zip(pricesStart, pricesEnd)]
    return performances
示例#4
0
 def __init__(self, manager: CollectionManager, agent: InvestorAgent,
              startDay: int):
     self.timeperiod = manager.dates()
     self.manager = manager
     self.agent = agent
     self.day = startDay
     self.currentDate = self.timeperiod[self.day]
示例#5
0
def async_grid(args):
    """
    Runs grid search to see parameter values
    :param args: args for the trade method
    :return: None
    """
    manager = CollectionManager('grid_search', 'AlgoTradingDB')
    try:
        stock = args[-1]
        result = trade(*args)
        log(f"{args} SUCCESS!\n{result}\n")
        save_results(result, manager, stock)

    except Exception as e:
        log(f"{args} failed {e}")

    manager.close()
def get_data_by_sector(stocks, sector):
    """
    Gets price data from the database for a given sector
    :param stocks: list of stocks
    :param sector: given sector
    :return: writes to CSV
    """
    manager = CollectionManager('5Y_technicals', 'AlgoTradingDB')
    dates = manager.dates()
    data = pd.DataFrame()
    for stock in stocks:
        stocksData = avg_price_timeseries(manager, stock.lower(), dates)
        if len(stocksData) != 1259:
            continue
        data[stock] = stocksData
    data.to_csv('sectorAnalysis/{0}.csv'.format(sector))
    manager.close()
 def run_simulation(self):
     """
     Runs the full trading framework.
     :return: None
     """
     warnings.filterwarnings("ignore")
     sectors = []
     for day in range(self.startIndex, self.stopIndex):
         print(f'--------DAY: {day - self.startIndex +1}--------')
         # Suggest a Sector
         sectorIDtoInvestIn = self.suggestor.predict_sector(day)
         sectorToInvestIn = id_to_sector[sectorIDtoInvestIn]
         print(f'I suggest investing in the {sectorToInvestIn} sector')
         if len(sectors) != 0:
             if sectors[-1] == sectorToInvestIn:
                 print('Already holding positions in this sector...')
                 sectors.append(sectorToInvestIn)
                 continue
         sectors.append(sectorToInvestIn)
         # Suggest top three stocks in this market
         if sectorToInvestIn not in self.sectorModels:
             stockModel = StockSuggestor(sectorToInvestIn, day,
                                         self.dates[day])
             self.sectorModels[sectorToInvestIn] = stockModel
             stockModel.build_network()
         else:
             stockModel = self.sectorModels[sectorToInvestIn]
         stockToInvestIn, untilThisDate = stockModel.predict_stock(
             self.dates[day])
         print(
             f'I suggest investing in the following stock: {stockToInvestIn}'
         )
         self.trade_stock(stockToInvestIn.lower(), self.startDate,
                          self.dates[day + 50])
     print(f'SECTORS INVESTED IN: {sectors}')
     resultManager = CollectionManager('trading_results', 'AlgoTradingDB')
     resultManager.insert(self.portfolio)
示例#8
0
    def fit_and_plot(self, series, dates, window=0):
        """
        Fits the ARIMA model and plots the prediction results
        :param series: time series
        :param dates: dates for fitting
        :param window: sliding window
        :return: None
        """
        manager = CollectionManager('5Y_technicals', 'AlgoTradingDB')
        size = len(dates) - 518
        train, test = series[0:size], series[size:len(series)]
        predictions = list()
        w = 0
        for t in range(len(test) + 1):
            model = ARIMA(train, order=(self.p, self.d, self.q))
            model_fit = model.fit(disp=0)
            output = model_fit.forecast()
            yhat = output[0][0]
            predictions.append(yhat)
            obs = yhat
            if w == window and t != len(test):
                train.append(test[t])
                w = 0
            else:
                train.append(obs)
                w += 1

        error = mean_squared_error(test, predictions[:len(test)])
        print(error)
        actual, days = create_timeseries(manager, self.ticker)
        days = [days[x] for x in range(0, len(days), 2)]
        actual = [actual[y] for y in range(0, len(actual), 2)]
        predictions = [predictions[p] for p in range(0, len(predictions), 2)]

        plt.plot(days, actual, color='black', label='Actual')
        plt.plot(days[1000:],
                 predictions[:-1],
                 color='red',
                 label='LSTM predictions')
        plt.xlabel('day')
        plt.title(self.ticker)
        plt.ylabel('price')
        plt.legend(loc=2)
        plt.savefig('plots/ARIMA/ARIMA_{0}_predictions.pdf'.format(
            self.ticker))
        plt.show()
示例#9
0
def add_fundamentals_to_db():
    """
    Adds the fundamental data to the database from a json file
    :return:None
    """
    fundFile = 'sectorAnalysis/fundamentals/combinedFundamentals.json'
    funds = pd.read_json(fundFile)

    manager = CollectionManager('10y_Fundamentals', 'AlgoTradingDB')

    for index, row in funds.iterrows():
        document = row.to_dict()
        manager.insert(document, is_dictionary=True)
    manager.close()
示例#10
0
from DataHandler.putAndGetData import get_stock_data,add_data
from DataHandler.mongoObjects import CollectionManager,MongoDocument
from pymongo import MongoClient
import DataHandler.apiCall as api


if __name__ == '__main__':
    manager = CollectionManager('daily_technicals', 'AlgoTradingDB')
    add_data(manager,function=api.iex_1d,unwantedFields=['label','average','changeOverTime',
                                                'marketAverage','marketChangeOverTime'])
示例#11
0
    features = list(dataset.columns.values)
    for feature in features:
        series = dataset[feature]
        diff = list()
        for i in range(interval, len(series)):
            value = series[i] - series[i - interval]
            diff.append(value)
        differenced[feature] = diff
    return differenced['price']


startDay = 1153
stopDay = 1258
stocks = ['googl','nvda','vz','wmt']
model = 'LSTM'
manager = CollectionManager('5Y_technicals','AlgoTradingDB')
dates = manager.dates()

actualPrice = avg_price_timeseries(manager, 'spy', dates[startDay:stopDay])
diff_price = pd.DataFrame()
diff_price['price'] = actualPrice
diff_price = list(diff(diff_price))

portfolioTrades = f'/Users/adelekap/Documents/capstone_algo_trading/comparison/{model}/trades/'

capitalDates = []
all = pd.DataFrame()
for stock in stocks:
    stockData = pd.read_csv(portfolioTrades+stock+'.csv').iloc[:(stopDay-startDay-4),:]
    all[stock] = stockData['CurrentCapital']
    capitalDates = stockData['Date'].unique()
示例#12
0
def trade(loss,
          statsModel,
          p,
          sharePer,
          startDate,
          startingCapital,
          stop,
          ticker,
          epochs=1,
          neurons=1,
          plotting=False):
    """
    TRADES a given stock for a period of time
    :param loss: amount of loss willing to take
    :param statsModel: string of the predictive model to be used
    :param p: p value for the strategy
    :param sharePer: share percentage for the strategy
    :param startDate: date to start YYYY-MM-DD
    :param startingCapital: capital to start trading with
    :param stop: stop date YYYY-MM-DD
    :param ticker: stock ticker
    :param plotting: whether you want to plot or not
    :return: results (dictionary)
    """
    logger = Logger('comparison/{0}/trades/{1}.csv'.format(statsModel, ticker))
    logger.log(
        'Date,Open/Close,PositionNum,Type,Price,Shares,Investment,Profit,CurrentCapital'
    )
    positionOpenNum = 0
    positionCloseNum = 0
    warnings.filterwarnings("ignore")
    """Initialize Environment"""
    # Data
    manager = CollectionManager('5Y_technicals', 'AlgoTradingDB')

    # Time
    dates = manager.dates()
    currentDate = startDate
    startDay = dates.index(currentDate)
    stopDay = dates.index(stop)
    # bar = utils.ProgressBar(stopDay - startDay)

    results = {'p': p, 'sharePer': sharePer}

    # Predictive Model
    if statsModel == 'Arima':
        model = ArimaModel(1, 1, 0, ticker)
        k = 5
    if statsModel == 'LSTM':
        model = NeuralNet(ticker, manager, startDay)
        model.create_network()
        model.train_network()
        k = 1
    if statsModel == 'SVM':
        model = SVM(100, 0.01, ticker, manager, startDay)
        model.fit()
        k = 5

    # Investor, Strategy and Trading Environment
    stopLoss = (1 - loss) * startingCapital
    tradingStrategy = Strategy(model, manager, ticker, currentDate, stopLoss,
                               p)
    investor = InvestorAgent(startingCapital, tradingStrategy, startDay)
    environment = Environment(manager, investor, startDay)

    # Simulate Trading Environment
    print(f'Starting Trading {ticker}')
    for d in range(startDay, stopDay):
        if len(investor.positions):
            for position in investor.positions:
                currentPrice = investor.check_price(environment.currentDate)
                actionDay = utils.laterDate(position.startDate,
                                            position.holdTime)
                if environment.currentDate == actionDay or position.at_trigger_point(
                        currentPrice):
                    sellMessage = position.sell(investor, currentPrice)
                    logger.log(
                        f'{environment.currentDate},close,{position.id},' +
                        sellMessage)
                    positionCloseNum += 1

        T = investor.strategy.arithmetic_returns(k, environment.day)
        sig = investor.signal(T)
        if sig != 0:
            message = investor.strategy.make_position(investor,
                                                      sig,
                                                      environment.currentDate,
                                                      stopLoss,
                                                      sharePer,
                                                      posNum=positionOpenNum)
            if message != None:
                logger.log(
                    f'{environment.currentDate},open,{positionOpenNum},' +
                    message)
            positionOpenNum += 1
        environment.update_total_assets(investor)
        if d != stopDay - 1:
            environment.increment_day(investor.strategy)
            # bar.progress()
    """PLOTTING"""
    print('PLOTTING')
    actualPrice = avg_price_timeseries(manager, ticker,
                                       dates[startDay:stopDay])
    if not len(investor.capitalHistory):
        expReturn = 0
    else:
        expReturn = round(
            ((investor.totalAssetHistory[len(investor.totalAssetHistory) - 1] -
              startingCapital) / startingCapital) * 100)
    gain = str(expReturn) + '%'

    possible = round(
        ((actualPrice[-1] - actualPrice[0]) / actualPrice[0]) * 100, 1)
    mdd = utils.MDD(investor.totalAssetHistory)
    if plotting:
        utils.plot_capital(investor.totalAssetHistory,
                           dates[startDay:stopDay],
                           ticker,
                           actualPrice,
                           gain,
                           mdd,
                           possible,
                           model=statsModel)
    results['MDD'] = mdd
    results['return'] = expReturn
    results['possible'] = possible

    etf = avg_price_timeseries(manager, 'spy', dates[startDay:stopDay])
    print(f'RETURN ON INVESTMENT: {expReturn}')
    print(f'Number of Positions Opened: {positionOpenNum}')
    print(f'Number of Positions Closed:{positionCloseNum}')
    print(
        f'Sharpe Ratio = {sharpe_ratio(investor.totalAssetHistory, etf, possible)}'
    )

    manager.close()
    return (results)
示例#13
0
class TradingFramework():
    def __init__(self,
                 start,
                 capital,
                 model,
                 loss,
                 p=0.015,
                 sharePer=0.5,
                 stop='2018-02-05'):
        self.manager = CollectionManager('5Y_technicals', 'AlgoTradingDB')

        self.dates = self.manager.dates()
        self.startIndex = self.dates.index(start) + 1
        self.stop = stop
        self.stopIndex = self.dates.index(stop)

        self.suggestor = SectorSuggestor(self.startIndex)
        self.suggestor.build_sector_NN()

        self.sectorModels = {}
        self.portfolio = {}

        self.loss = loss
        self.model = model
        self.p = p
        self.sharePer = sharePer
        self.startDate = date
        self.startingCapital = capital

    def run_simulation(self):
        """
        Runs the full trading framework.
        :return: None
        """
        warnings.filterwarnings("ignore")
        sectors = []
        for day in range(self.startIndex, self.stopIndex):
            print(f'--------DAY: {day - self.startIndex +1}--------')
            # Suggest a Sector
            sectorIDtoInvestIn = self.suggestor.predict_sector(day)
            sectorToInvestIn = id_to_sector[sectorIDtoInvestIn]
            print(f'I suggest investing in the {sectorToInvestIn} sector')
            if len(sectors) != 0:
                if sectors[-1] == sectorToInvestIn:
                    print('Already holding positions in this sector...')
                    sectors.append(sectorToInvestIn)
                    continue
            sectors.append(sectorToInvestIn)
            # Suggest top three stocks in this market
            if sectorToInvestIn not in self.sectorModels:
                stockModel = StockSuggestor(sectorToInvestIn, day,
                                            self.dates[day])
                self.sectorModels[sectorToInvestIn] = stockModel
                stockModel.build_network()
            else:
                stockModel = self.sectorModels[sectorToInvestIn]
            stockToInvestIn, untilThisDate = stockModel.predict_stock(
                self.dates[day])
            print(
                f'I suggest investing in the following stock: {stockToInvestIn}'
            )
            self.trade_stock(stockToInvestIn.lower(), self.startDate,
                             self.dates[day + 50])
        print(f'SECTORS INVESTED IN: {sectors}')
        resultManager = CollectionManager('trading_results', 'AlgoTradingDB')
        resultManager.insert(self.portfolio)

    def trade_stock(self, ticker, start, stop):
        self.portfolio[ticker] = (trade(self.loss,
                                        self.model,
                                        self.p,
                                        self.sharePer,
                                        start,
                                        self.startingCapital,
                                        stop,
                                        ticker,
                                        plotting=True))
示例#14
0
def get_all_fundamentals(stocks: list, tradeDate: date):
    """
    Gets all of the fundamentals for a list of tickers and list of quarters
    :param tickers: stocks
    :param quarters: list of quarters
    :param final: whether this is a final prediction
    :return: Xs and ys
    """
    manager = CollectionManager('10y_Fundamentals', 'AlgoTradingDB')
    tickers_set = set(stocks)
    all_fundamental_tickers = set(manager.find({})["ticker"])
    tickers = list(tickers_set.intersection(all_fundamental_tickers))

    allFundamentals = pd.DataFrame()
    performances = pd.DataFrame()
    quarters = 17
    allTest = pd.DataFrame()
    testDates = []
    for ticker in tickers:
        data, announcementDates, test = get_historical_fundamentals(
            ticker, tradeDate, manager)
        nextAnnouncementDates = announcementDates[1:] + [
            dt.strptime('2018-02-05', '%Y-%m-%d').date()
        ]

        performance = calculate_performance(ticker, announcementDates,
                                            nextAnnouncementDates)
        if len(testDates) == 0:
            testDates = test['date'].tolist()

        if len(performance) != 17:
            performance = performance[len(performance) - 17:]
            performances[ticker] = performance
        else:
            performances[ticker] = performance

        for index, funds in data.iterrows():
            tempDF = pd.DataFrame()
            tempDF['fundamentals'] = list(funds)[:-1]
            tempDF['ticker'] = [ticker for i in range(len(funds) - 1)]
            tempDF['quarter'] = [index for j in range(len(funds) - 1)]
            allFundamentals = pd.concat([allFundamentals, tempDF])

        for index, testFunds in test.iterrows():
            temp = pd.DataFrame()
            temp['fundamentals'] = list(testFunds)[:-1]
            temp['ticker'] = [ticker for k in range(len(testFunds) - 1)]
            temp['quarter'] = [index for l in range(len(testFunds) - 1)]
            allTest = pd.concat([allTest, temp])

    manager.close()

    trainingData = []
    for quarter in range(quarters):
        q = []
        for ticker in tickers:
            tickerdata = allFundamentals[allFundamentals['ticker'] == ticker]
            quarterdata = tickerdata[tickerdata['quarter'] ==
                                     quarter]['fundamentals']
            q.append(quarterdata.tolist())
        trainingData.append(np.array(q))
    trainingDataX = np.array(trainingData)
    trainingDataY = find_best_stock(performances)

    allTestY = []
    quarterLen = len(allTest['quarter'].unique())
    if quarterLen == 1:
        fix = allTest.copy()
        fix['quarter'] = [2 for i in range(len(fix))]
        allTest = pd.concat([allTest, fix])
    for testQuarter in range(2):
        testQ = []
        for tick in tickers:
            tickData = allTest[allTest['ticker'] == tick]
            testQuarterData = tickData[tickData['quarter'] ==
                                       testQuarter]['fundamentals']
            if testQuarterData.shape[0] != 15:
                print('ERROR ' + tick)
            testQ.append(testQuarterData.tolist()[:-4])
        allTestY.append(np.array(testQ))

    return trainingDataX, trainingDataY, np.array(allTestY), testDates, tickers
示例#15
0
from environment import trade
from utils import save_results
import pandas as pd
from DataHandler.mongoObjects import CollectionManager

if __name__ == '__main__':
    stocks = [
        symbol.lower() for symbol in list(pd.read_csv('stocks.csv')['Symbol'])
    ]
    manager = CollectionManager('trading_results', 'AlgoTradingDB')

    loss = 0.30
    startingCapital = 15000
    p = 0.025
    sharePer = 0.17
    startDate = '2018-01-03'
    stopDate = '2018-02-05'

    models = ['Arima', 'LSTM']
    epochs = 10
    neurons = 4

    for stock in stocks:
        for model in models:
            result = trade(loss,
                           model,
                           p,
                           sharePer,
                           startDate,
                           startingCapital,
                           stopDate,