@gaberoo/kalshitools 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +666 -0
  2. package/bin/dev.cmd +3 -0
  3. package/bin/dev.js +5 -0
  4. package/bin/run.cmd +3 -0
  5. package/bin/run.js +5 -0
  6. package/dist/commands/config/init.d.ts +13 -0
  7. package/dist/commands/config/init.js +89 -0
  8. package/dist/commands/config/show.d.ts +10 -0
  9. package/dist/commands/config/show.js +77 -0
  10. package/dist/commands/markets/list.d.ts +11 -0
  11. package/dist/commands/markets/list.js +64 -0
  12. package/dist/commands/markets/show.d.ts +13 -0
  13. package/dist/commands/markets/show.js +79 -0
  14. package/dist/commands/orders/cancel.d.ts +14 -0
  15. package/dist/commands/orders/cancel.js +129 -0
  16. package/dist/commands/orders/create.d.ts +19 -0
  17. package/dist/commands/orders/create.js +211 -0
  18. package/dist/commands/orders/list.d.ts +13 -0
  19. package/dist/commands/orders/list.js +92 -0
  20. package/dist/commands/portfolio/balance.d.ts +9 -0
  21. package/dist/commands/portfolio/balance.js +36 -0
  22. package/dist/commands/portfolio/fills.d.ts +11 -0
  23. package/dist/commands/portfolio/fills.js +80 -0
  24. package/dist/commands/portfolio/positions.d.ts +9 -0
  25. package/dist/commands/portfolio/positions.js +58 -0
  26. package/dist/index.d.ts +1 -0
  27. package/dist/index.js +1 -0
  28. package/dist/lib/base-command.d.ts +13 -0
  29. package/dist/lib/base-command.js +38 -0
  30. package/dist/lib/config/manager.d.ts +71 -0
  31. package/dist/lib/config/manager.js +137 -0
  32. package/dist/lib/config/schema.d.ts +175 -0
  33. package/dist/lib/config/schema.js +59 -0
  34. package/dist/lib/errors/base.d.ts +84 -0
  35. package/dist/lib/errors/base.js +106 -0
  36. package/dist/lib/kalshi/auth.d.ts +17 -0
  37. package/dist/lib/kalshi/auth.js +71 -0
  38. package/dist/lib/kalshi/client.d.ts +86 -0
  39. package/dist/lib/kalshi/client.js +228 -0
  40. package/dist/lib/kalshi/index.d.ts +8 -0
  41. package/dist/lib/kalshi/index.js +19 -0
  42. package/dist/lib/kalshi/types.d.ts +155 -0
  43. package/dist/lib/kalshi/types.js +4 -0
  44. package/dist/lib/logger.d.ts +9 -0
  45. package/dist/lib/logger.js +41 -0
  46. package/dist/lib/output/formatter.d.ts +69 -0
  47. package/dist/lib/output/formatter.js +111 -0
  48. package/dist/lib/retry.d.ts +18 -0
  49. package/dist/lib/retry.js +81 -0
  50. package/dist/lib/sanitize.d.ts +28 -0
  51. package/dist/lib/sanitize.js +124 -0
  52. package/dist/lib/shutdown.d.ts +43 -0
  53. package/dist/lib/shutdown.js +106 -0
  54. package/dist/lib/validation.d.ts +37 -0
  55. package/dist/lib/validation.js +120 -0
  56. package/oclif.manifest.json +520 -0
  57. package/package.json +98 -0
@@ -0,0 +1,89 @@
1
+ import { Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { BaseCommand } from '../../lib/base-command.js';
4
+ import { getConfig } from '../../lib/config/manager.js';
5
+ import { logger } from '../../lib/logger.js';
6
+ export default class ConfigInit extends BaseCommand {
7
+ static description = 'Initialize kalshitools configuration interactively';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %>',
10
+ '<%= config.bin %> <%= command.id %> --env production',
11
+ ];
12
+ static flags = {
13
+ ...BaseCommand.baseFlags,
14
+ env: Flags.string({
15
+ description: 'Environment to configure (demo or production)',
16
+ options: ['demo', 'production'],
17
+ default: 'demo',
18
+ }),
19
+ keyId: Flags.string({
20
+ description: 'API key ID (email)',
21
+ }),
22
+ privateKeyPath: Flags.string({
23
+ description: 'Path to private key file',
24
+ }),
25
+ };
26
+ async run() {
27
+ const { flags } = await this.parse(ConfigInit);
28
+ const configManager = getConfig();
29
+ // Interactive prompts
30
+ const env = flags.env || 'demo';
31
+ let keyId = flags.keyId;
32
+ let privateKeyPath = flags.privateKeyPath;
33
+ // If not provided via flags, prompt the user
34
+ if (!keyId) {
35
+ keyId = await this.promptForInput('API Key ID (email)');
36
+ }
37
+ if (!privateKeyPath) {
38
+ privateKeyPath = await this.promptForInput(`Path to private key file (default: ~/.kalshitools/${env}-private-key.pem)`, `~/.kalshitools/${env}-private-key.pem`);
39
+ }
40
+ // Save configuration
41
+ configManager.setApiConfig(env, {
42
+ keyId,
43
+ privateKeyPath,
44
+ });
45
+ configManager.setEnvironment(env);
46
+ if (flags.json) {
47
+ this.formatter.success({
48
+ environment: env,
49
+ keyId,
50
+ privateKeyPath,
51
+ configPath: configManager.getConfigPath(),
52
+ });
53
+ }
54
+ else {
55
+ this.log(chalk.green('✓ Configuration saved successfully!'));
56
+ this.log();
57
+ this.log(chalk.cyan('Configuration:'));
58
+ this.log(` Environment: ${chalk.yellow(env)}`);
59
+ this.log(` Key ID: ${chalk.yellow(keyId)}`);
60
+ this.log(` Private Key Path: ${chalk.yellow(privateKeyPath)}`);
61
+ this.log(` Config File: ${chalk.gray(configManager.getConfigPath())}`);
62
+ this.log();
63
+ this.log(chalk.cyan('Next steps:'));
64
+ this.log(` 1. Make sure your private key is at: ${privateKeyPath}`);
65
+ this.log(` 2. Verify configuration: ${chalk.yellow('kalshitools config show')}`);
66
+ this.log(` 3. Test connection: ${chalk.yellow('kalshitools portfolio balance')}`);
67
+ }
68
+ logger.info({ env, keyId }, 'Configuration initialized');
69
+ }
70
+ async promptForInput(prompt, defaultValue) {
71
+ // For now, if in non-interactive mode or JSON mode, use defaults or fail
72
+ if (this.formatter.isJSONMode() || !process.stdin.isTTY) {
73
+ if (defaultValue) {
74
+ return defaultValue;
75
+ }
76
+ throw new Error(`${prompt} is required in non-interactive mode`);
77
+ }
78
+ // Simple readline prompt (could be enhanced with inquirer or @oclif/prompts)
79
+ const readline = await import('node:readline/promises');
80
+ const rl = readline.createInterface({
81
+ input: process.stdin,
82
+ output: process.stdout,
83
+ });
84
+ const displayPrompt = defaultValue ? `${prompt} [${defaultValue}]: ` : `${prompt}: `;
85
+ const answer = await rl.question(displayPrompt);
86
+ rl.close();
87
+ return answer.trim() || defaultValue || '';
88
+ }
89
+ }
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../lib/base-command.js';
2
+ export default class ConfigShow extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ private redact;
10
+ }
@@ -0,0 +1,77 @@
1
+ import chalk from 'chalk';
2
+ import { BaseCommand } from '../../lib/base-command.js';
3
+ import { getConfig } from '../../lib/config/manager.js';
4
+ export default class ConfigShow extends BaseCommand {
5
+ static description = 'Show current configuration (credentials redacted)';
6
+ static examples = ['<%= config.bin %> <%= command.id %>', '<%= config.bin %> <%= command.id %> --json'];
7
+ static flags = {
8
+ ...BaseCommand.baseFlags,
9
+ };
10
+ async run() {
11
+ await this.parse(ConfigShow);
12
+ const configManager = getConfig();
13
+ const config = configManager.getConfig();
14
+ const env = configManager.getEnvironment();
15
+ // Redact sensitive information
16
+ const safeConfig = {
17
+ version: config.version,
18
+ environment: env,
19
+ configPath: configManager.getConfigPath(),
20
+ api: {
21
+ demo: {
22
+ baseUrl: config.api.demo.baseUrl,
23
+ keyId: config.api.demo.keyId ? this.redact(config.api.demo.keyId) : undefined,
24
+ privateKeyPath: config.api.demo.privateKeyPath,
25
+ configured: Boolean(config.api.demo.keyId && config.api.demo.privateKeyPath),
26
+ },
27
+ production: {
28
+ baseUrl: config.api.production.baseUrl,
29
+ keyId: config.api.production.keyId ? this.redact(config.api.production.keyId) : undefined,
30
+ privateKeyPath: config.api.production.privateKeyPath,
31
+ configured: Boolean(config.api.production.keyId && config.api.production.privateKeyPath),
32
+ },
33
+ },
34
+ output: config.output,
35
+ trading: config.trading,
36
+ };
37
+ if (this.formatter.isJSONMode()) {
38
+ this.formatter.success(safeConfig);
39
+ }
40
+ else {
41
+ this.log(chalk.cyan.bold('Kalshitools Configuration'));
42
+ this.log();
43
+ this.log(`${chalk.cyan('Version:')} ${safeConfig.version}`);
44
+ this.log(`${chalk.cyan('Current Environment:')} ${chalk.yellow(safeConfig.environment)}`);
45
+ this.log(`${chalk.cyan('Config File:')} ${chalk.gray(safeConfig.configPath)}`);
46
+ this.log();
47
+ this.log(chalk.cyan.bold('API Configuration:'));
48
+ for (const [envName, envConfig] of Object.entries(safeConfig.api)) {
49
+ const isActive = envName === safeConfig.environment;
50
+ const prefix = isActive ? chalk.green('● ') : chalk.gray('○ ');
51
+ const status = envConfig.configured ? chalk.green('✓ Configured') : chalk.red('✗ Not configured');
52
+ this.log(`${prefix}${chalk.yellow(envName.toUpperCase())} ${status}`);
53
+ this.log(` Base URL: ${envConfig.baseUrl}`);
54
+ if (envConfig.keyId) {
55
+ this.log(` Key ID: ${envConfig.keyId}`);
56
+ }
57
+ if (envConfig.privateKeyPath) {
58
+ this.log(` Private Key: ${envConfig.privateKeyPath}`);
59
+ }
60
+ this.log();
61
+ }
62
+ this.log(chalk.cyan.bold('Output Settings:'));
63
+ this.log(` Default Format: ${safeConfig.output.defaultFormat}`);
64
+ this.log(` Colors: ${safeConfig.output.colors ? 'enabled' : 'disabled'}`);
65
+ this.log();
66
+ this.log(chalk.cyan.bold('Trading Safety:'));
67
+ this.log(` Confirmations: ${safeConfig.trading.confirmations ? 'enabled' : 'disabled'}`);
68
+ this.log(` Max Order Size: ${safeConfig.trading.maxOrderSize}`);
69
+ }
70
+ }
71
+ redact(value) {
72
+ if (value.length <= 8) {
73
+ return '***';
74
+ }
75
+ return `${value.slice(0, 4)}...${value.slice(-4)}`;
76
+ }
77
+ }
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from '../../lib/base-command.js';
2
+ export default class MarketsList extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ status: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
8
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,64 @@
1
+ import { Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { BaseCommand } from '../../lib/base-command.js';
4
+ import { createClientFromConfig } from '../../lib/kalshi/index.js';
5
+ import { logger } from '../../lib/logger.js';
6
+ export default class MarketsList extends BaseCommand {
7
+ static description = 'List prediction markets';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %>',
10
+ '<%= config.bin %> <%= command.id %> --status active --limit 10',
11
+ '<%= config.bin %> <%= command.id %> --json',
12
+ ];
13
+ static flags = {
14
+ ...BaseCommand.baseFlags,
15
+ status: Flags.string({
16
+ description: 'Filter by market status',
17
+ options: ['active', 'closed', 'settled', 'finalized'],
18
+ }),
19
+ limit: Flags.integer({
20
+ description: 'Maximum number of markets to return',
21
+ default: 20,
22
+ }),
23
+ };
24
+ async run() {
25
+ const { flags } = await this.parse(MarketsList);
26
+ try {
27
+ // Create API client from configuration
28
+ const client = createClientFromConfig();
29
+ // Fetch markets
30
+ const result = await client.getMarkets({
31
+ status: flags.status,
32
+ limit: flags.limit,
33
+ });
34
+ const markets = result.markets;
35
+ if (this.formatter.isJSONMode()) {
36
+ this.formatter.success({ markets, cursor: result.cursor });
37
+ }
38
+ else {
39
+ if (markets.length === 0) {
40
+ this.log(chalk.yellow('No markets found'));
41
+ return;
42
+ }
43
+ this.log(chalk.cyan.bold(`Markets (${markets.length})`));
44
+ this.log();
45
+ const rows = markets.map((market) => [
46
+ market.ticker,
47
+ market.title.length > 50 ? market.title.slice(0, 47) + '...' : market.title,
48
+ market.status,
49
+ market.last_price !== undefined ? market.last_price.toFixed(2) : 'N/A',
50
+ market.volume_24h !== undefined ? market.volume_24h.toLocaleString() : 'N/A',
51
+ ]);
52
+ this.formatter.outputTable(['Ticker', 'Title', 'Status', 'Price', 'Volume 24h'], rows);
53
+ if (result.cursor) {
54
+ this.log();
55
+ this.log(chalk.gray(`More results available. Use cursor: ${result.cursor}`));
56
+ }
57
+ }
58
+ logger.info({ count: markets.length }, 'Markets fetched successfully');
59
+ }
60
+ catch (error) {
61
+ throw error;
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../lib/base-command.js';
2
+ export default class MarketsShow extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ static args: {
9
+ ticker: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
10
+ };
11
+ run(): Promise<void>;
12
+ private formatStatus;
13
+ }
@@ -0,0 +1,79 @@
1
+ import { Args } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { BaseCommand } from '../../lib/base-command.js';
4
+ import { createClientFromConfig } from '../../lib/kalshi/index.js';
5
+ import { logger } from '../../lib/logger.js';
6
+ export default class MarketsShow extends BaseCommand {
7
+ static description = 'Show market details';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %> TICKER',
10
+ '<%= config.bin %> <%= command.id %> TICKER --json',
11
+ ];
12
+ static flags = {
13
+ ...BaseCommand.baseFlags,
14
+ };
15
+ static args = {
16
+ ticker: Args.string({
17
+ description: 'Market ticker symbol',
18
+ required: true,
19
+ }),
20
+ };
21
+ async run() {
22
+ const { args } = await this.parse(MarketsShow);
23
+ try {
24
+ // Create API client from configuration
25
+ const client = createClientFromConfig();
26
+ // Fetch market details
27
+ const market = await client.getMarket(args.ticker);
28
+ if (this.formatter.isJSONMode()) {
29
+ this.formatter.success(market);
30
+ }
31
+ else {
32
+ this.log(chalk.cyan.bold(market.title));
33
+ this.log(chalk.gray(market.subtitle));
34
+ this.log();
35
+ this.log(`${chalk.cyan('Ticker:')} ${market.ticker}`);
36
+ this.log(`${chalk.cyan('Status:')} ${this.formatStatus(market.status)}`);
37
+ this.log();
38
+ this.log(chalk.cyan.bold('Pricing:'));
39
+ if (market.yes_bid !== undefined && market.yes_ask !== undefined) {
40
+ this.log(` Yes: ${chalk.green(market.yes_bid.toFixed(2))} / ${chalk.green(market.yes_ask.toFixed(2))}`);
41
+ }
42
+ if (market.no_bid !== undefined && market.no_ask !== undefined) {
43
+ this.log(` No: ${chalk.red(market.no_bid.toFixed(2))} / ${chalk.red(market.no_ask.toFixed(2))}`);
44
+ }
45
+ if (market.last_price !== undefined) {
46
+ this.log(` Last: ${chalk.yellow(market.last_price.toFixed(2))}`);
47
+ }
48
+ this.log();
49
+ this.log(chalk.cyan.bold('Trading:'));
50
+ this.log(` Volume: ${market.volume?.toLocaleString() || 'N/A'}`);
51
+ this.log(` 24h Volume: ${market.volume_24h?.toLocaleString() || 'N/A'}`);
52
+ this.log(` Liquidity: ${market.liquidity?.toLocaleString() || 'N/A'}`);
53
+ this.log();
54
+ this.log(chalk.cyan.bold('Timing:'));
55
+ this.log(` Opens: ${new Date(market.open_time).toLocaleString()}`);
56
+ this.log(` Closes: ${new Date(market.close_time).toLocaleString()}`);
57
+ this.log(` Expires: ${new Date(market.expiration_time).toLocaleString()}`);
58
+ if (market.result) {
59
+ this.log();
60
+ this.log(`${chalk.cyan('Result:')} ${chalk.bold(market.result.toUpperCase())}`);
61
+ }
62
+ }
63
+ logger.info({ ticker: market.ticker }, 'Market details fetched successfully');
64
+ }
65
+ catch (error) {
66
+ throw error;
67
+ }
68
+ }
69
+ formatStatus(status) {
70
+ const colors = {
71
+ active: chalk.green,
72
+ closed: chalk.yellow,
73
+ settled: chalk.blue,
74
+ finalized: chalk.gray,
75
+ };
76
+ const colorFn = colors[status] || chalk.white;
77
+ return colorFn(status);
78
+ }
79
+ }
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../lib/base-command.js';
2
+ export default class OrdersCancel extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ static args: {
10
+ orderId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
11
+ };
12
+ run(): Promise<void>;
13
+ private confirm;
14
+ }
@@ -0,0 +1,129 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { BaseCommand } from '../../lib/base-command.js';
4
+ import { getConfig } from '../../lib/config/manager.js';
5
+ import { createClientFromConfig } from '../../lib/kalshi/index.js';
6
+ import { logger } from '../../lib/logger.js';
7
+ export default class OrdersCancel extends BaseCommand {
8
+ static description = 'Cancel an order';
9
+ static examples = [
10
+ '<%= config.bin %> <%= command.id %> ORDER_ID',
11
+ '<%= config.bin %> <%= command.id %> ORDER_ID --yes',
12
+ '<%= config.bin %> <%= command.id %> ORDER_ID --json',
13
+ ];
14
+ static flags = {
15
+ ...BaseCommand.baseFlags,
16
+ yes: Flags.boolean({
17
+ char: 'y',
18
+ description: 'Skip confirmation prompt',
19
+ default: false,
20
+ }),
21
+ };
22
+ static args = {
23
+ orderId: Args.string({
24
+ description: 'Order ID to cancel',
25
+ required: true,
26
+ }),
27
+ };
28
+ async run() {
29
+ const { args, flags } = await this.parse(OrdersCancel);
30
+ const configManager = getConfig();
31
+ const tradingConfig = configManager.getTradingConfig();
32
+ const environment = configManager.getEnvironment();
33
+ try {
34
+ // Create API client
35
+ const client = createClientFromConfig();
36
+ // Fetch order details first
37
+ const order = await client.getOrder(args.orderId);
38
+ // Check if order can be cancelled
39
+ if (order.status === 'executed') {
40
+ if (this.formatter.isJSONMode()) {
41
+ this.formatter.error('VALIDATION_ERROR', 'Order has already been executed and cannot be cancelled', {
42
+ orderId: args.orderId,
43
+ status: order.status,
44
+ });
45
+ }
46
+ else {
47
+ this.log(chalk.red('✗ Order has already been executed and cannot be cancelled'));
48
+ }
49
+ return;
50
+ }
51
+ if (order.status === 'canceled') {
52
+ if (this.formatter.isJSONMode()) {
53
+ this.formatter.error('VALIDATION_ERROR', 'Order has already been cancelled', {
54
+ orderId: args.orderId,
55
+ status: order.status,
56
+ });
57
+ }
58
+ else {
59
+ this.log(chalk.yellow('Order has already been cancelled'));
60
+ }
61
+ return;
62
+ }
63
+ if (order.status === 'expired') {
64
+ if (this.formatter.isJSONMode()) {
65
+ this.formatter.error('VALIDATION_ERROR', 'Order has already expired', {
66
+ orderId: args.orderId,
67
+ status: order.status,
68
+ });
69
+ }
70
+ else {
71
+ this.log(chalk.yellow('Order has already expired'));
72
+ }
73
+ return;
74
+ }
75
+ // Display order info
76
+ if (!this.formatter.isJSONMode()) {
77
+ this.log();
78
+ this.log(chalk.cyan.bold('Cancel Order'));
79
+ this.log(chalk.gray('─'.repeat(50)));
80
+ this.log(`${chalk.cyan('Environment:')} ${environment === 'demo' ? chalk.yellow('DEMO') : chalk.red('PRODUCTION')}`);
81
+ this.log(`${chalk.cyan('Order ID:')} ${order.order_id}`);
82
+ this.log(`${chalk.cyan('Ticker:')} ${order.ticker}`);
83
+ this.log(`${chalk.cyan('Action:')} ${order.action.toUpperCase()} ${order.side.toUpperCase()}`);
84
+ this.log(`${chalk.cyan('Quantity:')} ${order.count}`);
85
+ this.log(`${chalk.cyan('Filled:')} ${order.filled_count}/${order.count}`);
86
+ this.log(`${chalk.cyan('Status:')} ${order.status}`);
87
+ this.log(chalk.gray('─'.repeat(50)));
88
+ this.log();
89
+ }
90
+ // Confirmation prompt (unless --yes flag or JSON mode)
91
+ if (tradingConfig.confirmations && !flags.yes && !this.formatter.isJSONMode()) {
92
+ const confirmed = await this.confirm('Cancel this order?');
93
+ if (!confirmed) {
94
+ this.log(chalk.yellow('Cancellation aborted'));
95
+ return;
96
+ }
97
+ }
98
+ // Cancel the order
99
+ const cancelledOrder = await client.cancelOrder(args.orderId);
100
+ if (this.formatter.isJSONMode()) {
101
+ this.formatter.success(cancelledOrder);
102
+ }
103
+ else {
104
+ this.log(chalk.green('✓ Order cancelled successfully'));
105
+ this.log();
106
+ this.log(`${chalk.cyan('Order ID:')} ${cancelledOrder.order_id}`);
107
+ this.log(`${chalk.cyan('Status:')} ${chalk.gray(cancelledOrder.status)}`);
108
+ if (cancelledOrder.filled_count > 0) {
109
+ this.log();
110
+ this.log(chalk.yellow(`Note: ${cancelledOrder.filled_count} contracts were filled before cancellation`));
111
+ }
112
+ }
113
+ logger.info({ orderId: args.orderId }, 'Order cancelled successfully');
114
+ }
115
+ catch (error) {
116
+ throw error;
117
+ }
118
+ }
119
+ async confirm(message) {
120
+ const readline = await import('node:readline/promises');
121
+ const rl = readline.createInterface({
122
+ input: process.stdin,
123
+ output: process.stdout,
124
+ });
125
+ const answer = await rl.question(`${message} (y/N): `);
126
+ rl.close();
127
+ return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
128
+ }
129
+ }
@@ -0,0 +1,19 @@
1
+ import { BaseCommand } from '../../lib/base-command.js';
2
+ export default class OrdersCreate extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ ticker: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
7
+ action: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
+ side: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
+ quantity: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
10
+ type: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ price: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ 'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ };
16
+ run(): Promise<void>;
17
+ private formatStatus;
18
+ private confirm;
19
+ }