FIN310 • Course Hub Index

Two-track course: Part I — Money & Banking and Part II — Financial Markets & Institutions. Reference site (prior year): https://www.jufinance.com/fin310_24f/
Theme:
Legend: Basics Term Projects Syllabus Exams Trading Tools Part I Part II

Course Basics & Projects

Term Projects — Pick ONE of these four options

Project 1 and 2 are downloadable write-ups. Project 3 and 4 are hands-on builds. Submit according to your instructor’s directions.

Term Project 1 — Tariff Policy (DOCX)

Policy analysis with citations; follow the template.

Download (DOCX)

Term Project 2 — Bank Failure 2023 (DOCX)

Case study on 2023 banking events; follow the template.

Download (DOCX)

Term Project 3 — Google Sheets Stock Fetcher (Apps Script)

Build a small web app + Google Sheet that fetches a stock’s daily prices and computes monthly returns using GOOGLEFINANCE. (Corrected instructions.)

Step 1 — Create a new Google Sheet
  • Go to Google Sheets → Blank sheet.
Step 2 — Apps Script (container-bound)
  1. Sheet menu → Extensions ▸ Apps Script.
  2. Delete any starter code.
  3. Paste this script and save (Project name e.g. Stock Data Fetcher):
// Serves the HTML UI (file name must be lowercase: 'index')
function doGet() {
  return HtmlService.createHtmlOutputFromFile('index');
}

function fetchStockData(ticker, startDateStr) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

  // Clear previous content (A..F)
  sheet.getRange("A1:F1000").clearContent();

  // Headers
  sheet.getRange("A1").setValue("Date");
  sheet.getRange("B1").setValue("Closing Price");
  sheet.getRange("C1").setValue("Stock Name");

  // Stock name via GOOGLEFINANCE
  sheet.getRange("C2").setFormula('=GOOGLEFINANCE("' + ticker + '", "name")');

  // Daily close series from startDate to today
  // NOTE: "close" returns Date + Close columns
  sheet.getRange("A2").setFormula('=GOOGLEFINANCE("' + ticker + '","close","' + startDateStr + '",TODAY(),"daily")');

  SpreadsheetApp.flush();

  // Pull populated daily values (Date, Close)
  var dataRange = sheet.getRange("A2:B1000").getValues();
  var valid = dataRange.filter(function(row){ return row[0] && row[1]; });

  if (valid.length === 0) {
    return "No data returned. Check ticker/date.";
  }

  // Monthly table headers
  sheet.getRange("D1").setValue("Month (YYYY-MM)");
  sheet.getRange("E1").setValue("Closing Price");
  sheet.getRange("F1").setValue("Monthly Return");

  // Last day per month
  var monthly = {};
  valid.forEach(function(row){
    var d = new Date(row[0]);
    var p = row[1];
    var key = d.getFullYear() + '-' + String(d.getMonth()+1).padStart(2,'0');
    monthly[key] = p; // last encountered price becomes "month-end"
  });

  // Write out months in ascending order
  var months = Object.keys(monthly).sort();
  var prev = null, r = 2;
  months.forEach(function(m){
    var price = monthly[m];
    sheet.getRange(r, 4).setValue(m);
    sheet.getRange(r, 5).setValue(price);
    if (prev !== null) {
      var ret = ((price - prev) / prev) * 100;
      sheet.getRange(r, 6).setValue(ret.toFixed(2) + "%");
    }
    prev = price; r++;
  });

  return "OK: Data fetched and monthly returns calculated.";
}
Step 3 — Create the HTML UI file (lowercase name: index)
  1. Apps Script editor → +HTML → name it index (all lowercase).
  2. Paste this HTML:
<!DOCTYPE html>
<html>
<head>
  <base target="_top">
  <title>Stock Data Fetcher</title>
  <style>
    body{font-family:Arial, sans-serif;margin:20px}
    label{display:block;margin-top:10px}
    input,button{margin-top:5px}
    .footer{margin-top:20px;font-size:12px;color:#666;text-align:center}
  </style>
</head>
<body>
  <h2>Stock Data Fetcher</h2>

  <label for="ticker">Stock Ticker:</label>
  <input type="text" id="ticker" placeholder="e.g., AAPL, WMT" />

  <label for="startDate">Start Date:</label>
  <input type="date" id="startDate" />

  <div style="margin-top:10px">
    <button onclick="fetchData()">Fetch Data</button>
    <button onclick="openGoogleSheet()">Open Google Sheet</button>
  </div>

  <p id="status"></p>

  <script>
    function fetchData(){
      var ticker = document.getElementById('ticker').value.trim();
      var startDate = document.getElementById('startDate').value;
      if(!ticker || !startDate){
        document.getElementById('status').innerText = "Enter ticker and start date.";
        return;
      }
      google.script.run.withSuccessHandler(function(msg){
        document.getElementById('status').innerText = msg;
      }).fetchStockData(ticker, startDate);
    }

    function openGoogleSheet(){
      // Replace with your actual Sheet URL (see Troubleshooting)
      var sheetUrl = "YOUR_GOOGLE_SHEET_URL";
      window.open(sheetUrl, "_blank");
    }
  </script>
</body>
</html>
Important: The filename is index (lowercase). This must match HtmlService.createHtmlOutputFromFile('index').
Step 4 — Authorize & Deploy the Web App
  • Click Run (▶). Approve permissions when prompted.
  • Deploy ▸ New deployment ▸ Web app:
    • Execute as: Me
    • Who has access: Anyone (or Only myself for private use)
  • Click Deploy → copy the Web App URL.
Troubleshooting & Sharing
  • In the HTML openGoogleSheet(), replace YOUR_GOOGLE_SHEET_URL with your sheet’s URL (copy from the browser).
  • Sheet sharing: click Share → set to Anyone with the link (view/comment/edit as desired).
  • If GOOGLEFINANCE returns blanks: verify the ticker and date range; try a different symbol or a closer start date.
What to Submit
  • Web App URL
  • Google Sheet URL (with sharing enabled)
  • Screenshot of the populated sheet (daily area and monthly summary)
  • 1–2 paragraphs: lessons learned + one improvement you’d ship next

Term Project 4 — Club Stablecoin (Local Ganache)

Deploy a minimal ERC-20 “Campus Dollar (cUSD)” to a local blockchain using Ganache and MetaMask. No Sepolia, no faucets.

Step 1 — Setup Ganache + MetaMask
  • Install Ganache (GUI) and start a workspace (you’ll see funded test accounts).
  • Open MetaMask → Add Network (manually):
    • Network name: Ganache (Local)
    • RPC URL: http://127.0.0.1:7545
    • Chain ID: 1337 (or use the one shown by Ganache)
    • Currency symbol: ETH
  • From Ganache, copy a private key of an account → MetaMask Import account (paste key). You now have local test ETH.
Step 2 — Remix & Contract
  • Go to remix.ethereum.org → “+” New File → ClubStablecoin.sol → paste the contract below.
  • Compile with Solidity 0.8.20 (any ^0.8.x ok).
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/**
 * Club Stablecoin (simple ERC-20 demo)
 * - Owner (deployer) can mint and change owner.
 * - Anyone can transfer.
 * - Anyone can burn their own tokens.
 * - Decimals = 6 (dollar-like: 1.000000)
 * NOTE: Local demo only. Not audited. No fees/pausing/blacklists.
 */
contract ClubStablecoin {
    string public name;
    string public symbol;
    uint8  public immutable decimals;
    uint256 public totalSupply;

    mapping(address => uint256)                     private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;

    address public owner;
    modifier onlyOwner(){ require(msg.sender == owner, "not owner"); _; }

    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Approval(address indexed owner, address indexed spender, uint256 amount);
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);

    constructor(string memory _name, string memory _symbol, uint8 _decimals){
        owner = msg.sender;
        emit OwnershipTransferred(address(0), msg.sender);
        name = _name;
        symbol = _symbol;
        decimals = _decimals; // e.g., 6 for $-style 1.000000
    }

    function balanceOf(address a) public view returns (uint256) { return _balances[a]; }
    function allowance(address a, address s) public view returns (uint256) { return _allowances[a][s]; }

    function transfer(address to, uint256 amount) public returns (bool) {
        _transfer(msg.sender, to, amount); return true;
    }
    function approve(address spender, uint256 amount) public returns (bool) {
        _approve(msg.sender, spender, amount); return true;
    }
    function transferFrom(address from, address to, uint256 amount) public returns (bool) {
        uint256 allowed = _allowances[from][msg.sender];
        require(allowed >= amount, "insufficient allowance");
        if (allowed != type(uint256).max) {
            _allowances[from][msg.sender] = allowed - amount;
            emit Approval(from, msg.sender, _allowances[from][msg.sender]);
        }
        _transfer(from, to, amount); return true;
    }

    function mint(address to, uint256 amount) public onlyOwner {
        require(to != address(0), "mint to zero");
        totalSupply += amount; _balances[to] += amount;
        emit Transfer(address(0), to, amount);
    }
    function burn(uint256 amount) public {
        uint256 bal = _balances[msg.sender]; require(bal >= amount, "insufficient");
        _balances[msg.sender] = bal - amount; totalSupply -= amount;
        emit Transfer(msg.sender, address(0), amount);
    }
    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0), "zero owner");
        emit OwnershipTransferred(owner, newOwner); owner = newOwner;
    }

    function _transfer(address from, address to, uint256 amount) internal {
        require(to != address(0), "transfer to zero");
        uint256 bal = _balances[from]; require(bal >= amount, "insufficient balance");
        _balances[from] = bal - amount; _balances[to] += amount;
        emit Transfer(from, to, amount);
    }
    function _approve(address a, address s, uint256 amount) internal {
        require(s != address(0), "approve to zero");
        _allowances[a][s] = amount; emit Approval(a, s, amount);
    }
}
Step 3 — Deploy (Injected Provider — MetaMask)
  • In Remix → Deploy & RunEnvironment: Injected Provider — MetaMask (select your Ganache (Local) network).
  • Constructor args:
    • name: Campus Dollar
    • symbol: cUSD
    • decimals: 6
  • Click Deploy → approve in MetaMask → copy the deployed contract address.
Step 4 — Mint & View in Wallets
  • As owner, call mint(<memberAddress>, 1000000) to send 1.000000 cUSD (6 decimals).
  • In MetaMask (Ganache network) → Import tokens → paste contract address → add. Members can transfer locally.
Safety & Scope (include in README)
  • Local only. Not audited; do not use with real funds.
  • Never share seed phrases. Use distinct browser profiles if testing multiple accounts.
  • For leadership rotation: transferOwnership() to next treasurer (or migrate to a Safe on a testnet if you later move beyond Ganache).
What to Submit
  • Contract address (Ganache) + short note of your Ganache chain ID
  • 2–4 screenshots: deploy, a mint tx, and wallet balance
  • 1–2 paragraphs: what worked, what confused you, and one risk you’d mitigate before using anything like this for real
Reminder: You only submit one term project (choose TP1, TP2, TP3, or TP4).

Syllabus (On-Page)

Cross-listed with FIN 310. Credit cannot be awarded for both ECON 310 and FIN 310.

Meeting Information

Section: ECON 310 • 103Z • 25FALL

When/Where: TR 12:30–1:45 PM · Room SIJU137

Instructor: Maggie Foley (mfoley3@ju.edu)

Office: DCOBT 118A · Office Hours: Mon–Thu 2–3 PM & by appt.

Texts & Materials

Money, Banking, and Financial Markets, Cecchetti & Schoenholtz, 6e (2020), McGraw-Hill Irwin. ISBN 978-1260571363.

Lecture integrates textbook, primary sources, and discussion.

Course Outcomes

  • Describe U.S. financial markets and instruments
  • Explain risk and its role in decisions
  • Identify drivers of interest rates
  • Explain stock market efficiency foundations
  • Understand basic derivatives
  • Compare intermediation vs. direct finance
  • Articulate current monetary policy & effects
  • Use standard financial terminology
Grading & Coursework
ComponentWeight
Two Mid-Term Exams40%
Final Exam20%
Term Project10%
Homework20%
Quizzes (T/F at end of each class; up to 6 misses allowed)10%

Exams: Closed-book/notes; mostly new material but cumulative concepts may reappear.

Quizzes: End of each class; also used for attendance. Up to 6 misses without penalty.

Homework: Due at start of class; legible and done individually unless stated.

Make-ups: With documentation (doctor, coach, Student Life, or university official); notify instructor in advance when possible.

Electronics: Laptops/tablets/phones generally not allowed unless required for an activity.

Extra Credit: Max 5 points across opportunities announced by the instructor.

Weekly Schedule (subject to change)
  • 8/19 — Introduction
  • 8/21 — Ch.15–18 Federal Reserve & Monetary Policy I
  • 8/26 — Ch.15–18 Federal Reserve & Monetary Policy II
  • 8/28 — Ch.15–18 Federal Reserve & Monetary Policy III
  • 9/2 — Ch.11–14 M0, M1, M2
  • 9/4 — Ch.11–14 Banks & Banking System I
  • 9/9 — Ch.11–14 Banks & Banking System II
  • 9/11 — Review
  • 9/16 — Ch.2 What is Money I
  • 9/18 — Ch.2 What is Money II
  • 9/23 — First Mid-Term Exam
  • 9/25 — Ch.3 Financial Instrument, Market & Institution I
  • 9/30 — Ch.3 Financial Instrument, Market & Institution II
  • 10/2 — Ch.5 Diversification
  • 10/7 — Ch.9 Options
  • 10/9 — Ch.8 Stock Market
  • 10/14 — Ch.8 Mutual Fund
  • 10/16 — Ch.6 Bond Market I
  • 10/21 — Ch.6 Bond Market II
  • 10/23 — Ch.7 Ratings, Term Structure, Yield Curve I
  • 10/28 — Ch.7 Ratings, Term Structure, Yield Curve II
  • 10/30 — Second Mid-Term Exam
  • 11/4 — Ch.9 Futures Contract
  • 11/6 — Ch.10 International Finance
  • 11/11 — Ch.10 International Finance
  • 11/13 — Intro to Blockchain, Bitcoin & Ethereum I
  • 11/18 — Intro to Blockchain, Bitcoin & Ethereum II
  • 11/20 — Review
  • 11/22 — Final Exam 3:00–5:30 PM & Term Project Due

Exam Solutions

First Midterm — Solution

Administered in class (54 T/F; last 4 ungraded). Solution provided as an HTML/JS page.

Open Solution (HTML)

Second Midterm — Solution

Released after the in-class exam.

Open Solution (HTML)

Final Exam — Solution

Released after the in-class exam.

Open Solution (HTML)

Trading Game Tools (FINVIZ + MarketWatch)

Use these for the class MarketWatch game. Open an app, pick candidates in Finviz, then size the trade properly.

Featured Video

MarketWatch game walkthrough

Short-Only Scanner (App)

Daily shorts with presets, risk tool, checklist.

Open Short App

Long-Only Position Builder (App)

Fundamentals + technical entries, sector mix planner.

Open Long App

MarketWatch Game Website

Create/join your class game (Virtual Stock Exchange).

Open MarketWatch Games

FINVIZ Screener

Run scans, then use the apps above for sizing & diversification.

Open FINVIZ

Class Game Rooms

Game - FIN310 25 Fall (Live) (have fun)

Part I — Money & Banking

Session 1 The Federal Reserve

Intro, short history, role, structure, 2010 chair (Bernanke), JU 2011 visit, videos, mini-quiz.

Open Session 1

Session 2 Monetary Policy

Fed funds rate, OMOs, discount window, IORB, QE/QT, transmission, statements/minutes, quiz.

Open Session 2

Session 3 What Is Money?

Money vs. income/wealth, M0/M1/M2, deposits & money creation, velocity basics, quiz.

Open Session 3

Session 4 Crypto & Stablecoins

Blockchain basics, BTC/ETH, stablecoin types & risks (fiat-backed/crypto/algorithmic), policy, quiz.

Open Session 4

Part II — Banks & Money/Payments

Session 5 Banking System

Balance-sheet basics, capital & liquidity, FDIC, supervision, lender-of-last-resort. Quiz + examples.

Open Session 5

Session 6 Banking Regulations

Basel accords, capital & liquidity rules, stress tests, resolution and “living wills.”

Open Session 6

Session 7 Fractional Reserve Banking

T-accounts, money multiplier, currency drain, capital limits; interactive simulator game with quiz.

Open Session 7

Session 8 Discussion Session

Debates on TBTF, stablecoins vs banks, and “start-a-bank?” scenarios. Students pick sides; instructor verdicts.

Open Session 8

Session 9 Credit Unions & VyStar

Member-owned credit unions, NCUA insurance, field of membership, local case study on VyStar. Coverage calculator & quiz.

Open Session 9

Disclaimer: All materials are developed and provided independently via jufinance.com. Feedback and suggestions are welcome.