Skip to content
Merged
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
8 changes: 0 additions & 8 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
---
name: Pull Request
about: Pull request to merge into upper branch
assignees:
- Ruthgyeul
- Copilot
---

# Related Issue
> #ISSUE_NUMBER

Expand Down
84 changes: 44 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Stock Price Generator
Generates synthetic stock price data using various random algorithm models. The generated data can be used for testing and simulation purposes.
Generates random number for synthetic stock price data using various random algorithm models. The generated data can be used for testing and simulation purposes.

## Features
- Generate one-time stock price arrays
- Create continuous stock price generators with configurable intervals
- Support for various random algorithms (Random Walk)
- Support for various random algorithms (Random Walk, GBM, etc.)
- Configurable parameters for volatility, drift, and more
- Support for both ES Modules (import/export) and CommonJS (require)
- Support for both ES Modules (import/export), CommonJS (require), and TypeScript

## Installation

Expand All @@ -16,15 +16,15 @@ npm install stockprice-generator
```

## Usage

### ES Modules
> Check github for more example usages
### CommonJS
```javascript
import { getStockPrices, getContStockPrices } from 'stockprice-generator';
const { getStockPrices, getContStockPrices } = require('stockprice-generator');

// Generate an array of stock prices
const result = getStockPrices({
const result = getContStockPrices({
startPrice: 10000,
days: 100,
length: 100,
volatility: 0.1,
drift: 0.05,
algorithm: 'RandomWalk'
Expand All @@ -34,14 +34,14 @@ console.log(result.data); // Array of prices
console.log(result.price); // Current price (last price in the array)
```

### CommonJS
### ES Modules
```javascript
const { getStockPrices, getContStockPrices } = require('stockprice-generator');
import { getStockPrices, getContStockPrices } from 'stockprice-generator';

// Generate an array of stock prices
const result = getContStockPrices({
const result = getStockPrices({
startPrice: 10000,
days: 100,
length: 100,
volatility: 0.1,
drift: 0.05,
algorithm: 'RandomWalk'
Expand All @@ -51,18 +51,18 @@ console.log(result.data); // Array of prices
console.log(result.price); // Current price (last price in the array)
```

### Continuous Generation (ES Modules)
### Continuous Generation (CommonJS)
```javascript
import { getStockPrices } from 'stockprice-generator';
const { getContStockPrices } = require('stockprice-generator');

// Create a continuous generator that emits prices every 60 seconds
const generator = getStockPrices({
const generator = getContStockPrices({
startPrice: 10000,
volatility: 0.1,
drift: 0.05,
algorithm: 'RandomWalk',
interval: 60000, // 60 seconds
onPrice: (price: number) => {
onPrice: (price) => {
console.log(`New price: ${price}`);
}
});
Expand All @@ -77,18 +77,18 @@ console.log(`Current price: ${generator.getCurrentPrice()}`);
// generator.stop();
```

### Continuous Generation (CommonJS)
### Continuous Generation (ES Modules)
```javascript
const { getContStockPrices } = require('stockprice-generator');
import { getStockPrices } from 'stockprice-generator';

// Create a continuous generator that emits prices every 60 seconds
const generator = getContStockPrices({
const generator = getStockPrices({
startPrice: 10000,
volatility: 0.1,
drift: 0.05,
algorithm: 'RandomWalk',
interval: 60000, // 60 seconds
onPrice: (price) => {
onPrice: (price: number) => {
console.log(`New price: ${price}`);
}
});
Expand All @@ -105,26 +105,30 @@ console.log(`Current price: ${generator.getCurrentPrice()}`);

## Parameters

| Parameter | Required | Type | Default | Description |
|-----------|----------|------|----------|-------------|
| `startPrice` | Yes | number | - | Initial price of the stock |
| `days` | No | number | 100 | Number of days to generate prices for |
| `volatility` | No | number | 0.1 | Volatility of the stock price (standard deviation of the returns) |
| `drift` | No | number | 0.05 | The drift of the stock price (mean of the returns) |
| `seed` | No | number | DateTime | Seed for random number generation (for reproducibility) |
| `data` | No | number[] | [] | Pre-existing array of stock prices |
| `min` | No | number | 0 | Minimum price for the stock |
| `max` | No | number | 10000 | Maximum price for the stock |
| `length` | No | number | - | Length of the output array |
| `step` | No | number | - | Step size for discretization |
| `type` | No | 'float' \| 'int' | 'float' | Type of the data |
| `algorithm` | No | 'GBM' \| 'RandomWalk' | 'GBM' | Algorithm for generating the data |
| `interval` | No | number | 60000 | For continuous generation, interval in milliseconds between price updates |
| `onPrice` | No | function | - | Callback function to handle new prices in continuous generation |
| `onError` | No | function | - | Callback function to handle errors in continuous generation |
| `onStop` | No | function | - | Callback function to handle generator stop event |
| `onStart` | No | function | - | Callback function to handle generator start event |
| `onComplete` | No | function | - | Callback function to handle generator completion event |
| Parameter | Required | Type | Default | Description |
|--------------|----------|-----------------|--------|-------------------------------------------------------------------|
| `startPrice` | Yes | number | - | Initial price of the stock |
| `length` | No | number | 100 | Length of the output array |
| `volatility` | No | number | 0.1 | Volatility of the stock price (standard deviation of the returns) |
| `drift` | No | number | 0.05 | The drift of the stock price (mean of the returns) |
| `seed` | No | number | DateTime | Seed for random number generation (for reproducibility) |
| `min` | No | number | 0 | Minimum price for the stock (min >= 0) |
| `max` | No | number | 10000 | Maximum price for the stock (max >= 0) |
| `delisting` | No |boolean|false| Keep stock price to 0, if it reaches to 0 |
| `step` | No | number | - | Step size for discretization |
| `dataType` | No | float \| int | float | Type of the output data type |
| `algorithm` | No | RandomWalk \| GBM | RandomWalk | Algorithm for generating the random number |

## Handler Functions (only for continuous generation)

| Parameter | Required | Type | Default | Description |
|-----------|----------|------|----------|--------------------------------------------------------------------------|
| `interval` | Yes | number | 60000 | Interval in milliseconds between price updates in continuous generation |
| `onStart` | No | function | - | Callback function to handle generator start event |
| `onPrice` | No | function | - | Callback function to handle new prices in continuous generation |
| `onStop` | No | function | - | Callback function to handle generator stop event |
| `onComplete` | No | function | - | Callback function to handle generator completion event |
| `onError` | No | function | - | Callback function to handle errors in continuous generation |

## License
MIT
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "stockprice-generator",
"description": "A package for generating synthetic stock price data using various random algorithm models",
"version": "0.0.17",
"version": "0.0.20",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
Expand All @@ -27,9 +27,6 @@
"test:w": "jest --watch",
"prepare": "npm run build"
},
"publishConfig": {
"registry": "https://npm.pkg.github.com"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Ruthgyeul/stockPriceGenerator.git"
Expand All @@ -41,12 +38,14 @@
},
"homepage": "https://github.com/Ruthgyeul/stockPriceGenerator.git#readme",
"keywords": [
"random",
"number",
"stock",
"price",
"generator",
"simulation",
"GBM",
"random-walk",
"GBM",
"finance"
],
"devDependencies": {
Expand Down
42 changes: 37 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,30 @@ class StockPriceGeneratorImpl implements StockPriceGenerator {
}

generateNextPrice(): number {
const { volatility = 0.1, drift = 0.05, algorithm = 'RandomWalk', seed } = this.options;
const { volatility = 0.1, drift = 0.05, algorithm = 'RandomWalk', seed, step } = this.options;

if (volatility < 0) {
throw new Error('Volatility must be a non-negative number');
}

const selectedAlgorithm = algorithms[algorithm as AlgorithmType];
return selectedAlgorithm({
let nextPrice = selectedAlgorithm({
currentPrice: this.currentPrice,
volatility,
drift,
seed
seed,
min: this.options.min ?? 0,
max: this.options.max ?? 0,
delisting: this.options.delisting ?? false,
dataType: this.options.dataType ?? 'float'
});

// Apply step size discretization if specified
if (step && step > 0) {
nextPrice = Math.round(nextPrice / step) * step;
}

return nextPrice;
}

start(): void {
Expand All @@ -52,11 +63,32 @@ class StockPriceGeneratorImpl implements StockPriceGenerator {
}, this.interval);
}

pause(): void {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
}

continue(): void {
if (this.timer) return;

this.timer = setInterval(() => {
try {
this.currentPrice = this.generateNextPrice();
this.options.onPrice?.(this.currentPrice);
} catch (error) {
this.options.onError?.(error as Error);
}
}, this.interval);
}

stop(): void {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
this.options.onStop?.();
this.options.onComplete?.();
}
}

Expand All @@ -66,11 +98,11 @@ class StockPriceGeneratorImpl implements StockPriceGenerator {
}

export function getStockPrices(options: StockPriceOptions): StockPriceResult {
const { startPrice, days = 100, algorithm = 'RandomWalk' } = options;
const { startPrice, length = 100, step } = options;
const data: number[] = [startPrice];
let currentPrice = startPrice;

for (let i = 1; i < days; i++) {
for (let i = 1; i < length; i++) {
const generator = new StockPriceGeneratorImpl({
...options,
startPrice: currentPrice
Expand Down
13 changes: 7 additions & 6 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,22 @@ export type DataType = 'float' | 'int';

export interface StockPriceOptions {
startPrice: number; // Initial stock price
days?: number; // Number of days to generate prices for
length?: number; // Length of the generated data
volatility?: number; // Volatility of the stock price
drift?: number; // Drift of the stock price
seed?: number; // Seed for random number generation
data?: number[]; // Array of stock prices
min?: number; // Minimum stock price
max?: number; // Maximum stock price
length?: number; // Length of the generated data
delisting?: boolean; // Keep stock price to 0 if it reaches 0
step?: number; // Step size for the generated data
type?: DataType; // Type of data to generate (float or int)
dataType?: DataType; // Type of data to generate (float or int)
algorithm?: Algorithm; // Algorithm to use for generating stock prices
interval?: number; // Interval for generating stock prices (in milliseconds)
onStart?: () => void; // Callback for when the generator starts
onPrice?: (price: number) => void; // Callback for each generated price
onError?: (error: Error) => void; // Callback for errors
onStop?: () => void; // Callback for when the generator stops
onStart?: () => void; // Callback for when the generator starts
onComplete?: () => void; // Callback for when the generator completes
onError?: (error: Error) => void; // Callback for errors
}

export interface StockPriceResult {
Expand All @@ -30,6 +29,8 @@ export interface StockPriceResult {

export interface StockPriceGenerator {
start: () => void; // Start generating stock prices
pause: () => void; // Pause generating stock prices
continue: () => void; // Continue generating stock prices
stop: () => void; // Stop generating stock prices
getCurrentPrice: () => number; // Get the current stock price
}
6 changes: 6 additions & 0 deletions src/utils/algorithm/algorithmParams.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
export type DataType = 'float' | 'int';

export interface AlgorithmParams {
currentPrice: number; // Current stock price
volatility: number; // Volatility of the stock price
drift: number; // Drift of the stock price
seed?: number; // Seed for random number generation
min?: number; // Minimum stock price
max?: number; // Maximum stock price
delisting?: boolean; // Keep stock price to 0 if it reaches 0
dataType?: DataType; // Type of data to generate (float or int)
}
19 changes: 17 additions & 2 deletions src/utils/algorithm/useGBM.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import type { AlgorithmParams } from './algorithmParams';
import { seededRandom } from '../seed';
import { minMaxCheck} from '../minMaxCheck';
import { killStock } from "../killStock";
import { outputType } from "../outputType";

export function GBM({ currentPrice, volatility, drift, seed = (Date.now() + new Date().getMilliseconds()) }: AlgorithmParams): number {
export function GBM({ currentPrice, volatility = 0.1, drift = 0.05, seed = (Date.now() + new Date().getMilliseconds()), min = 0, max = 0, delisting = false, dataType = 'float' }: AlgorithmParams): number {
const dt = 1 / 365;

const u1 = seededRandom(seed);
Expand All @@ -13,5 +16,17 @@ export function GBM({ currentPrice, volatility, drift, seed = (Date.now() + new
volatility * Math.sqrt(dt) * z
);

return currentPrice * change;
let nextPrice = currentPrice * change;

// Check if delisting is enabled
if (delisting) {
// Delisting logic
nextPrice = killStock(nextPrice);
} else {
// Check min and max limits
nextPrice = minMaxCheck(min, max, nextPrice);
}

// Output with specified data type
return outputType(nextPrice, dataType);
}
Loading
Loading