Skip to content
jdfergason edited this page Aug 5, 2024 · 3 revisions

pv-engine

PV-Engine is a next generation investing platform for back testing and strategy execution in golang. This repository is still in the very early design phases. It is a replacement for the current pv-api back-tester.

One major difference between pv-engine and pv-api is that pv-engine can only be run from the command line--a major departure from pv-api's REST interfaces. The reasons for this change are:

  1. As strategy execution becomes increasingly complex and takes longer to complete the REST model does not scale well. Its better to have an individual instance that is launched by a scheduler than a long running server.
  2. The REST server model was inconvenient when developing a new strategy.

The functions that pv-api offered will be replaced by a TBD orchestration service (maybe something like AWS lambda) and https://postgrest.org

Goals of pv-engine

  1. Fast and simple strategy development: Defining strategies should be possible with as little code as possible. Also, code structure should support understanding of the central idea behind the strategy.
  2. Fast strategy execution
  3. Back-test and live execution of strategies
  4. Easily scale execution of strategies

Ecosystem

PV-Engine relies upon two other Penny Vault services for proper execution:

  1. PV-Data regularly downloads and updates the database with stock prices, fundamental data, economic indicators, etc. PV-Engine relies on the postgresql database structure created by pv-data
  2. PV-Web is a VueJS website that interacts with PostgreSQL to visualize user portfolio's created with pv-engine

Writing Strategies

Strategies are simply go modules that import the pv-engine module. pv-engine provides command line parsing, strategy flow-control, an indicators library, and portfolio simulation.

Typical strategy strcuture:

  • settings.toml - required inputs, execution schedule (e.g. daily, month-end), strategy name, version, author and other meta-data
  • README.md - description of the strategy
  • go.mod / go.sum - required dependencies
  • .go - strategy source code

Investing strategies create orders based on a universe of possible investments. Orders are not guaranteed to fill - they may result in no-fill, partial, or full. If an order fills then the quantity of assets purchased are added to the portfolio and the cost of the assets and any fees are deducted from the portfolio.

Strategies must implement the Strategy interface.

type Strategy interface {
  Universe() Universe
  OrdersForDate(eventTime time.Time, portfolio Portfolio) OrderBook
}

type Indicator func(args ...Args) float64 

Indicators

DualMomentum = ( price("30d") + price("3mo") + price("6mo") ) / 3 - price(EconomicIndicator = "dgs3mo")

SMA(window) = window(3d) price

MACD(fast, slow)

Universe

Risk_Universe = SPY WCMSX

Protective_Universe = SP500 Russell-1000 Nasdaq-100

Portfolio Construction

  • Portfolio
  • Portfolio Target
  • Order Book
Clone this wiki locally