reportify-sdk 0.3.23 → 0.3.25

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.
package/dist/index.d.mts CHANGED
@@ -255,6 +255,10 @@ interface FollowedCompany {
255
255
  logo?: string;
256
256
  followedAt?: number;
257
257
  }
258
+ interface BatchOHLCVOutput {
259
+ datas: Array<Record<string, unknown>>;
260
+ metadata: Record<string, unknown>;
261
+ }
258
262
  declare class ReportifyError extends Error {
259
263
  statusCode?: number;
260
264
  constructor(message: string, statusCode?: number);
@@ -723,16 +727,20 @@ interface OHLCVData {
723
727
  interface BacktestParams {
724
728
  startDate: string;
725
729
  endDate: string;
726
- symbol: string;
730
+ symbols?: string[];
731
+ filterFormula?: string;
727
732
  market?: StockMarket;
728
- entryFormula: string;
733
+ entryFormula?: string;
734
+ strategyCode?: string;
729
735
  exitFormula?: string;
730
736
  initialCash?: number;
731
737
  commission?: number;
732
738
  stopLoss?: number;
733
- sizerPercent?: number;
739
+ positionSize?: number;
740
+ maxPositions?: number;
741
+ minVolume?: number;
734
742
  autoClose?: boolean;
735
- labels?: Record<string, string>;
743
+ signalFactors?: Record<string, string>;
736
744
  }
737
745
  interface Kline1mParams {
738
746
  symbol: string;
@@ -768,14 +776,23 @@ interface BacktestResult {
768
776
  profit_factor: number;
769
777
  win_rate: number;
770
778
  total_trades: number;
779
+ winning_trades: number;
780
+ losing_trades: number;
771
781
  trades: Array<{
772
- date: string;
773
- action: 'buy' | 'sell';
774
- price: number;
775
- quantity: number;
776
- value: number;
777
- pnl?: number;
782
+ id: number;
783
+ symbol: string | null;
784
+ type: string;
785
+ entry_date: string;
786
+ exit_date: string;
787
+ entry_price: number;
788
+ exit_price: number;
789
+ size: number;
790
+ net_pnl: number;
791
+ return_pct: number;
792
+ cumulative_pnl: number;
778
793
  }>;
794
+ portfolio_value: Record<string, number>;
795
+ error_msg: string | null;
779
796
  }
780
797
  /**
781
798
  * Quantitative analysis module
@@ -1036,6 +1053,8 @@ declare class QuantModule {
1036
1053
  * - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20), PE(), ROE(), RSI(14), etc.
1037
1054
  *
1038
1055
  * @param params - Backtest parameters
1056
+ * @param params.autoClose Whether to automatically close positions at end of backtest (default true)
1057
+ * @param params.signalFactors Signal factors dictionary for custom strategy pre-computation
1039
1058
  * @returns Backtest results
1040
1059
  *
1041
1060
  * @example
@@ -1044,7 +1063,7 @@ declare class QuantModule {
1044
1063
  * const result = await client.quant.backtest({
1045
1064
  * startDate: '2023-01-01',
1046
1065
  * endDate: '2024-01-01',
1047
- * symbol: '000001',
1066
+ * symbols: ['000001'],
1048
1067
  * entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 20))', // Buy when MA5 crosses above MA20
1049
1068
  * initialCash: 100000
1050
1069
  * });
@@ -1057,27 +1076,28 @@ declare class QuantModule {
1057
1076
  * const result2 = await client.quant.backtest({
1058
1077
  * startDate: '2023-01-01',
1059
1078
  * endDate: '2024-01-01',
1060
- * symbol: '000001',
1079
+ * symbols: ['000001'],
1061
1080
  * entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 20))', // Buy signal
1062
1081
  * exitFormula: 'CROSSDOWN(MA(CLOSE, 5), MA(CLOSE, 20))' // Sell signal
1063
1082
  * });
1064
1083
  *
1065
- * // Fundamental screening backtest (note: functions require parentheses)
1066
- * const result3 = await client.quant.backtest({
1067
- * startDate: '2023-01-01',
1068
- * endDate: '2024-01-01',
1069
- * symbol: '000001',
1070
- * entryFormula: '(PE() < 20) & (ROE() > 0.15)'
1071
- * });
1072
- *
1073
- * // With custom labels for analysis
1074
- * const result4 = await client.quant.backtest({
1084
+ * // With custom python strategy code using signalFactors
1085
+ * const customStrategy = `
1086
+ * def handle_data(context, datas):
1087
+ * for data in datas:
1088
+ * symbol = data.name
1089
+ * if not context.portfolio.get_position(symbol):
1090
+ * if data.pe < 20 and data.rsi < 30: # Use pre-calculated factors
1091
+ * context.order_target_percent(symbol, 0.2)
1092
+ * elif data.rsi > 70:
1093
+ * context.order_target_percent(symbol, 0)
1094
+ * `;
1095
+ * const result5 = await client.quant.backtest({
1075
1096
  * startDate: '2023-01-01',
1076
1097
  * endDate: '2024-01-01',
1077
- * symbol: '000001',
1078
- * entryFormula: 'RSI(14) < 30',
1079
- * exitFormula: 'RSI(14) > 70',
1080
- * labels: { rsi: 'RSI(14)', ma20: 'MA(CLOSE, 20)' }
1098
+ * symbols: ['000001'],
1099
+ * signalFactors: { rsi: 'RSI(14)', pe: 'PE_TTM()' },
1100
+ * strategyCode: customStrategy
1081
1101
  * });
1082
1102
  * ```
1083
1103
  */
@@ -1637,6 +1657,11 @@ declare class SearchModule {
1637
1657
  * Provides access to follow group management functionality.
1638
1658
  */
1639
1659
 
1660
+ type FollowType = 'company' | 'channel';
1661
+ interface FollowValue {
1662
+ follow_type: FollowType;
1663
+ follow_value: string;
1664
+ }
1640
1665
  declare class FollowingModule {
1641
1666
  private client;
1642
1667
  constructor(client: Reportify);
@@ -1644,23 +1669,20 @@ declare class FollowingModule {
1644
1669
  * Create a new follow group
1645
1670
  *
1646
1671
  * @param name - Group name
1647
- * @param followValues - List of follow values (each with 'follow_type' as int and 'follow_value' as string)
1648
- * follow_type: 1=company, 3=channel
1672
+ * @param followValues - List of follow values (each with 'follow_type' and 'follow_value')
1673
+ * follow_type: "company", "channel"
1649
1674
  * @returns Created group information including group_id, name, and count
1650
1675
  *
1651
1676
  * @example
1652
1677
  * ```typescript
1653
1678
  * const result = await client.following.createFollowGroup('My Stocks', [
1654
- * { follow_type: 1, follow_value: 'US:AAPL' },
1655
- * { follow_type: 1, follow_value: 'HK:00700' }
1679
+ * { follow_type: 'company', follow_value: 'US:AAPL' },
1680
+ * { follow_type: 'company', follow_value: 'HK:00700' }
1656
1681
  * ]);
1657
1682
  * console.log(`Created group: ${result.group_id}`);
1658
1683
  * ```
1659
1684
  */
1660
- createFollowGroup(name: string, followValues?: Array<{
1661
- follow_type: number;
1662
- follow_value: string;
1663
- }>): Promise<{
1685
+ createFollowGroup(name: string, followValues?: FollowValue[]): Promise<{
1664
1686
  group_id: string;
1665
1687
  name: string;
1666
1688
  count: number;
@@ -1699,10 +1721,7 @@ declare class FollowingModule {
1699
1721
  group_id: string;
1700
1722
  name: string;
1701
1723
  count: number;
1702
- follow_values: Array<{
1703
- follow_type: number;
1704
- follow_value: string;
1705
- }>;
1724
+ follow_values?: FollowValue[];
1706
1725
  }>;
1707
1726
  /**
1708
1727
  * Update a follow group
@@ -1738,21 +1757,18 @@ declare class FollowingModule {
1738
1757
  * Add follows to a group
1739
1758
  *
1740
1759
  * @param groupId - Group ID
1741
- * @param followValues - List of follow values (each with 'follow_type' as int and 'follow_value' as string)
1742
- * follow_type: 1=company, 3=channel
1760
+ * @param followValues - List of follow values (each with 'follow_type' and 'follow_value')
1761
+ * follow_type: "company", "channel"
1743
1762
  * @returns Status message
1744
1763
  *
1745
1764
  * @example
1746
1765
  * ```typescript
1747
1766
  * await client.following.addFollowsToGroup('group_123', [
1748
- * { follow_type: 1, follow_value: 'US:TSLA' }
1767
+ * { follow_type: 'company', follow_value: 'US:TSLA' }
1749
1768
  * ]);
1750
1769
  * ```
1751
1770
  */
1752
- addFollowsToGroup(groupId: string, followValues: Array<{
1753
- follow_type: number;
1754
- follow_value: string;
1755
- }>): Promise<void>;
1771
+ addFollowsToGroup(groupId: string, followValues: FollowValue[]): Promise<void>;
1756
1772
  /**
1757
1773
  * Remove follows from a group
1758
1774
  *
@@ -1770,22 +1786,19 @@ declare class FollowingModule {
1770
1786
  * Set follows for a group (replace all existing follows)
1771
1787
  *
1772
1788
  * @param groupId - Group ID
1773
- * @param followValues - List of follow values (each with 'follow_type' as int and 'follow_value' as string)
1774
- * follow_type: 1=company, 3=channel
1789
+ * @param followValues - List of follow values (each with 'follow_type' and 'follow_value')
1790
+ * follow_type: "company", "channel"
1775
1791
  * @returns Status message
1776
1792
  *
1777
1793
  * @example
1778
1794
  * ```typescript
1779
1795
  * await client.following.setGroupFollows('group_123', [
1780
- * { follow_type: 1, follow_value: 'US:AAPL' },
1781
- * { follow_type: 1, follow_value: 'HK:00700' }
1796
+ * { follow_type: 'company', follow_value: 'US:AAPL' },
1797
+ * { follow_type: 'company', follow_value: 'HK:00700' }
1782
1798
  * ]);
1783
1799
  * ```
1784
1800
  */
1785
- setGroupFollows(groupId: string, followValues: Array<{
1786
- follow_type: number;
1787
- follow_value: string;
1788
- }>): Promise<void>;
1801
+ setGroupFollows(groupId: string, followValues: FollowValue[]): Promise<void>;
1789
1802
  /**
1790
1803
  * Get docs for a follow group
1791
1804
  *
@@ -1934,4 +1947,4 @@ declare class Reportify {
1934
1947
  getBytes(path: string): Promise<ArrayBuffer>;
1935
1948
  }
1936
1949
 
1937
- export { APIError, type AgentConversation, type AgentMessage, AgentModule, AuthenticationError, type BacktestParams, type BacktestResult, type BatchKline1mParams, type BatchMinuteParams, type BatchOHLCVParams, type Calendar, type Channel, ChannelsModule, type ChatCompletionOptions, type ChatCompletionResponse, type ChatMode, ChatModule, type Chunk, type ChunkSearchOptions, type CommodityData, type CommodityType, type CompanyInfo, type CompanyOverview, type Concept, type ConceptDoc, type ConceptEvent, type ConceptFeed, type ConceptStock, ConceptsModule, type DocsListOptions, DocsModule, type Document, type DocumentInput, type EarningsEvent, type EarningsSearchOptions, type FactorComputeParams, type FactorMeta, type FinancialStatement, type FollowedCompany, FollowingModule, type IPOEvent, type IPOStatus, type IndexConstituent, type IndexFund, type IndicatorComputeParams, type IndicatorData, type IndicatorMeta, type IndustryConstituent, KBModule, type KBSearchOptions, type Kline1mParams, MacroModule, type Market, type MinuteParams, NotFoundError, type OHLCVData, type OHLCVParams, type PaginatedResponse, type Period, type PriceData, QuantModule, type Quote, RateLimitError, Reportify, type ReportifyConfig, ReportifyError, type ScreenParams, type ScreenedStock, SearchModule, type SearchOptions, type Shareholder, type ShareholderType, type StockInfo, type StockMarket, StockModule, TimelineModule, type TimelineOptions, type UploadDocRequest, UserModule };
1950
+ export { APIError, type AgentConversation, type AgentMessage, AgentModule, AuthenticationError, type BacktestParams, type BacktestResult, type BatchKline1mParams, type BatchMinuteParams, type BatchOHLCVOutput, type BatchOHLCVParams, type Calendar, type Channel, ChannelsModule, type ChatCompletionOptions, type ChatCompletionResponse, type ChatMode, ChatModule, type Chunk, type ChunkSearchOptions, type CommodityData, type CommodityType, type CompanyInfo, type CompanyOverview, type Concept, type ConceptDoc, type ConceptEvent, type ConceptFeed, type ConceptStock, ConceptsModule, type DocsListOptions, DocsModule, type Document, type DocumentInput, type EarningsEvent, type EarningsSearchOptions, type FactorComputeParams, type FactorMeta, type FinancialStatement, type FollowedCompany, FollowingModule, type IPOEvent, type IPOStatus, type IndexConstituent, type IndexFund, type IndicatorComputeParams, type IndicatorData, type IndicatorMeta, type IndustryConstituent, KBModule, type KBSearchOptions, type Kline1mParams, MacroModule, type Market, type MinuteParams, NotFoundError, type OHLCVData, type OHLCVParams, type PaginatedResponse, type Period, type PriceData, QuantModule, type Quote, RateLimitError, Reportify, type ReportifyConfig, ReportifyError, type ScreenParams, type ScreenedStock, SearchModule, type SearchOptions, type Shareholder, type ShareholderType, type StockInfo, type StockMarket, StockModule, TimelineModule, type TimelineOptions, type UploadDocRequest, UserModule };
package/dist/index.d.ts CHANGED
@@ -255,6 +255,10 @@ interface FollowedCompany {
255
255
  logo?: string;
256
256
  followedAt?: number;
257
257
  }
258
+ interface BatchOHLCVOutput {
259
+ datas: Array<Record<string, unknown>>;
260
+ metadata: Record<string, unknown>;
261
+ }
258
262
  declare class ReportifyError extends Error {
259
263
  statusCode?: number;
260
264
  constructor(message: string, statusCode?: number);
@@ -723,16 +727,20 @@ interface OHLCVData {
723
727
  interface BacktestParams {
724
728
  startDate: string;
725
729
  endDate: string;
726
- symbol: string;
730
+ symbols?: string[];
731
+ filterFormula?: string;
727
732
  market?: StockMarket;
728
- entryFormula: string;
733
+ entryFormula?: string;
734
+ strategyCode?: string;
729
735
  exitFormula?: string;
730
736
  initialCash?: number;
731
737
  commission?: number;
732
738
  stopLoss?: number;
733
- sizerPercent?: number;
739
+ positionSize?: number;
740
+ maxPositions?: number;
741
+ minVolume?: number;
734
742
  autoClose?: boolean;
735
- labels?: Record<string, string>;
743
+ signalFactors?: Record<string, string>;
736
744
  }
737
745
  interface Kline1mParams {
738
746
  symbol: string;
@@ -768,14 +776,23 @@ interface BacktestResult {
768
776
  profit_factor: number;
769
777
  win_rate: number;
770
778
  total_trades: number;
779
+ winning_trades: number;
780
+ losing_trades: number;
771
781
  trades: Array<{
772
- date: string;
773
- action: 'buy' | 'sell';
774
- price: number;
775
- quantity: number;
776
- value: number;
777
- pnl?: number;
782
+ id: number;
783
+ symbol: string | null;
784
+ type: string;
785
+ entry_date: string;
786
+ exit_date: string;
787
+ entry_price: number;
788
+ exit_price: number;
789
+ size: number;
790
+ net_pnl: number;
791
+ return_pct: number;
792
+ cumulative_pnl: number;
778
793
  }>;
794
+ portfolio_value: Record<string, number>;
795
+ error_msg: string | null;
779
796
  }
780
797
  /**
781
798
  * Quantitative analysis module
@@ -1036,6 +1053,8 @@ declare class QuantModule {
1036
1053
  * - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20), PE(), ROE(), RSI(14), etc.
1037
1054
  *
1038
1055
  * @param params - Backtest parameters
1056
+ * @param params.autoClose Whether to automatically close positions at end of backtest (default true)
1057
+ * @param params.signalFactors Signal factors dictionary for custom strategy pre-computation
1039
1058
  * @returns Backtest results
1040
1059
  *
1041
1060
  * @example
@@ -1044,7 +1063,7 @@ declare class QuantModule {
1044
1063
  * const result = await client.quant.backtest({
1045
1064
  * startDate: '2023-01-01',
1046
1065
  * endDate: '2024-01-01',
1047
- * symbol: '000001',
1066
+ * symbols: ['000001'],
1048
1067
  * entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 20))', // Buy when MA5 crosses above MA20
1049
1068
  * initialCash: 100000
1050
1069
  * });
@@ -1057,27 +1076,28 @@ declare class QuantModule {
1057
1076
  * const result2 = await client.quant.backtest({
1058
1077
  * startDate: '2023-01-01',
1059
1078
  * endDate: '2024-01-01',
1060
- * symbol: '000001',
1079
+ * symbols: ['000001'],
1061
1080
  * entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 20))', // Buy signal
1062
1081
  * exitFormula: 'CROSSDOWN(MA(CLOSE, 5), MA(CLOSE, 20))' // Sell signal
1063
1082
  * });
1064
1083
  *
1065
- * // Fundamental screening backtest (note: functions require parentheses)
1066
- * const result3 = await client.quant.backtest({
1067
- * startDate: '2023-01-01',
1068
- * endDate: '2024-01-01',
1069
- * symbol: '000001',
1070
- * entryFormula: '(PE() < 20) & (ROE() > 0.15)'
1071
- * });
1072
- *
1073
- * // With custom labels for analysis
1074
- * const result4 = await client.quant.backtest({
1084
+ * // With custom python strategy code using signalFactors
1085
+ * const customStrategy = `
1086
+ * def handle_data(context, datas):
1087
+ * for data in datas:
1088
+ * symbol = data.name
1089
+ * if not context.portfolio.get_position(symbol):
1090
+ * if data.pe < 20 and data.rsi < 30: # Use pre-calculated factors
1091
+ * context.order_target_percent(symbol, 0.2)
1092
+ * elif data.rsi > 70:
1093
+ * context.order_target_percent(symbol, 0)
1094
+ * `;
1095
+ * const result5 = await client.quant.backtest({
1075
1096
  * startDate: '2023-01-01',
1076
1097
  * endDate: '2024-01-01',
1077
- * symbol: '000001',
1078
- * entryFormula: 'RSI(14) < 30',
1079
- * exitFormula: 'RSI(14) > 70',
1080
- * labels: { rsi: 'RSI(14)', ma20: 'MA(CLOSE, 20)' }
1098
+ * symbols: ['000001'],
1099
+ * signalFactors: { rsi: 'RSI(14)', pe: 'PE_TTM()' },
1100
+ * strategyCode: customStrategy
1081
1101
  * });
1082
1102
  * ```
1083
1103
  */
@@ -1637,6 +1657,11 @@ declare class SearchModule {
1637
1657
  * Provides access to follow group management functionality.
1638
1658
  */
1639
1659
 
1660
+ type FollowType = 'company' | 'channel';
1661
+ interface FollowValue {
1662
+ follow_type: FollowType;
1663
+ follow_value: string;
1664
+ }
1640
1665
  declare class FollowingModule {
1641
1666
  private client;
1642
1667
  constructor(client: Reportify);
@@ -1644,23 +1669,20 @@ declare class FollowingModule {
1644
1669
  * Create a new follow group
1645
1670
  *
1646
1671
  * @param name - Group name
1647
- * @param followValues - List of follow values (each with 'follow_type' as int and 'follow_value' as string)
1648
- * follow_type: 1=company, 3=channel
1672
+ * @param followValues - List of follow values (each with 'follow_type' and 'follow_value')
1673
+ * follow_type: "company", "channel"
1649
1674
  * @returns Created group information including group_id, name, and count
1650
1675
  *
1651
1676
  * @example
1652
1677
  * ```typescript
1653
1678
  * const result = await client.following.createFollowGroup('My Stocks', [
1654
- * { follow_type: 1, follow_value: 'US:AAPL' },
1655
- * { follow_type: 1, follow_value: 'HK:00700' }
1679
+ * { follow_type: 'company', follow_value: 'US:AAPL' },
1680
+ * { follow_type: 'company', follow_value: 'HK:00700' }
1656
1681
  * ]);
1657
1682
  * console.log(`Created group: ${result.group_id}`);
1658
1683
  * ```
1659
1684
  */
1660
- createFollowGroup(name: string, followValues?: Array<{
1661
- follow_type: number;
1662
- follow_value: string;
1663
- }>): Promise<{
1685
+ createFollowGroup(name: string, followValues?: FollowValue[]): Promise<{
1664
1686
  group_id: string;
1665
1687
  name: string;
1666
1688
  count: number;
@@ -1699,10 +1721,7 @@ declare class FollowingModule {
1699
1721
  group_id: string;
1700
1722
  name: string;
1701
1723
  count: number;
1702
- follow_values: Array<{
1703
- follow_type: number;
1704
- follow_value: string;
1705
- }>;
1724
+ follow_values?: FollowValue[];
1706
1725
  }>;
1707
1726
  /**
1708
1727
  * Update a follow group
@@ -1738,21 +1757,18 @@ declare class FollowingModule {
1738
1757
  * Add follows to a group
1739
1758
  *
1740
1759
  * @param groupId - Group ID
1741
- * @param followValues - List of follow values (each with 'follow_type' as int and 'follow_value' as string)
1742
- * follow_type: 1=company, 3=channel
1760
+ * @param followValues - List of follow values (each with 'follow_type' and 'follow_value')
1761
+ * follow_type: "company", "channel"
1743
1762
  * @returns Status message
1744
1763
  *
1745
1764
  * @example
1746
1765
  * ```typescript
1747
1766
  * await client.following.addFollowsToGroup('group_123', [
1748
- * { follow_type: 1, follow_value: 'US:TSLA' }
1767
+ * { follow_type: 'company', follow_value: 'US:TSLA' }
1749
1768
  * ]);
1750
1769
  * ```
1751
1770
  */
1752
- addFollowsToGroup(groupId: string, followValues: Array<{
1753
- follow_type: number;
1754
- follow_value: string;
1755
- }>): Promise<void>;
1771
+ addFollowsToGroup(groupId: string, followValues: FollowValue[]): Promise<void>;
1756
1772
  /**
1757
1773
  * Remove follows from a group
1758
1774
  *
@@ -1770,22 +1786,19 @@ declare class FollowingModule {
1770
1786
  * Set follows for a group (replace all existing follows)
1771
1787
  *
1772
1788
  * @param groupId - Group ID
1773
- * @param followValues - List of follow values (each with 'follow_type' as int and 'follow_value' as string)
1774
- * follow_type: 1=company, 3=channel
1789
+ * @param followValues - List of follow values (each with 'follow_type' and 'follow_value')
1790
+ * follow_type: "company", "channel"
1775
1791
  * @returns Status message
1776
1792
  *
1777
1793
  * @example
1778
1794
  * ```typescript
1779
1795
  * await client.following.setGroupFollows('group_123', [
1780
- * { follow_type: 1, follow_value: 'US:AAPL' },
1781
- * { follow_type: 1, follow_value: 'HK:00700' }
1796
+ * { follow_type: 'company', follow_value: 'US:AAPL' },
1797
+ * { follow_type: 'company', follow_value: 'HK:00700' }
1782
1798
  * ]);
1783
1799
  * ```
1784
1800
  */
1785
- setGroupFollows(groupId: string, followValues: Array<{
1786
- follow_type: number;
1787
- follow_value: string;
1788
- }>): Promise<void>;
1801
+ setGroupFollows(groupId: string, followValues: FollowValue[]): Promise<void>;
1789
1802
  /**
1790
1803
  * Get docs for a follow group
1791
1804
  *
@@ -1934,4 +1947,4 @@ declare class Reportify {
1934
1947
  getBytes(path: string): Promise<ArrayBuffer>;
1935
1948
  }
1936
1949
 
1937
- export { APIError, type AgentConversation, type AgentMessage, AgentModule, AuthenticationError, type BacktestParams, type BacktestResult, type BatchKline1mParams, type BatchMinuteParams, type BatchOHLCVParams, type Calendar, type Channel, ChannelsModule, type ChatCompletionOptions, type ChatCompletionResponse, type ChatMode, ChatModule, type Chunk, type ChunkSearchOptions, type CommodityData, type CommodityType, type CompanyInfo, type CompanyOverview, type Concept, type ConceptDoc, type ConceptEvent, type ConceptFeed, type ConceptStock, ConceptsModule, type DocsListOptions, DocsModule, type Document, type DocumentInput, type EarningsEvent, type EarningsSearchOptions, type FactorComputeParams, type FactorMeta, type FinancialStatement, type FollowedCompany, FollowingModule, type IPOEvent, type IPOStatus, type IndexConstituent, type IndexFund, type IndicatorComputeParams, type IndicatorData, type IndicatorMeta, type IndustryConstituent, KBModule, type KBSearchOptions, type Kline1mParams, MacroModule, type Market, type MinuteParams, NotFoundError, type OHLCVData, type OHLCVParams, type PaginatedResponse, type Period, type PriceData, QuantModule, type Quote, RateLimitError, Reportify, type ReportifyConfig, ReportifyError, type ScreenParams, type ScreenedStock, SearchModule, type SearchOptions, type Shareholder, type ShareholderType, type StockInfo, type StockMarket, StockModule, TimelineModule, type TimelineOptions, type UploadDocRequest, UserModule };
1950
+ export { APIError, type AgentConversation, type AgentMessage, AgentModule, AuthenticationError, type BacktestParams, type BacktestResult, type BatchKline1mParams, type BatchMinuteParams, type BatchOHLCVOutput, type BatchOHLCVParams, type Calendar, type Channel, ChannelsModule, type ChatCompletionOptions, type ChatCompletionResponse, type ChatMode, ChatModule, type Chunk, type ChunkSearchOptions, type CommodityData, type CommodityType, type CompanyInfo, type CompanyOverview, type Concept, type ConceptDoc, type ConceptEvent, type ConceptFeed, type ConceptStock, ConceptsModule, type DocsListOptions, DocsModule, type Document, type DocumentInput, type EarningsEvent, type EarningsSearchOptions, type FactorComputeParams, type FactorMeta, type FinancialStatement, type FollowedCompany, FollowingModule, type IPOEvent, type IPOStatus, type IndexConstituent, type IndexFund, type IndicatorComputeParams, type IndicatorData, type IndicatorMeta, type IndustryConstituent, KBModule, type KBSearchOptions, type Kline1mParams, MacroModule, type Market, type MinuteParams, NotFoundError, type OHLCVData, type OHLCVParams, type PaginatedResponse, type Period, type PriceData, QuantModule, type Quote, RateLimitError, Reportify, type ReportifyConfig, ReportifyError, type ScreenParams, type ScreenedStock, SearchModule, type SearchOptions, type Shareholder, type ShareholderType, type StockInfo, type StockMarket, StockModule, TimelineModule, type TimelineOptions, type UploadDocRequest, UserModule };
package/dist/index.js CHANGED
@@ -947,6 +947,8 @@ var QuantModule = class {
947
947
  * - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20), PE(), ROE(), RSI(14), etc.
948
948
  *
949
949
  * @param params - Backtest parameters
950
+ * @param params.autoClose Whether to automatically close positions at end of backtest (default true)
951
+ * @param params.signalFactors Signal factors dictionary for custom strategy pre-computation
950
952
  * @returns Backtest results
951
953
  *
952
954
  * @example
@@ -955,7 +957,7 @@ var QuantModule = class {
955
957
  * const result = await client.quant.backtest({
956
958
  * startDate: '2023-01-01',
957
959
  * endDate: '2024-01-01',
958
- * symbol: '000001',
960
+ * symbols: ['000001'],
959
961
  * entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 20))', // Buy when MA5 crosses above MA20
960
962
  * initialCash: 100000
961
963
  * });
@@ -968,27 +970,28 @@ var QuantModule = class {
968
970
  * const result2 = await client.quant.backtest({
969
971
  * startDate: '2023-01-01',
970
972
  * endDate: '2024-01-01',
971
- * symbol: '000001',
973
+ * symbols: ['000001'],
972
974
  * entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 20))', // Buy signal
973
975
  * exitFormula: 'CROSSDOWN(MA(CLOSE, 5), MA(CLOSE, 20))' // Sell signal
974
976
  * });
975
977
  *
976
- * // Fundamental screening backtest (note: functions require parentheses)
977
- * const result3 = await client.quant.backtest({
978
- * startDate: '2023-01-01',
979
- * endDate: '2024-01-01',
980
- * symbol: '000001',
981
- * entryFormula: '(PE() < 20) & (ROE() > 0.15)'
982
- * });
983
- *
984
- * // With custom labels for analysis
985
- * const result4 = await client.quant.backtest({
978
+ * // With custom python strategy code using signalFactors
979
+ * const customStrategy = `
980
+ * def handle_data(context, datas):
981
+ * for data in datas:
982
+ * symbol = data.name
983
+ * if not context.portfolio.get_position(symbol):
984
+ * if data.pe < 20 and data.rsi < 30: # Use pre-calculated factors
985
+ * context.order_target_percent(symbol, 0.2)
986
+ * elif data.rsi > 70:
987
+ * context.order_target_percent(symbol, 0)
988
+ * `;
989
+ * const result5 = await client.quant.backtest({
986
990
  * startDate: '2023-01-01',
987
991
  * endDate: '2024-01-01',
988
- * symbol: '000001',
989
- * entryFormula: 'RSI(14) < 30',
990
- * exitFormula: 'RSI(14) > 70',
991
- * labels: { rsi: 'RSI(14)', ma20: 'MA(CLOSE, 20)' }
992
+ * symbols: ['000001'],
993
+ * signalFactors: { rsi: 'RSI(14)', pe: 'PE_TTM()' },
994
+ * strategyCode: customStrategy
992
995
  * });
993
996
  * ```
994
997
  */
@@ -996,20 +999,32 @@ var QuantModule = class {
996
999
  const body = {
997
1000
  start_date: params.startDate,
998
1001
  end_date: params.endDate,
999
- symbol: params.symbol,
1000
1002
  market: params.market || "cn",
1001
- entry_formula: params.entryFormula,
1002
1003
  initial_cash: params.initialCash ?? 1e5,
1003
1004
  commission: params.commission ?? 0,
1004
1005
  stop_loss: params.stopLoss ?? 0,
1005
- sizer_percent: params.sizerPercent ?? 99,
1006
+ position_size: params.positionSize ?? 0.2,
1007
+ max_positions: params.maxPositions ?? 5,
1008
+ min_volume: params.minVolume ?? 100,
1006
1009
  auto_close: params.autoClose ?? true
1007
1010
  };
1011
+ if (params.symbols !== void 0) {
1012
+ body.symbols = params.symbols;
1013
+ }
1014
+ if (params.filterFormula !== void 0) {
1015
+ body.filter_formula = params.filterFormula;
1016
+ }
1017
+ if (params.entryFormula !== void 0) {
1018
+ body.entry_formula = params.entryFormula;
1019
+ }
1020
+ if (params.strategyCode !== void 0) {
1021
+ body.strategy_code = params.strategyCode;
1022
+ }
1008
1023
  if (params.exitFormula !== void 0) {
1009
1024
  body.exit_formula = params.exitFormula;
1010
1025
  }
1011
- if (params.labels !== void 0) {
1012
- body.labels = params.labels;
1026
+ if (params.signalFactors !== void 0) {
1027
+ body.signal_factors = params.signalFactors;
1013
1028
  }
1014
1029
  return this.client.post("/v1/quant/backtest", body);
1015
1030
  }
@@ -1763,15 +1778,15 @@ var FollowingModule = class {
1763
1778
  * Create a new follow group
1764
1779
  *
1765
1780
  * @param name - Group name
1766
- * @param followValues - List of follow values (each with 'follow_type' as int and 'follow_value' as string)
1767
- * follow_type: 1=company, 3=channel
1781
+ * @param followValues - List of follow values (each with 'follow_type' and 'follow_value')
1782
+ * follow_type: "company", "channel"
1768
1783
  * @returns Created group information including group_id, name, and count
1769
1784
  *
1770
1785
  * @example
1771
1786
  * ```typescript
1772
1787
  * const result = await client.following.createFollowGroup('My Stocks', [
1773
- * { follow_type: 1, follow_value: 'US:AAPL' },
1774
- * { follow_type: 1, follow_value: 'HK:00700' }
1788
+ * { follow_type: 'company', follow_value: 'US:AAPL' },
1789
+ * { follow_type: 'company', follow_value: 'HK:00700' }
1775
1790
  * ]);
1776
1791
  * console.log(`Created group: ${result.group_id}`);
1777
1792
  * ```
@@ -1861,14 +1876,14 @@ var FollowingModule = class {
1861
1876
  * Add follows to a group
1862
1877
  *
1863
1878
  * @param groupId - Group ID
1864
- * @param followValues - List of follow values (each with 'follow_type' as int and 'follow_value' as string)
1865
- * follow_type: 1=company, 3=channel
1879
+ * @param followValues - List of follow values (each with 'follow_type' and 'follow_value')
1880
+ * follow_type: "company", "channel"
1866
1881
  * @returns Status message
1867
1882
  *
1868
1883
  * @example
1869
1884
  * ```typescript
1870
1885
  * await client.following.addFollowsToGroup('group_123', [
1871
- * { follow_type: 1, follow_value: 'US:TSLA' }
1886
+ * { follow_type: 'company', follow_value: 'US:TSLA' }
1872
1887
  * ]);
1873
1888
  * ```
1874
1889
  */
@@ -1899,15 +1914,15 @@ var FollowingModule = class {
1899
1914
  * Set follows for a group (replace all existing follows)
1900
1915
  *
1901
1916
  * @param groupId - Group ID
1902
- * @param followValues - List of follow values (each with 'follow_type' as int and 'follow_value' as string)
1903
- * follow_type: 1=company, 3=channel
1917
+ * @param followValues - List of follow values (each with 'follow_type' and 'follow_value')
1918
+ * follow_type: "company", "channel"
1904
1919
  * @returns Status message
1905
1920
  *
1906
1921
  * @example
1907
1922
  * ```typescript
1908
1923
  * await client.following.setGroupFollows('group_123', [
1909
- * { follow_type: 1, follow_value: 'US:AAPL' },
1910
- * { follow_type: 1, follow_value: 'HK:00700' }
1924
+ * { follow_type: 'company', follow_value: 'US:AAPL' },
1925
+ * { follow_type: 'company', follow_value: 'HK:00700' }
1911
1926
  * ]);
1912
1927
  * ```
1913
1928
  */
package/dist/index.mjs CHANGED
@@ -903,6 +903,8 @@ var QuantModule = class {
903
903
  * - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20), PE(), ROE(), RSI(14), etc.
904
904
  *
905
905
  * @param params - Backtest parameters
906
+ * @param params.autoClose Whether to automatically close positions at end of backtest (default true)
907
+ * @param params.signalFactors Signal factors dictionary for custom strategy pre-computation
906
908
  * @returns Backtest results
907
909
  *
908
910
  * @example
@@ -911,7 +913,7 @@ var QuantModule = class {
911
913
  * const result = await client.quant.backtest({
912
914
  * startDate: '2023-01-01',
913
915
  * endDate: '2024-01-01',
914
- * symbol: '000001',
916
+ * symbols: ['000001'],
915
917
  * entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 20))', // Buy when MA5 crosses above MA20
916
918
  * initialCash: 100000
917
919
  * });
@@ -924,27 +926,28 @@ var QuantModule = class {
924
926
  * const result2 = await client.quant.backtest({
925
927
  * startDate: '2023-01-01',
926
928
  * endDate: '2024-01-01',
927
- * symbol: '000001',
929
+ * symbols: ['000001'],
928
930
  * entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 20))', // Buy signal
929
931
  * exitFormula: 'CROSSDOWN(MA(CLOSE, 5), MA(CLOSE, 20))' // Sell signal
930
932
  * });
931
933
  *
932
- * // Fundamental screening backtest (note: functions require parentheses)
933
- * const result3 = await client.quant.backtest({
934
- * startDate: '2023-01-01',
935
- * endDate: '2024-01-01',
936
- * symbol: '000001',
937
- * entryFormula: '(PE() < 20) & (ROE() > 0.15)'
938
- * });
939
- *
940
- * // With custom labels for analysis
941
- * const result4 = await client.quant.backtest({
934
+ * // With custom python strategy code using signalFactors
935
+ * const customStrategy = `
936
+ * def handle_data(context, datas):
937
+ * for data in datas:
938
+ * symbol = data.name
939
+ * if not context.portfolio.get_position(symbol):
940
+ * if data.pe < 20 and data.rsi < 30: # Use pre-calculated factors
941
+ * context.order_target_percent(symbol, 0.2)
942
+ * elif data.rsi > 70:
943
+ * context.order_target_percent(symbol, 0)
944
+ * `;
945
+ * const result5 = await client.quant.backtest({
942
946
  * startDate: '2023-01-01',
943
947
  * endDate: '2024-01-01',
944
- * symbol: '000001',
945
- * entryFormula: 'RSI(14) < 30',
946
- * exitFormula: 'RSI(14) > 70',
947
- * labels: { rsi: 'RSI(14)', ma20: 'MA(CLOSE, 20)' }
948
+ * symbols: ['000001'],
949
+ * signalFactors: { rsi: 'RSI(14)', pe: 'PE_TTM()' },
950
+ * strategyCode: customStrategy
948
951
  * });
949
952
  * ```
950
953
  */
@@ -952,20 +955,32 @@ var QuantModule = class {
952
955
  const body = {
953
956
  start_date: params.startDate,
954
957
  end_date: params.endDate,
955
- symbol: params.symbol,
956
958
  market: params.market || "cn",
957
- entry_formula: params.entryFormula,
958
959
  initial_cash: params.initialCash ?? 1e5,
959
960
  commission: params.commission ?? 0,
960
961
  stop_loss: params.stopLoss ?? 0,
961
- sizer_percent: params.sizerPercent ?? 99,
962
+ position_size: params.positionSize ?? 0.2,
963
+ max_positions: params.maxPositions ?? 5,
964
+ min_volume: params.minVolume ?? 100,
962
965
  auto_close: params.autoClose ?? true
963
966
  };
967
+ if (params.symbols !== void 0) {
968
+ body.symbols = params.symbols;
969
+ }
970
+ if (params.filterFormula !== void 0) {
971
+ body.filter_formula = params.filterFormula;
972
+ }
973
+ if (params.entryFormula !== void 0) {
974
+ body.entry_formula = params.entryFormula;
975
+ }
976
+ if (params.strategyCode !== void 0) {
977
+ body.strategy_code = params.strategyCode;
978
+ }
964
979
  if (params.exitFormula !== void 0) {
965
980
  body.exit_formula = params.exitFormula;
966
981
  }
967
- if (params.labels !== void 0) {
968
- body.labels = params.labels;
982
+ if (params.signalFactors !== void 0) {
983
+ body.signal_factors = params.signalFactors;
969
984
  }
970
985
  return this.client.post("/v1/quant/backtest", body);
971
986
  }
@@ -1719,15 +1734,15 @@ var FollowingModule = class {
1719
1734
  * Create a new follow group
1720
1735
  *
1721
1736
  * @param name - Group name
1722
- * @param followValues - List of follow values (each with 'follow_type' as int and 'follow_value' as string)
1723
- * follow_type: 1=company, 3=channel
1737
+ * @param followValues - List of follow values (each with 'follow_type' and 'follow_value')
1738
+ * follow_type: "company", "channel"
1724
1739
  * @returns Created group information including group_id, name, and count
1725
1740
  *
1726
1741
  * @example
1727
1742
  * ```typescript
1728
1743
  * const result = await client.following.createFollowGroup('My Stocks', [
1729
- * { follow_type: 1, follow_value: 'US:AAPL' },
1730
- * { follow_type: 1, follow_value: 'HK:00700' }
1744
+ * { follow_type: 'company', follow_value: 'US:AAPL' },
1745
+ * { follow_type: 'company', follow_value: 'HK:00700' }
1731
1746
  * ]);
1732
1747
  * console.log(`Created group: ${result.group_id}`);
1733
1748
  * ```
@@ -1817,14 +1832,14 @@ var FollowingModule = class {
1817
1832
  * Add follows to a group
1818
1833
  *
1819
1834
  * @param groupId - Group ID
1820
- * @param followValues - List of follow values (each with 'follow_type' as int and 'follow_value' as string)
1821
- * follow_type: 1=company, 3=channel
1835
+ * @param followValues - List of follow values (each with 'follow_type' and 'follow_value')
1836
+ * follow_type: "company", "channel"
1822
1837
  * @returns Status message
1823
1838
  *
1824
1839
  * @example
1825
1840
  * ```typescript
1826
1841
  * await client.following.addFollowsToGroup('group_123', [
1827
- * { follow_type: 1, follow_value: 'US:TSLA' }
1842
+ * { follow_type: 'company', follow_value: 'US:TSLA' }
1828
1843
  * ]);
1829
1844
  * ```
1830
1845
  */
@@ -1855,15 +1870,15 @@ var FollowingModule = class {
1855
1870
  * Set follows for a group (replace all existing follows)
1856
1871
  *
1857
1872
  * @param groupId - Group ID
1858
- * @param followValues - List of follow values (each with 'follow_type' as int and 'follow_value' as string)
1859
- * follow_type: 1=company, 3=channel
1873
+ * @param followValues - List of follow values (each with 'follow_type' and 'follow_value')
1874
+ * follow_type: "company", "channel"
1860
1875
  * @returns Status message
1861
1876
  *
1862
1877
  * @example
1863
1878
  * ```typescript
1864
1879
  * await client.following.setGroupFollows('group_123', [
1865
- * { follow_type: 1, follow_value: 'US:AAPL' },
1866
- * { follow_type: 1, follow_value: 'HK:00700' }
1880
+ * { follow_type: 'company', follow_value: 'US:AAPL' },
1881
+ * { follow_type: 'company', follow_value: 'HK:00700' }
1867
1882
  * ]);
1868
1883
  * ```
1869
1884
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reportify-sdk",
3
- "version": "0.3.23",
3
+ "version": "0.3.25",
4
4
  "description": "TypeScript SDK for Reportify API - Financial data and document search",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",