trading-cycle
Version:
A lightweight, modular core library designed for backtesting trading strategies in financial markets.
192 lines (136 loc) • 5.84 kB
Markdown
# Trading Cycle
[](https://www.npmjs.com/package/trading-cycle) [](https://github.com/vladtarrow/trading-cycle/actions) [](https://codecov.io/gh/vladtarrow/trading-cycle) [](https://github.com/prettier/prettier)
[](https://bundlephobia.com/package/trading-cycle) [](https://bundlephobia.com/package/trading-cycle) [](https://bundlephobia.com/package/trading-cycle)
A lightweight, modular core library designed for backtesting trading strategies in financial markets.
## Installation
Install the full or light version depending on your use case:
```bash
# Full version (with built-in indicators and helpers)
npm install trading-cycle
# Light version (core only)
npm install trading-cycle
```
## Usage
### Full Version
```ts
import {
Candles,
PositiveValues,
NegativeValues,
Renko,
TimeRenko,
TestLogic,
PositiveTimeLength,
NegativeTimeLength,
FakeTrader,
LogCandle,
RenkoCounter
} from 'trading-cycle/full';
```
### Light Version
```ts
import { TradingCycle } from 'trading-cycle/light';
```
## Versions
- **Full**: Includes core, built-in indicators, helpers, and utility functions.
- **Light**: Contains only the core functionality — `TradingCycle` class and abstract handler interfaces.
## Built-in Handlers
Trading Cycle ships with a set of predefined handlers you can use out of the box:
```
Candles,
PositiveValues,
NegativeValues,
Renko,
TimeRenko,
TestLogic,
PositiveTimeLength,
NegativeTimeLength,
FakeTrader,
LogCandle,
RenkoCounter
```
## Default Preset Configuration
A default preset is provided under `trading-cycle/config`, pre-wiring common handlers with sensible defaults (e.g. Renko bar size of 0.05):
```ts
import defaultPreset from 'trading-cycle/config';
```
This preset includes handlers such as:
- `candles`
- `log-candles`
- `renko-0.05`
- `time-renko`
- `renko-counter`
- `test-logic`
- `fake-trader`
Customize or extend it by supplying your own `HandlerConfig[]` when creating `TradingCycle`.
## Handler Example
Below is a concise description of a custom handler, illustrating how you can extend the core functionality:
1. **Class Declaration**
Create a class that extends `AbstractHandler`.
2. **Internal State**
Define private fields (e.g., `prev`) to store data between ticks.
3. **Constructor**
Call `super(state, config)` to initialize base properties and set up your own fields.
4. **Override `doExecute()`**
- Access input values via `this.v` and stored state via `this._s`.
- Implement your logic (e.g., detect when the current close is lower than the previous close).
- Update internal state (`this.prev = this.v.input;`).
- Return a result only when the condition is met.
**NegativeValues** handler example (pseudocode):
> Extends `AbstractHandler`, tracks the previous candle in `prev`, and returns the current candle when its close is less than the previous close.
## Example: Backtest from CSV
A quick outline to run a backtest with CSV data:
```ts
import TradingCycle from 'trading-cycle';
import handlers from 'trading-cycle/full';
import defaultPreset from 'trading-cycle/config';
// Initialize the cycle
const cycle = new TradingCycle(handlers, defaultPreset);
// Load your CSV into `ticks: Array<{ o, h, l, c, v }>`
// e.g. via `csv-parse` or any CSV loader
ticks.forEach(tick => cycle.execute(tick));
// Inspect results
console.log(cycle.state);
```
## API Overview
- `new TradingCycle(handlerClasses: Record<string, HandlerConstructor>, preset: HandlerConfig[])` — Create a cycle with provided handlers and configuration presets.
- `execute(tick: any): void` — Run all handlers on a single market tick; results accumulate in `cycle.state`.
- `cycle.state: Record<string, any[]>` — Current output arrays for each handler.
## Design Philosophy
- **Modularity**: Handlers are self-contained units; you can add, remove or customize them without affecting others.
- **Flexibility**: Presets define the pipeline; you control data flow by composing inputs and defaults.
- **Simplicity**: Core abstractions (`TradingCycle`, `AbstractHandler`) remain minimal and clear.
## Continuous Integration
This project uses GitHub Actions for CI and Codecov for coverage reporting.
### Setup
1. **Add Codecov action**: No extra npm packages needed, simply configure the workflow.
2. **Create a secret**: Add `CODECOV_TOKEN` in your repository's *Settings > Secrets*.
### Workflow (`.github/workflows/ci.yml`)
```yaml
name: CI
on:
push:
branches: [ main ]
pull_request:
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Run tests
run: yarn test --coverage
- name: Upload to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
```
## License
MIT
## Author
[Vladyslav Tarasenko](https://github.com/vladtarrow)