Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html ng-app="fideligard">
<head>
<title>Fideligard</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="styles.css">
<script src="https://cdn.jsdelivr.net/tether/1.3.7/tether.min.js"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/lodash/4.16.2/lodash.min.js"></script>
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Fideligard Historical Portfolio Simulator</a>
</div>

<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Log In</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container">
<div class="row">
<div class="col-sm-4">
<div ui-view="ticker"></div>
</div>
<div class="col-sm-8">
<div class="row">
<div class="col-xs-10 col-xs-offset-1">
<div ui-view="date"></div>
</div>
</div>
<div class="col-xs-10 col-xs-offset-1">
<div class="row">
<div class="col-xs-8 col-xs-offset-2">
<ul class="nav nav-tabs">
<li role="presentation"><a ui-sref="stocks.portfolio">Portfolio</a></li>
<li role="presentation"><a ui-sref="stocks.trade">Trade</a></li>
<li role="presentation"><a ui-sref="stocks.transactions">Transactions</a></li>
</ul>
</div>
</div>
<div ui-view="main"><h3><br>Data Loading...</h3></div>
</div>
</div>
</div>
<script src="js/app.js"></script>
<script src="js/services/date_service.js"></script>
<script src="js/services/stock_service.js"></script>
<script src="js/services/portfolio_service.js"></script>
<script src="js/filters/ticker.js"></script>
<script src="js/controllers/stocks_controller.js"></script>
<script src="js/controllers/trade_controller.js"></script>
<script src="js/controllers/transactions_controller.js"></script>
<script src="js/controllers/portfolio_controller.js"></script>
<script src="js/directives/stock_index_row.js"></script>
</body>
</html>
72 changes: 72 additions & 0 deletions js/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
var app = angular.module('fideligard', ['ui.router']);

app.run(function($rootScope){
$rootScope.$on("$stateChangeError", console.log.bind(console));
});


app.config(function($stateProvider, $urlRouterProvider){

$urlRouterProvider.otherwise('/');

$stateProvider

.state('stocks', {
url: '',
views: {
'date': {
templateUrl: 'js/templates/date.html',
controller: 'StocksCtrl'
},
'ticker': {
templateUrl: 'js/templates/ticker.html',
controller: 'StocksCtrl'
},
'main': {
templateUrl: 'js/templates/main.html'
}
},
resolve: {
stocks: ['StockService', function(StockService){
return StockService.getStocks();
}],
dates: ['StockService', function(StockService){
return StockService.allDates();
}]
}
})

.state('stocks.portfolio', {
url: '/portfolio',
views: {
"main@" : {
templateUrl: 'js/templates/portfolio.html',
controller: 'PortfolioCtrl'
}
}
})
.state('stocks.trade', {
url: '/trade/:stock',
params: {
symbol: null,
price: null,
date: null
},
views: {
"main@" : {
templateUrl: 'js/templates/trade.html',
controller: 'TradeCtrl'
}
}
})
.state('stocks.transactions', {
url: '/transactions',
views: {
"main@" : {
templateUrl: 'js/templates/transactions.html',
controller: 'TransactionsCtrl'
}
}
})

});
56 changes: 56 additions & 0 deletions js/controllers/portfolio_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
app.controller('PortfolioCtrl',
['stocks', '$scope', 'StockService', 'DateService', 'dates', '$stateParams', 'PortfolioService', "$state",
function(stocks, $scope, StockService, DateService, dates, $stateParams, PortfolioService, $state) {

$scope.dateInfo = DateService.getDateInfo();
$scope.portfolio = PortfolioService.getPortfolio();
$scope.allDates = StockService.allDates();

$scope.getDaysBack = function(symbol, days, currentBasis) {
var currentIndex = _.indexOf($scope.allDates, $scope.dateInfo.currentDate)
var prevIndex = currentIndex - days;
if (prevIndex < 0) {
prevIndex = 0;
}
var prevDate = $scope.allDates[prevIndex];
var pastPortfolio = $scope.portfolio[prevDate];
if (symbol === "CASH") {
var prevValue = pastPortfolio.cash.quantity
var prevBasis = pastPortfolio.cash.quantity
} else {
var prevValue = pastPortfolio[symbol].quantity * pastPortfolio[symbol].currentPrice;
var prevBasis = pastPortfolio[symbol].costBasis
}
return prevValue - prevBasis;
}

$scope.getPortValue = function(day){
if (day === undefined) {
day = $scope.dateInfo.currentDate;
}
var sum = 0;
_.forEach($scope.portfolio[day], function(holding){
sum += holding.currentPrice * holding.quantity
})
return sum
}

$scope.getPrevValue = function(days) {
var currentIndex = _.indexOf($scope.allDates, $scope.dateInfo.currentDate)
var prevIndex = currentIndex - days;
if (prevIndex < 0) {
prevIndex = 0;
}
var prevDate = $scope.allDates[prevIndex];
return $scope.getPortValue(prevDate);
}


$scope.greaterThan = function(prop, val){
return function(item){
return item[prop] > val;
}
};


}]);
21 changes: 21 additions & 0 deletions js/controllers/stocks_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
app.controller('StocksCtrl',
['stocks', '$scope', 'StockService', 'DateService', 'dates',
function(stocks, $scope, StockService, DateService, dates) {


$scope.dateInfo = DateService.getDateInfo();
$scope.stocksInfo = StockService.getStocks('2015-01-02');
$scope.sliderLength = dates.length - 1;

$scope.setDate = function() {
DateService.setDate($scope.newDate);
$scope.stocksInfo = StockService.getStocks($scope.dateInfo.currentDate);
};

// $scope.$watch('currentDate', function(){
// console.log("watch firing");
// $scope.currentStocks = stocks[$scope.dateInfo.currentDate];
// })

}]);

69 changes: 69 additions & 0 deletions js/controllers/trade_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
app.controller('TradeCtrl',
['stocks', '$scope', 'StockService', 'DateService', 'dates', '$stateParams', 'PortfolioService', "$state",
function(stocks, $scope, StockService, DateService, dates, $stateParams, PortfolioService, $state) {

$scope.dateInfo = DateService.getDateInfo();
$scope.symbol = $stateParams.symbol;
$scope.price = $stateParams.price;
$scope.date = $stateParams.date;
$scope.quantity = 1;
$scope.buySell = 1;
$scope.portfolio = PortfolioService.getPortfolio();
$scope.currentPortfolio = $scope.portfolio[$scope.date]
$scope.cash = $scope.currentPortfolio.cash.quantity

$scope.submitOrder = function(){

var success = PortfolioService.placeOrder({
date: $scope.date,
quantity: $scope.quantity,
price: $scope.price,
symbol: $scope.symbol,
buySell: $scope.buySell
})
if (success) {
$scope.tradePreventer = '';
$state.go('stocks.transactions')
} else if ($scope.buySell == -1 && $scope.quantity > $scope.currentPortfolio[$scope.symbol].quantity) {
$scope.tradePreventer = "You're trying to sell more shares than you currently own."
} else {
$scope.tradePreventer = "This order can't be placed as it does not leave you enough cash or enough shares for a future trade you've already placed. Either reduce the amount of remove some future trades."
}

};

$scope.invalidTrade = function() {
if ($scope.buySell == 1 ) {
if ($scope.price * $scope.quantity > $scope.cash) {
return true;
}
} else {
if ($scope.quantity > $scope.currentPortfolio[$scope.symbol].quantity) {
$scope.tradePreventer = "You're trying to sell more shares than you currently own."
return true;
}
}
};

$scope.tradeChosen = function(){
if ($scope.symbol.length > 0) {
return true;
} else {
return false;
}
}


}]);

// $scope.dateInfo = DateService.getDateInfo();

// $scope.setDate = function() {
// DateService.setDate($scope.newDate);
// $scope.stocksInfo = StockService.getStocks($scope.dateInfo.currentDate);
// };

// $scope.$watch('currentDate', function(){
// console.log("watch firing");
// $scope.currentStocks = stocks[$scope.dateInfo.currentDate];
// })
7 changes: 7 additions & 0 deletions js/controllers/transactions_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
app.controller('TransactionsCtrl',
['$scope', 'PortfolioService', function($scope, PortfolioService) {


$scope.transactions = PortfolioService.getTransactions();

}]);
1 change: 1 addition & 0 deletions js/data/stocks.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions js/directives/stock_index_row.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<td>{{ stock.symbol}}</td>
<td>{{ stock.price | currency }}</td>
<td>{{ stock.oneDay | currency}}</td>
<td>{{ stock.sevenDay | currency}}</td>
<td>{{ stock.thirtyDay | currency}}</td>
<td> <a ui-sref="stocks.trade({symbol: stock.symbol, date: date, price: stock.price})" class="btn btn-primary">Trade</a> </td>
13 changes: 13 additions & 0 deletions js/directives/stock_index_row.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
app.directive('stockIndexRow', function() {

return {
restrict: 'A',
templateUrl: 'js/directives/stock_index_row.html',
scope: {
stock: "=",
symbol: "=",
date: "="
}
};

});
12 changes: 12 additions & 0 deletions js/filters/ticker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
app.filter('tickerFilter', [function(){

return function(collection) {
var values = []
for (var key in collection) {
values.push(collection[key]);
}
return values
}

}])

34 changes: 34 additions & 0 deletions js/services/date_service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
app.factory('DateService', ['StockService', function(StockService){


var _dates = StockService.allDates();

var _dateInfo = {
currentIndex: 0,
currentDate: _dates[0]
};



var getDateInfo = function(){
return _dateInfo;
}


var getDate = function(){
return _dateInfo.currentIndex;
};

var setDate = function(date) {
_dates = StockService.allDates()
_dateInfo.currentDate = _dates[date];
return _dateInfo.currentIndex = date;
};

return {
getDate: getDate,
setDate: setDate,
getDateInfo: getDateInfo
};

}]);
Loading