reportify-sdk 0.3.26 → 0.3.28
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 +112 -82
- package/dist/index.d.ts +112 -82
- package/dist/index.js +108 -81
- package/dist/index.mjs +108 -81
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -656,33 +656,19 @@ declare class DocsModule {
|
|
|
656
656
|
/**
|
|
657
657
|
* Quant Module
|
|
658
658
|
*
|
|
659
|
-
* Provides quantitative analysis tools including
|
|
659
|
+
* Provides quantitative analysis tools including factors (technical and fundamental), quotes, and backtesting.
|
|
660
660
|
* Based on Mai-language syntax compatible with TongDaXin/TongHuaShun.
|
|
661
|
+
*
|
|
662
|
+
* All technical indicators (RSI, MACD, KDJ, etc.) are now available as factors through the unified factors API.
|
|
661
663
|
*/
|
|
662
664
|
|
|
663
665
|
type StockMarket = 'cn' | 'hk' | 'us';
|
|
664
|
-
interface IndicatorMeta {
|
|
665
|
-
name: string;
|
|
666
|
-
description: string;
|
|
667
|
-
fields: string[];
|
|
668
|
-
}
|
|
669
|
-
interface IndicatorComputeParams {
|
|
670
|
-
symbols: string[];
|
|
671
|
-
formula: string;
|
|
672
|
-
market?: StockMarket;
|
|
673
|
-
startDate?: string;
|
|
674
|
-
endDate?: string;
|
|
675
|
-
}
|
|
676
|
-
interface IndicatorData {
|
|
677
|
-
symbol: string;
|
|
678
|
-
date: string;
|
|
679
|
-
[key: string]: unknown;
|
|
680
|
-
}
|
|
681
666
|
interface FactorMeta {
|
|
682
667
|
name: string;
|
|
683
668
|
type: 'variable' | 'function';
|
|
684
669
|
level: 0 | 1 | 2;
|
|
685
670
|
description: string;
|
|
671
|
+
fields?: string[];
|
|
686
672
|
}
|
|
687
673
|
interface FactorComputeParams {
|
|
688
674
|
symbols: string[];
|
|
@@ -714,6 +700,16 @@ interface BatchOHLCVParams {
|
|
|
714
700
|
startDate?: string;
|
|
715
701
|
endDate?: string;
|
|
716
702
|
}
|
|
703
|
+
interface FactorComputeData {
|
|
704
|
+
symbol: string;
|
|
705
|
+
date: string;
|
|
706
|
+
name?: string;
|
|
707
|
+
name_en?: string;
|
|
708
|
+
close?: number;
|
|
709
|
+
factor_value?: number | boolean;
|
|
710
|
+
indicators?: Record<string, number | boolean>;
|
|
711
|
+
[key: string]: unknown;
|
|
712
|
+
}
|
|
717
713
|
interface OHLCVData {
|
|
718
714
|
symbol: string;
|
|
719
715
|
date: string;
|
|
@@ -766,6 +762,19 @@ interface BatchMinuteParams {
|
|
|
766
762
|
endDateTime: string;
|
|
767
763
|
market?: StockMarket;
|
|
768
764
|
}
|
|
765
|
+
interface BacktestUploadParams {
|
|
766
|
+
file: File;
|
|
767
|
+
entryFormula?: string;
|
|
768
|
+
strategyCode?: string;
|
|
769
|
+
exitFormula?: string;
|
|
770
|
+
initialCash?: number;
|
|
771
|
+
commission?: number;
|
|
772
|
+
positionSize?: number;
|
|
773
|
+
maxPositions?: number;
|
|
774
|
+
minVolume?: number;
|
|
775
|
+
autoClose?: boolean;
|
|
776
|
+
signalFactors?: Record<string, string>;
|
|
777
|
+
}
|
|
769
778
|
interface BacktestResult {
|
|
770
779
|
success: boolean;
|
|
771
780
|
initial_cash: number;
|
|
@@ -797,10 +806,21 @@ interface BacktestResult {
|
|
|
797
806
|
/**
|
|
798
807
|
* Quantitative analysis module
|
|
799
808
|
*
|
|
809
|
+
* Access factors (including technical indicators and fundamental factors), OHLCV quotes, and backtesting functionality.
|
|
810
|
+
* Uses Mai-language syntax for formulas.
|
|
811
|
+
*
|
|
812
|
+
* Technical indicators are now part of the unified factors system:
|
|
813
|
+
* - Level 0: Basic variables (CLOSE, OPEN, HIGH, LOW, VOLUME) and core functions (MA, EMA, REF, etc.)
|
|
814
|
+
* - Level 1: Application functions (CROSS, COUNT, EVERY, etc.)
|
|
815
|
+
* - Level 2: Technical indicators (RSI, MACD, KDJ, BOLL, etc.) and fundamental factors (PE, ROE, etc.)
|
|
816
|
+
*
|
|
800
817
|
* @example
|
|
801
818
|
* ```typescript
|
|
802
|
-
* //
|
|
803
|
-
* const
|
|
819
|
+
* // List all available factors (including technical indicators)
|
|
820
|
+
* const factors = await client.quant.factors();
|
|
821
|
+
*
|
|
822
|
+
* // Compute RSI (now through factors API)
|
|
823
|
+
* const data = await client.quant.factorsCompute({
|
|
804
824
|
* symbols: ['000001'],
|
|
805
825
|
* formula: 'RSI(14)'
|
|
806
826
|
* });
|
|
@@ -815,63 +835,31 @@ declare class QuantModule {
|
|
|
815
835
|
private client;
|
|
816
836
|
constructor(client: Reportify);
|
|
817
837
|
/**
|
|
818
|
-
* Get list of available
|
|
819
|
-
*
|
|
820
|
-
* All indicators are functions and require parentheses when used (e.g., MA(CLOSE, 20), RSI(14), MACD()).
|
|
838
|
+
* Get list of available factors (variables, functions, and indicators)
|
|
821
839
|
*
|
|
822
|
-
*
|
|
823
|
-
*
|
|
824
|
-
*
|
|
825
|
-
*
|
|
826
|
-
*
|
|
827
|
-
* indicators.forEach(ind => {
|
|
828
|
-
* console.log(`${ind.name}: ${ind.description}`);
|
|
829
|
-
* console.log(` Fields: ${ind.fields.join(', ')}`);
|
|
830
|
-
* });
|
|
831
|
-
* ```
|
|
832
|
-
*/
|
|
833
|
-
indicators(): Promise<IndicatorMeta[]>;
|
|
834
|
-
/**
|
|
835
|
-
* Compute indicator values for given symbols
|
|
840
|
+
* Returns factors organized by level:
|
|
841
|
+
* - Level 0 Variables: CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT (price data, no parentheses)
|
|
842
|
+
* - Level 0 Functions: MA(), EMA(), REF(), HHV(), LLV(), STD(), etc. (require parentheses)
|
|
843
|
+
* - Level 1 Functions: CROSS(), COUNT(), EVERY(), etc. (require parentheses)
|
|
844
|
+
* - Level 2 Functions: Technical indicators (MACD(), KDJ(), RSI(), BOLL(), etc.) and fundamental factors (PE(), ROE(), etc.)
|
|
836
845
|
*
|
|
837
846
|
* Variables vs Functions:
|
|
838
|
-
* - Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT
|
|
839
|
-
* - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20),
|
|
847
|
+
* - Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT
|
|
848
|
+
* - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20), PE(), ROE(), RSI(14), etc.
|
|
840
849
|
*
|
|
841
|
-
* @
|
|
842
|
-
* @returns Array of indicator data
|
|
850
|
+
* @returns Array of factor definitions with name, type, level, description, and optional fields
|
|
843
851
|
*
|
|
844
852
|
* @example
|
|
845
853
|
* ```typescript
|
|
846
|
-
*
|
|
847
|
-
*
|
|
848
|
-
*
|
|
849
|
-
*
|
|
850
|
-
* });
|
|
851
|
-
*
|
|
852
|
-
* // MACD indicator
|
|
853
|
-
* const data = await client.quant.indicatorsCompute({
|
|
854
|
-
* symbols: ['000001'],
|
|
855
|
-
* formula: 'MACD()'
|
|
856
|
-
* });
|
|
857
|
-
*
|
|
858
|
-
* // Standard deviation
|
|
859
|
-
* const data = await client.quant.indicatorsCompute({
|
|
860
|
-
* symbols: ['000001'],
|
|
861
|
-
* formula: 'STD(CLOSE, 20)'
|
|
854
|
+
* const factors = await client.quant.factors();
|
|
855
|
+
* factors.forEach(f => {
|
|
856
|
+
* console.log(`${f.name} (${f.type}, level ${f.level})`);
|
|
857
|
+
* if (f.fields) {
|
|
858
|
+
* console.log(` Fields: ${f.fields.join(', ')}`);
|
|
859
|
+
* }
|
|
862
860
|
* });
|
|
863
861
|
* ```
|
|
864
862
|
*/
|
|
865
|
-
indicatorsCompute(params: IndicatorComputeParams): Promise<IndicatorData[]>;
|
|
866
|
-
/**
|
|
867
|
-
* Get list of available factors (variables and functions)
|
|
868
|
-
*
|
|
869
|
-
* Variables vs Functions:
|
|
870
|
-
* - Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT, PE_TTM, ROE_TTM, etc.
|
|
871
|
-
* - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20), PE(), ROE(), RSI(14), etc.
|
|
872
|
-
*
|
|
873
|
-
* @returns Array of factor definitions organized by level
|
|
874
|
-
*/
|
|
875
863
|
factors(): Promise<FactorMeta[]>;
|
|
876
864
|
/**
|
|
877
865
|
* Compute factor values for given symbols
|
|
@@ -887,32 +875,32 @@ declare class QuantModule {
|
|
|
887
875
|
*
|
|
888
876
|
* @example
|
|
889
877
|
* ```typescript
|
|
890
|
-
* //
|
|
878
|
+
* // Technical indicators (RSI, MACD, etc.)
|
|
891
879
|
* const data = await client.quant.factorsCompute({
|
|
892
880
|
* symbols: ['000001'],
|
|
893
881
|
* formula: 'RSI(14)'
|
|
894
882
|
* });
|
|
895
883
|
*
|
|
896
|
-
* // MACD
|
|
884
|
+
* // MACD indicator
|
|
897
885
|
* const data = await client.quant.factorsCompute({
|
|
898
886
|
* symbols: ['000001'],
|
|
899
887
|
* formula: 'MACD().dif'
|
|
900
888
|
* });
|
|
901
889
|
*
|
|
902
|
-
* //
|
|
890
|
+
* // Core functions
|
|
903
891
|
* const data = await client.quant.factorsCompute({
|
|
904
892
|
* symbols: ['000001'],
|
|
905
|
-
* formula: '
|
|
893
|
+
* formula: 'MA(CLOSE, 20)'
|
|
906
894
|
* });
|
|
907
895
|
*
|
|
908
|
-
* // Fundamental factors
|
|
896
|
+
* // Fundamental factors
|
|
909
897
|
* const data = await client.quant.factorsCompute({
|
|
910
898
|
* symbols: ['000001'],
|
|
911
899
|
* formula: 'PE()'
|
|
912
900
|
* });
|
|
913
901
|
* ```
|
|
914
902
|
*/
|
|
915
|
-
factorsCompute(params: FactorComputeParams): Promise<
|
|
903
|
+
factorsCompute(params: FactorComputeParams): Promise<FactorComputeData[]>;
|
|
916
904
|
/**
|
|
917
905
|
* Screen stocks based on factor formula
|
|
918
906
|
*
|
|
@@ -925,7 +913,7 @@ declare class QuantModule {
|
|
|
925
913
|
*
|
|
926
914
|
* @example
|
|
927
915
|
* ```typescript
|
|
928
|
-
* //
|
|
916
|
+
* // Technical screening
|
|
929
917
|
* const stocks = await client.quant.factorsScreen({
|
|
930
918
|
* formula: 'RSI(14) < 30'
|
|
931
919
|
* });
|
|
@@ -935,12 +923,7 @@ declare class QuantModule {
|
|
|
935
923
|
* formula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))'
|
|
936
924
|
* });
|
|
937
925
|
*
|
|
938
|
-
* //
|
|
939
|
-
* const stocks = await client.quant.factorsScreen({
|
|
940
|
-
* formula: '(CLOSE > MA(CLOSE, 20)) & (MA(CLOSE, 20) > MA(CLOSE, 60))'
|
|
941
|
-
* });
|
|
942
|
-
*
|
|
943
|
-
* // Fundamental screening (note: functions require parentheses)
|
|
926
|
+
* // Fundamental screening
|
|
944
927
|
* const stocks = await client.quant.factorsScreen({
|
|
945
928
|
* formula: '(PE() < 20) & (ROE() > 0.15)'
|
|
946
929
|
* });
|
|
@@ -1087,7 +1070,7 @@ declare class QuantModule {
|
|
|
1087
1070
|
* for data in datas:
|
|
1088
1071
|
* symbol = data.name
|
|
1089
1072
|
* if not context.portfolio.get_position(symbol):
|
|
1090
|
-
* if data.pe < 20 and data.rsi < 30:
|
|
1073
|
+
* if data.pe < 20 and data.rsi < 30: // Use pre-calculated factors
|
|
1091
1074
|
* context.order_target_percent(symbol, 0.2)
|
|
1092
1075
|
* elif data.rsi > 70:
|
|
1093
1076
|
* context.order_target_percent(symbol, 0)
|
|
@@ -1102,6 +1085,52 @@ declare class QuantModule {
|
|
|
1102
1085
|
* ```
|
|
1103
1086
|
*/
|
|
1104
1087
|
backtest(params: BacktestParams): Promise<BacktestResult>;
|
|
1088
|
+
/**
|
|
1089
|
+
* Upload an Excel file to run backtest
|
|
1090
|
+
*
|
|
1091
|
+
* Upload an Excel file (.xlsx/.xls) containing OHLCV data for backtesting.
|
|
1092
|
+
* This allows you to use your own market data instead of the system's built-in data source.
|
|
1093
|
+
*
|
|
1094
|
+
* Excel file format requirements:
|
|
1095
|
+
* - Required columns: date, open, high, low, close
|
|
1096
|
+
* - Optional columns: symbol (required for multi-symbol), volume, amount
|
|
1097
|
+
* - Custom fields: any ASCII-named columns with numeric values (e.g., pe, market_cap, pb_ratio)
|
|
1098
|
+
*
|
|
1099
|
+
* @param params - Upload backtest parameters
|
|
1100
|
+
* @returns Backtest results
|
|
1101
|
+
*
|
|
1102
|
+
* @example
|
|
1103
|
+
* ```typescript
|
|
1104
|
+
* // Upload from file input
|
|
1105
|
+
* const fileInput = document.getElementById('file') as HTMLInputElement;
|
|
1106
|
+
* const result = await client.quant.backtestUpload({
|
|
1107
|
+
* file: fileInput.files[0],
|
|
1108
|
+
* entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))',
|
|
1109
|
+
* exitFormula: 'CROSS(MA(CLOSE, 10), MA(CLOSE, 5))',
|
|
1110
|
+
* initialCash: 100000,
|
|
1111
|
+
* commission: 0.0003
|
|
1112
|
+
* });
|
|
1113
|
+
*
|
|
1114
|
+
* console.log(`Total Return: ${(result.total_return_pct * 100).toFixed(2)}%`);
|
|
1115
|
+
*
|
|
1116
|
+
* // With custom strategy code
|
|
1117
|
+
* const result2 = await client.quant.backtestUpload({
|
|
1118
|
+
* file: fileInput.files[0],
|
|
1119
|
+
* signalFactors: { ma5: 'MA(CLOSE, 5)', ma20: 'MA(CLOSE, 20)' },
|
|
1120
|
+
* strategyCode: `
|
|
1121
|
+
* def handle_data(context, datas):
|
|
1122
|
+
* for data in datas:
|
|
1123
|
+
* symbol = data.name
|
|
1124
|
+
* if not context.portfolio.get_position(symbol):
|
|
1125
|
+
* if data.ma5 > data.ma20:
|
|
1126
|
+
* context.order_target_percent(symbol, 0.2)
|
|
1127
|
+
* elif data.ma5 < data.ma20:
|
|
1128
|
+
* context.order_target_percent(symbol, 0)
|
|
1129
|
+
* `
|
|
1130
|
+
* });
|
|
1131
|
+
* ```
|
|
1132
|
+
*/
|
|
1133
|
+
backtestUpload(params: BacktestUploadParams): Promise<BacktestResult>;
|
|
1105
1134
|
}
|
|
1106
1135
|
|
|
1107
1136
|
/**
|
|
@@ -1924,6 +1953,7 @@ declare class Reportify {
|
|
|
1924
1953
|
request<T = unknown>(method: string, path: string, options?: {
|
|
1925
1954
|
params?: Record<string, unknown>;
|
|
1926
1955
|
body?: Record<string, unknown>;
|
|
1956
|
+
formData?: FormData;
|
|
1927
1957
|
}): Promise<T>;
|
|
1928
1958
|
/**
|
|
1929
1959
|
* Make a GET request
|
|
@@ -1947,4 +1977,4 @@ declare class Reportify {
|
|
|
1947
1977
|
getBytes(path: string): Promise<ArrayBuffer>;
|
|
1948
1978
|
}
|
|
1949
1979
|
|
|
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
|
|
1980
|
+
export { APIError, type AgentConversation, type AgentMessage, AgentModule, AuthenticationError, type BacktestParams, type BacktestResult, type BacktestUploadParams, 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 FactorComputeData, type FactorComputeParams, type FactorMeta, type FinancialStatement, type FollowedCompany, FollowingModule, type IPOEvent, type IPOStatus, type IndexConstituent, type IndexFund, 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
|
@@ -656,33 +656,19 @@ declare class DocsModule {
|
|
|
656
656
|
/**
|
|
657
657
|
* Quant Module
|
|
658
658
|
*
|
|
659
|
-
* Provides quantitative analysis tools including
|
|
659
|
+
* Provides quantitative analysis tools including factors (technical and fundamental), quotes, and backtesting.
|
|
660
660
|
* Based on Mai-language syntax compatible with TongDaXin/TongHuaShun.
|
|
661
|
+
*
|
|
662
|
+
* All technical indicators (RSI, MACD, KDJ, etc.) are now available as factors through the unified factors API.
|
|
661
663
|
*/
|
|
662
664
|
|
|
663
665
|
type StockMarket = 'cn' | 'hk' | 'us';
|
|
664
|
-
interface IndicatorMeta {
|
|
665
|
-
name: string;
|
|
666
|
-
description: string;
|
|
667
|
-
fields: string[];
|
|
668
|
-
}
|
|
669
|
-
interface IndicatorComputeParams {
|
|
670
|
-
symbols: string[];
|
|
671
|
-
formula: string;
|
|
672
|
-
market?: StockMarket;
|
|
673
|
-
startDate?: string;
|
|
674
|
-
endDate?: string;
|
|
675
|
-
}
|
|
676
|
-
interface IndicatorData {
|
|
677
|
-
symbol: string;
|
|
678
|
-
date: string;
|
|
679
|
-
[key: string]: unknown;
|
|
680
|
-
}
|
|
681
666
|
interface FactorMeta {
|
|
682
667
|
name: string;
|
|
683
668
|
type: 'variable' | 'function';
|
|
684
669
|
level: 0 | 1 | 2;
|
|
685
670
|
description: string;
|
|
671
|
+
fields?: string[];
|
|
686
672
|
}
|
|
687
673
|
interface FactorComputeParams {
|
|
688
674
|
symbols: string[];
|
|
@@ -714,6 +700,16 @@ interface BatchOHLCVParams {
|
|
|
714
700
|
startDate?: string;
|
|
715
701
|
endDate?: string;
|
|
716
702
|
}
|
|
703
|
+
interface FactorComputeData {
|
|
704
|
+
symbol: string;
|
|
705
|
+
date: string;
|
|
706
|
+
name?: string;
|
|
707
|
+
name_en?: string;
|
|
708
|
+
close?: number;
|
|
709
|
+
factor_value?: number | boolean;
|
|
710
|
+
indicators?: Record<string, number | boolean>;
|
|
711
|
+
[key: string]: unknown;
|
|
712
|
+
}
|
|
717
713
|
interface OHLCVData {
|
|
718
714
|
symbol: string;
|
|
719
715
|
date: string;
|
|
@@ -766,6 +762,19 @@ interface BatchMinuteParams {
|
|
|
766
762
|
endDateTime: string;
|
|
767
763
|
market?: StockMarket;
|
|
768
764
|
}
|
|
765
|
+
interface BacktestUploadParams {
|
|
766
|
+
file: File;
|
|
767
|
+
entryFormula?: string;
|
|
768
|
+
strategyCode?: string;
|
|
769
|
+
exitFormula?: string;
|
|
770
|
+
initialCash?: number;
|
|
771
|
+
commission?: number;
|
|
772
|
+
positionSize?: number;
|
|
773
|
+
maxPositions?: number;
|
|
774
|
+
minVolume?: number;
|
|
775
|
+
autoClose?: boolean;
|
|
776
|
+
signalFactors?: Record<string, string>;
|
|
777
|
+
}
|
|
769
778
|
interface BacktestResult {
|
|
770
779
|
success: boolean;
|
|
771
780
|
initial_cash: number;
|
|
@@ -797,10 +806,21 @@ interface BacktestResult {
|
|
|
797
806
|
/**
|
|
798
807
|
* Quantitative analysis module
|
|
799
808
|
*
|
|
809
|
+
* Access factors (including technical indicators and fundamental factors), OHLCV quotes, and backtesting functionality.
|
|
810
|
+
* Uses Mai-language syntax for formulas.
|
|
811
|
+
*
|
|
812
|
+
* Technical indicators are now part of the unified factors system:
|
|
813
|
+
* - Level 0: Basic variables (CLOSE, OPEN, HIGH, LOW, VOLUME) and core functions (MA, EMA, REF, etc.)
|
|
814
|
+
* - Level 1: Application functions (CROSS, COUNT, EVERY, etc.)
|
|
815
|
+
* - Level 2: Technical indicators (RSI, MACD, KDJ, BOLL, etc.) and fundamental factors (PE, ROE, etc.)
|
|
816
|
+
*
|
|
800
817
|
* @example
|
|
801
818
|
* ```typescript
|
|
802
|
-
* //
|
|
803
|
-
* const
|
|
819
|
+
* // List all available factors (including technical indicators)
|
|
820
|
+
* const factors = await client.quant.factors();
|
|
821
|
+
*
|
|
822
|
+
* // Compute RSI (now through factors API)
|
|
823
|
+
* const data = await client.quant.factorsCompute({
|
|
804
824
|
* symbols: ['000001'],
|
|
805
825
|
* formula: 'RSI(14)'
|
|
806
826
|
* });
|
|
@@ -815,63 +835,31 @@ declare class QuantModule {
|
|
|
815
835
|
private client;
|
|
816
836
|
constructor(client: Reportify);
|
|
817
837
|
/**
|
|
818
|
-
* Get list of available
|
|
819
|
-
*
|
|
820
|
-
* All indicators are functions and require parentheses when used (e.g., MA(CLOSE, 20), RSI(14), MACD()).
|
|
838
|
+
* Get list of available factors (variables, functions, and indicators)
|
|
821
839
|
*
|
|
822
|
-
*
|
|
823
|
-
*
|
|
824
|
-
*
|
|
825
|
-
*
|
|
826
|
-
*
|
|
827
|
-
* indicators.forEach(ind => {
|
|
828
|
-
* console.log(`${ind.name}: ${ind.description}`);
|
|
829
|
-
* console.log(` Fields: ${ind.fields.join(', ')}`);
|
|
830
|
-
* });
|
|
831
|
-
* ```
|
|
832
|
-
*/
|
|
833
|
-
indicators(): Promise<IndicatorMeta[]>;
|
|
834
|
-
/**
|
|
835
|
-
* Compute indicator values for given symbols
|
|
840
|
+
* Returns factors organized by level:
|
|
841
|
+
* - Level 0 Variables: CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT (price data, no parentheses)
|
|
842
|
+
* - Level 0 Functions: MA(), EMA(), REF(), HHV(), LLV(), STD(), etc. (require parentheses)
|
|
843
|
+
* - Level 1 Functions: CROSS(), COUNT(), EVERY(), etc. (require parentheses)
|
|
844
|
+
* - Level 2 Functions: Technical indicators (MACD(), KDJ(), RSI(), BOLL(), etc.) and fundamental factors (PE(), ROE(), etc.)
|
|
836
845
|
*
|
|
837
846
|
* Variables vs Functions:
|
|
838
|
-
* - Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT
|
|
839
|
-
* - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20),
|
|
847
|
+
* - Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT
|
|
848
|
+
* - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20), PE(), ROE(), RSI(14), etc.
|
|
840
849
|
*
|
|
841
|
-
* @
|
|
842
|
-
* @returns Array of indicator data
|
|
850
|
+
* @returns Array of factor definitions with name, type, level, description, and optional fields
|
|
843
851
|
*
|
|
844
852
|
* @example
|
|
845
853
|
* ```typescript
|
|
846
|
-
*
|
|
847
|
-
*
|
|
848
|
-
*
|
|
849
|
-
*
|
|
850
|
-
* });
|
|
851
|
-
*
|
|
852
|
-
* // MACD indicator
|
|
853
|
-
* const data = await client.quant.indicatorsCompute({
|
|
854
|
-
* symbols: ['000001'],
|
|
855
|
-
* formula: 'MACD()'
|
|
856
|
-
* });
|
|
857
|
-
*
|
|
858
|
-
* // Standard deviation
|
|
859
|
-
* const data = await client.quant.indicatorsCompute({
|
|
860
|
-
* symbols: ['000001'],
|
|
861
|
-
* formula: 'STD(CLOSE, 20)'
|
|
854
|
+
* const factors = await client.quant.factors();
|
|
855
|
+
* factors.forEach(f => {
|
|
856
|
+
* console.log(`${f.name} (${f.type}, level ${f.level})`);
|
|
857
|
+
* if (f.fields) {
|
|
858
|
+
* console.log(` Fields: ${f.fields.join(', ')}`);
|
|
859
|
+
* }
|
|
862
860
|
* });
|
|
863
861
|
* ```
|
|
864
862
|
*/
|
|
865
|
-
indicatorsCompute(params: IndicatorComputeParams): Promise<IndicatorData[]>;
|
|
866
|
-
/**
|
|
867
|
-
* Get list of available factors (variables and functions)
|
|
868
|
-
*
|
|
869
|
-
* Variables vs Functions:
|
|
870
|
-
* - Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT, PE_TTM, ROE_TTM, etc.
|
|
871
|
-
* - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20), PE(), ROE(), RSI(14), etc.
|
|
872
|
-
*
|
|
873
|
-
* @returns Array of factor definitions organized by level
|
|
874
|
-
*/
|
|
875
863
|
factors(): Promise<FactorMeta[]>;
|
|
876
864
|
/**
|
|
877
865
|
* Compute factor values for given symbols
|
|
@@ -887,32 +875,32 @@ declare class QuantModule {
|
|
|
887
875
|
*
|
|
888
876
|
* @example
|
|
889
877
|
* ```typescript
|
|
890
|
-
* //
|
|
878
|
+
* // Technical indicators (RSI, MACD, etc.)
|
|
891
879
|
* const data = await client.quant.factorsCompute({
|
|
892
880
|
* symbols: ['000001'],
|
|
893
881
|
* formula: 'RSI(14)'
|
|
894
882
|
* });
|
|
895
883
|
*
|
|
896
|
-
* // MACD
|
|
884
|
+
* // MACD indicator
|
|
897
885
|
* const data = await client.quant.factorsCompute({
|
|
898
886
|
* symbols: ['000001'],
|
|
899
887
|
* formula: 'MACD().dif'
|
|
900
888
|
* });
|
|
901
889
|
*
|
|
902
|
-
* //
|
|
890
|
+
* // Core functions
|
|
903
891
|
* const data = await client.quant.factorsCompute({
|
|
904
892
|
* symbols: ['000001'],
|
|
905
|
-
* formula: '
|
|
893
|
+
* formula: 'MA(CLOSE, 20)'
|
|
906
894
|
* });
|
|
907
895
|
*
|
|
908
|
-
* // Fundamental factors
|
|
896
|
+
* // Fundamental factors
|
|
909
897
|
* const data = await client.quant.factorsCompute({
|
|
910
898
|
* symbols: ['000001'],
|
|
911
899
|
* formula: 'PE()'
|
|
912
900
|
* });
|
|
913
901
|
* ```
|
|
914
902
|
*/
|
|
915
|
-
factorsCompute(params: FactorComputeParams): Promise<
|
|
903
|
+
factorsCompute(params: FactorComputeParams): Promise<FactorComputeData[]>;
|
|
916
904
|
/**
|
|
917
905
|
* Screen stocks based on factor formula
|
|
918
906
|
*
|
|
@@ -925,7 +913,7 @@ declare class QuantModule {
|
|
|
925
913
|
*
|
|
926
914
|
* @example
|
|
927
915
|
* ```typescript
|
|
928
|
-
* //
|
|
916
|
+
* // Technical screening
|
|
929
917
|
* const stocks = await client.quant.factorsScreen({
|
|
930
918
|
* formula: 'RSI(14) < 30'
|
|
931
919
|
* });
|
|
@@ -935,12 +923,7 @@ declare class QuantModule {
|
|
|
935
923
|
* formula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))'
|
|
936
924
|
* });
|
|
937
925
|
*
|
|
938
|
-
* //
|
|
939
|
-
* const stocks = await client.quant.factorsScreen({
|
|
940
|
-
* formula: '(CLOSE > MA(CLOSE, 20)) & (MA(CLOSE, 20) > MA(CLOSE, 60))'
|
|
941
|
-
* });
|
|
942
|
-
*
|
|
943
|
-
* // Fundamental screening (note: functions require parentheses)
|
|
926
|
+
* // Fundamental screening
|
|
944
927
|
* const stocks = await client.quant.factorsScreen({
|
|
945
928
|
* formula: '(PE() < 20) & (ROE() > 0.15)'
|
|
946
929
|
* });
|
|
@@ -1087,7 +1070,7 @@ declare class QuantModule {
|
|
|
1087
1070
|
* for data in datas:
|
|
1088
1071
|
* symbol = data.name
|
|
1089
1072
|
* if not context.portfolio.get_position(symbol):
|
|
1090
|
-
* if data.pe < 20 and data.rsi < 30:
|
|
1073
|
+
* if data.pe < 20 and data.rsi < 30: // Use pre-calculated factors
|
|
1091
1074
|
* context.order_target_percent(symbol, 0.2)
|
|
1092
1075
|
* elif data.rsi > 70:
|
|
1093
1076
|
* context.order_target_percent(symbol, 0)
|
|
@@ -1102,6 +1085,52 @@ declare class QuantModule {
|
|
|
1102
1085
|
* ```
|
|
1103
1086
|
*/
|
|
1104
1087
|
backtest(params: BacktestParams): Promise<BacktestResult>;
|
|
1088
|
+
/**
|
|
1089
|
+
* Upload an Excel file to run backtest
|
|
1090
|
+
*
|
|
1091
|
+
* Upload an Excel file (.xlsx/.xls) containing OHLCV data for backtesting.
|
|
1092
|
+
* This allows you to use your own market data instead of the system's built-in data source.
|
|
1093
|
+
*
|
|
1094
|
+
* Excel file format requirements:
|
|
1095
|
+
* - Required columns: date, open, high, low, close
|
|
1096
|
+
* - Optional columns: symbol (required for multi-symbol), volume, amount
|
|
1097
|
+
* - Custom fields: any ASCII-named columns with numeric values (e.g., pe, market_cap, pb_ratio)
|
|
1098
|
+
*
|
|
1099
|
+
* @param params - Upload backtest parameters
|
|
1100
|
+
* @returns Backtest results
|
|
1101
|
+
*
|
|
1102
|
+
* @example
|
|
1103
|
+
* ```typescript
|
|
1104
|
+
* // Upload from file input
|
|
1105
|
+
* const fileInput = document.getElementById('file') as HTMLInputElement;
|
|
1106
|
+
* const result = await client.quant.backtestUpload({
|
|
1107
|
+
* file: fileInput.files[0],
|
|
1108
|
+
* entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))',
|
|
1109
|
+
* exitFormula: 'CROSS(MA(CLOSE, 10), MA(CLOSE, 5))',
|
|
1110
|
+
* initialCash: 100000,
|
|
1111
|
+
* commission: 0.0003
|
|
1112
|
+
* });
|
|
1113
|
+
*
|
|
1114
|
+
* console.log(`Total Return: ${(result.total_return_pct * 100).toFixed(2)}%`);
|
|
1115
|
+
*
|
|
1116
|
+
* // With custom strategy code
|
|
1117
|
+
* const result2 = await client.quant.backtestUpload({
|
|
1118
|
+
* file: fileInput.files[0],
|
|
1119
|
+
* signalFactors: { ma5: 'MA(CLOSE, 5)', ma20: 'MA(CLOSE, 20)' },
|
|
1120
|
+
* strategyCode: `
|
|
1121
|
+
* def handle_data(context, datas):
|
|
1122
|
+
* for data in datas:
|
|
1123
|
+
* symbol = data.name
|
|
1124
|
+
* if not context.portfolio.get_position(symbol):
|
|
1125
|
+
* if data.ma5 > data.ma20:
|
|
1126
|
+
* context.order_target_percent(symbol, 0.2)
|
|
1127
|
+
* elif data.ma5 < data.ma20:
|
|
1128
|
+
* context.order_target_percent(symbol, 0)
|
|
1129
|
+
* `
|
|
1130
|
+
* });
|
|
1131
|
+
* ```
|
|
1132
|
+
*/
|
|
1133
|
+
backtestUpload(params: BacktestUploadParams): Promise<BacktestResult>;
|
|
1105
1134
|
}
|
|
1106
1135
|
|
|
1107
1136
|
/**
|
|
@@ -1924,6 +1953,7 @@ declare class Reportify {
|
|
|
1924
1953
|
request<T = unknown>(method: string, path: string, options?: {
|
|
1925
1954
|
params?: Record<string, unknown>;
|
|
1926
1955
|
body?: Record<string, unknown>;
|
|
1956
|
+
formData?: FormData;
|
|
1927
1957
|
}): Promise<T>;
|
|
1928
1958
|
/**
|
|
1929
1959
|
* Make a GET request
|
|
@@ -1947,4 +1977,4 @@ declare class Reportify {
|
|
|
1947
1977
|
getBytes(path: string): Promise<ArrayBuffer>;
|
|
1948
1978
|
}
|
|
1949
1979
|
|
|
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
|
|
1980
|
+
export { APIError, type AgentConversation, type AgentMessage, AgentModule, AuthenticationError, type BacktestParams, type BacktestResult, type BacktestUploadParams, 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 FactorComputeData, type FactorComputeParams, type FactorMeta, type FinancialStatement, type FollowedCompany, FollowingModule, type IPOEvent, type IPOStatus, type IndexConstituent, type IndexFund, 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
|
@@ -619,80 +619,34 @@ var QuantModule = class {
|
|
|
619
619
|
this.client = client;
|
|
620
620
|
}
|
|
621
621
|
// ===========================================================================
|
|
622
|
-
//
|
|
622
|
+
// Factors (includes technical indicators and fundamental factors)
|
|
623
623
|
// ===========================================================================
|
|
624
624
|
/**
|
|
625
|
-
* Get list of available
|
|
625
|
+
* Get list of available factors (variables, functions, and indicators)
|
|
626
626
|
*
|
|
627
|
-
*
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
631
|
-
*
|
|
632
|
-
* ```typescript
|
|
633
|
-
* const indicators = await client.quant.indicators();
|
|
634
|
-
* indicators.forEach(ind => {
|
|
635
|
-
* console.log(`${ind.name}: ${ind.description}`);
|
|
636
|
-
* console.log(` Fields: ${ind.fields.join(', ')}`);
|
|
637
|
-
* });
|
|
638
|
-
* ```
|
|
639
|
-
*/
|
|
640
|
-
async indicators() {
|
|
641
|
-
return this.client.get("/v1/quant/indicators");
|
|
642
|
-
}
|
|
643
|
-
/**
|
|
644
|
-
* Compute indicator values for given symbols
|
|
627
|
+
* Returns factors organized by level:
|
|
628
|
+
* - Level 0 Variables: CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT (price data, no parentheses)
|
|
629
|
+
* - Level 0 Functions: MA(), EMA(), REF(), HHV(), LLV(), STD(), etc. (require parentheses)
|
|
630
|
+
* - Level 1 Functions: CROSS(), COUNT(), EVERY(), etc. (require parentheses)
|
|
631
|
+
* - Level 2 Functions: Technical indicators (MACD(), KDJ(), RSI(), BOLL(), etc.) and fundamental factors (PE(), ROE(), etc.)
|
|
645
632
|
*
|
|
646
633
|
* Variables vs Functions:
|
|
647
|
-
* - Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT
|
|
648
|
-
* - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20),
|
|
634
|
+
* - Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT
|
|
635
|
+
* - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20), PE(), ROE(), RSI(14), etc.
|
|
649
636
|
*
|
|
650
|
-
* @
|
|
651
|
-
* @returns Array of indicator data
|
|
637
|
+
* @returns Array of factor definitions with name, type, level, description, and optional fields
|
|
652
638
|
*
|
|
653
639
|
* @example
|
|
654
640
|
* ```typescript
|
|
655
|
-
*
|
|
656
|
-
*
|
|
657
|
-
*
|
|
658
|
-
*
|
|
659
|
-
* });
|
|
660
|
-
*
|
|
661
|
-
* // MACD indicator
|
|
662
|
-
* const data = await client.quant.indicatorsCompute({
|
|
663
|
-
* symbols: ['000001'],
|
|
664
|
-
* formula: 'MACD()'
|
|
665
|
-
* });
|
|
666
|
-
*
|
|
667
|
-
* // Standard deviation
|
|
668
|
-
* const data = await client.quant.indicatorsCompute({
|
|
669
|
-
* symbols: ['000001'],
|
|
670
|
-
* formula: 'STD(CLOSE, 20)'
|
|
641
|
+
* const factors = await client.quant.factors();
|
|
642
|
+
* factors.forEach(f => {
|
|
643
|
+
* console.log(`${f.name} (${f.type}, level ${f.level})`);
|
|
644
|
+
* if (f.fields) {
|
|
645
|
+
* console.log(` Fields: ${f.fields.join(', ')}`);
|
|
646
|
+
* }
|
|
671
647
|
* });
|
|
672
648
|
* ```
|
|
673
649
|
*/
|
|
674
|
-
async indicatorsCompute(params) {
|
|
675
|
-
const response = await this.client.post("/v1/quant/indicators/compute", {
|
|
676
|
-
symbols: params.symbols,
|
|
677
|
-
formula: params.formula,
|
|
678
|
-
market: params.market || "cn",
|
|
679
|
-
start_date: params.startDate,
|
|
680
|
-
end_date: params.endDate
|
|
681
|
-
});
|
|
682
|
-
return response.datas || [];
|
|
683
|
-
}
|
|
684
|
-
// ===========================================================================
|
|
685
|
-
// Factors
|
|
686
|
-
// ===========================================================================
|
|
687
|
-
/**
|
|
688
|
-
* Get list of available factors (variables and functions)
|
|
689
|
-
*
|
|
690
|
-
* Variables vs Functions:
|
|
691
|
-
* - Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT, PE_TTM, ROE_TTM, etc.
|
|
692
|
-
* - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20), PE(), ROE(), RSI(14), etc.
|
|
693
|
-
*
|
|
694
|
-
* @returns Array of factor definitions organized by level
|
|
695
|
-
*/
|
|
696
650
|
async factors() {
|
|
697
651
|
return this.client.get("/v1/quant/factors");
|
|
698
652
|
}
|
|
@@ -710,25 +664,25 @@ var QuantModule = class {
|
|
|
710
664
|
*
|
|
711
665
|
* @example
|
|
712
666
|
* ```typescript
|
|
713
|
-
* //
|
|
667
|
+
* // Technical indicators (RSI, MACD, etc.)
|
|
714
668
|
* const data = await client.quant.factorsCompute({
|
|
715
669
|
* symbols: ['000001'],
|
|
716
670
|
* formula: 'RSI(14)'
|
|
717
671
|
* });
|
|
718
672
|
*
|
|
719
|
-
* // MACD
|
|
673
|
+
* // MACD indicator
|
|
720
674
|
* const data = await client.quant.factorsCompute({
|
|
721
675
|
* symbols: ['000001'],
|
|
722
676
|
* formula: 'MACD().dif'
|
|
723
677
|
* });
|
|
724
678
|
*
|
|
725
|
-
* //
|
|
679
|
+
* // Core functions
|
|
726
680
|
* const data = await client.quant.factorsCompute({
|
|
727
681
|
* symbols: ['000001'],
|
|
728
|
-
* formula: '
|
|
682
|
+
* formula: 'MA(CLOSE, 20)'
|
|
729
683
|
* });
|
|
730
684
|
*
|
|
731
|
-
* // Fundamental factors
|
|
685
|
+
* // Fundamental factors
|
|
732
686
|
* const data = await client.quant.factorsCompute({
|
|
733
687
|
* symbols: ['000001'],
|
|
734
688
|
* formula: 'PE()'
|
|
@@ -757,7 +711,7 @@ var QuantModule = class {
|
|
|
757
711
|
*
|
|
758
712
|
* @example
|
|
759
713
|
* ```typescript
|
|
760
|
-
* //
|
|
714
|
+
* // Technical screening
|
|
761
715
|
* const stocks = await client.quant.factorsScreen({
|
|
762
716
|
* formula: 'RSI(14) < 30'
|
|
763
717
|
* });
|
|
@@ -767,12 +721,7 @@ var QuantModule = class {
|
|
|
767
721
|
* formula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))'
|
|
768
722
|
* });
|
|
769
723
|
*
|
|
770
|
-
* //
|
|
771
|
-
* const stocks = await client.quant.factorsScreen({
|
|
772
|
-
* formula: '(CLOSE > MA(CLOSE, 20)) & (MA(CLOSE, 20) > MA(CLOSE, 60))'
|
|
773
|
-
* });
|
|
774
|
-
*
|
|
775
|
-
* // Fundamental screening (note: functions require parentheses)
|
|
724
|
+
* // Fundamental screening
|
|
776
725
|
* const stocks = await client.quant.factorsScreen({
|
|
777
726
|
* formula: '(PE() < 20) & (ROE() > 0.15)'
|
|
778
727
|
* });
|
|
@@ -981,7 +930,7 @@ var QuantModule = class {
|
|
|
981
930
|
* for data in datas:
|
|
982
931
|
* symbol = data.name
|
|
983
932
|
* if not context.portfolio.get_position(symbol):
|
|
984
|
-
* if data.pe < 20 and data.rsi < 30:
|
|
933
|
+
* if data.pe < 20 and data.rsi < 30: // Use pre-calculated factors
|
|
985
934
|
* context.order_target_percent(symbol, 0.2)
|
|
986
935
|
* elif data.rsi > 70:
|
|
987
936
|
* context.order_target_percent(symbol, 0)
|
|
@@ -1028,6 +977,77 @@ var QuantModule = class {
|
|
|
1028
977
|
}
|
|
1029
978
|
return this.client.post("/v1/quant/backtest", body);
|
|
1030
979
|
}
|
|
980
|
+
/**
|
|
981
|
+
* Upload an Excel file to run backtest
|
|
982
|
+
*
|
|
983
|
+
* Upload an Excel file (.xlsx/.xls) containing OHLCV data for backtesting.
|
|
984
|
+
* This allows you to use your own market data instead of the system's built-in data source.
|
|
985
|
+
*
|
|
986
|
+
* Excel file format requirements:
|
|
987
|
+
* - Required columns: date, open, high, low, close
|
|
988
|
+
* - Optional columns: symbol (required for multi-symbol), volume, amount
|
|
989
|
+
* - Custom fields: any ASCII-named columns with numeric values (e.g., pe, market_cap, pb_ratio)
|
|
990
|
+
*
|
|
991
|
+
* @param params - Upload backtest parameters
|
|
992
|
+
* @returns Backtest results
|
|
993
|
+
*
|
|
994
|
+
* @example
|
|
995
|
+
* ```typescript
|
|
996
|
+
* // Upload from file input
|
|
997
|
+
* const fileInput = document.getElementById('file') as HTMLInputElement;
|
|
998
|
+
* const result = await client.quant.backtestUpload({
|
|
999
|
+
* file: fileInput.files[0],
|
|
1000
|
+
* entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))',
|
|
1001
|
+
* exitFormula: 'CROSS(MA(CLOSE, 10), MA(CLOSE, 5))',
|
|
1002
|
+
* initialCash: 100000,
|
|
1003
|
+
* commission: 0.0003
|
|
1004
|
+
* });
|
|
1005
|
+
*
|
|
1006
|
+
* console.log(`Total Return: ${(result.total_return_pct * 100).toFixed(2)}%`);
|
|
1007
|
+
*
|
|
1008
|
+
* // With custom strategy code
|
|
1009
|
+
* const result2 = await client.quant.backtestUpload({
|
|
1010
|
+
* file: fileInput.files[0],
|
|
1011
|
+
* signalFactors: { ma5: 'MA(CLOSE, 5)', ma20: 'MA(CLOSE, 20)' },
|
|
1012
|
+
* strategyCode: `
|
|
1013
|
+
* def handle_data(context, datas):
|
|
1014
|
+
* for data in datas:
|
|
1015
|
+
* symbol = data.name
|
|
1016
|
+
* if not context.portfolio.get_position(symbol):
|
|
1017
|
+
* if data.ma5 > data.ma20:
|
|
1018
|
+
* context.order_target_percent(symbol, 0.2)
|
|
1019
|
+
* elif data.ma5 < data.ma20:
|
|
1020
|
+
* context.order_target_percent(symbol, 0)
|
|
1021
|
+
* `
|
|
1022
|
+
* });
|
|
1023
|
+
* ```
|
|
1024
|
+
*/
|
|
1025
|
+
async backtestUpload(params) {
|
|
1026
|
+
const paramsJson = {
|
|
1027
|
+
initial_cash: params.initialCash ?? 1e5,
|
|
1028
|
+
commission: params.commission ?? 0,
|
|
1029
|
+
position_size: params.positionSize ?? 0.2,
|
|
1030
|
+
max_positions: params.maxPositions ?? 5,
|
|
1031
|
+
min_volume: params.minVolume ?? 100,
|
|
1032
|
+
auto_close: params.autoClose ?? true
|
|
1033
|
+
};
|
|
1034
|
+
if (params.entryFormula !== void 0) {
|
|
1035
|
+
paramsJson.entry_formula = params.entryFormula;
|
|
1036
|
+
}
|
|
1037
|
+
if (params.strategyCode !== void 0) {
|
|
1038
|
+
paramsJson.strategy_code = params.strategyCode;
|
|
1039
|
+
}
|
|
1040
|
+
if (params.exitFormula !== void 0) {
|
|
1041
|
+
paramsJson.exit_formula = params.exitFormula;
|
|
1042
|
+
}
|
|
1043
|
+
if (params.signalFactors !== void 0) {
|
|
1044
|
+
paramsJson.signal_factors = params.signalFactors;
|
|
1045
|
+
}
|
|
1046
|
+
const formData = new FormData();
|
|
1047
|
+
formData.append("file", params.file);
|
|
1048
|
+
formData.append("params", JSON.stringify(paramsJson));
|
|
1049
|
+
return this.client.request("POST", "/v1/quant/backtest/upload", { formData });
|
|
1050
|
+
}
|
|
1031
1051
|
};
|
|
1032
1052
|
|
|
1033
1053
|
// src/concepts.ts
|
|
@@ -2091,15 +2111,22 @@ var Reportify = class {
|
|
|
2091
2111
|
}
|
|
2092
2112
|
const controller = new AbortController();
|
|
2093
2113
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
2114
|
+
const headers = {
|
|
2115
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
2116
|
+
"User-Agent": "reportify-sdk-js/0.3.10"
|
|
2117
|
+
};
|
|
2118
|
+
let requestBody;
|
|
2119
|
+
if (options.formData) {
|
|
2120
|
+
requestBody = options.formData;
|
|
2121
|
+
} else {
|
|
2122
|
+
headers["Content-Type"] = "application/json";
|
|
2123
|
+
requestBody = options.body ? JSON.stringify(options.body) : void 0;
|
|
2124
|
+
}
|
|
2094
2125
|
try {
|
|
2095
2126
|
const response = await fetch(url.toString(), {
|
|
2096
2127
|
method,
|
|
2097
|
-
headers
|
|
2098
|
-
|
|
2099
|
-
"Content-Type": "application/json",
|
|
2100
|
-
"User-Agent": "reportify-sdk-js/0.3.10"
|
|
2101
|
-
},
|
|
2102
|
-
body: options.body ? JSON.stringify(options.body) : void 0,
|
|
2128
|
+
headers,
|
|
2129
|
+
body: requestBody,
|
|
2103
2130
|
signal: controller.signal
|
|
2104
2131
|
});
|
|
2105
2132
|
clearTimeout(timeoutId);
|
package/dist/index.mjs
CHANGED
|
@@ -575,80 +575,34 @@ var QuantModule = class {
|
|
|
575
575
|
this.client = client;
|
|
576
576
|
}
|
|
577
577
|
// ===========================================================================
|
|
578
|
-
//
|
|
578
|
+
// Factors (includes technical indicators and fundamental factors)
|
|
579
579
|
// ===========================================================================
|
|
580
580
|
/**
|
|
581
|
-
* Get list of available
|
|
581
|
+
* Get list of available factors (variables, functions, and indicators)
|
|
582
582
|
*
|
|
583
|
-
*
|
|
584
|
-
*
|
|
585
|
-
*
|
|
586
|
-
*
|
|
587
|
-
*
|
|
588
|
-
* ```typescript
|
|
589
|
-
* const indicators = await client.quant.indicators();
|
|
590
|
-
* indicators.forEach(ind => {
|
|
591
|
-
* console.log(`${ind.name}: ${ind.description}`);
|
|
592
|
-
* console.log(` Fields: ${ind.fields.join(', ')}`);
|
|
593
|
-
* });
|
|
594
|
-
* ```
|
|
595
|
-
*/
|
|
596
|
-
async indicators() {
|
|
597
|
-
return this.client.get("/v1/quant/indicators");
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* Compute indicator values for given symbols
|
|
583
|
+
* Returns factors organized by level:
|
|
584
|
+
* - Level 0 Variables: CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT (price data, no parentheses)
|
|
585
|
+
* - Level 0 Functions: MA(), EMA(), REF(), HHV(), LLV(), STD(), etc. (require parentheses)
|
|
586
|
+
* - Level 1 Functions: CROSS(), COUNT(), EVERY(), etc. (require parentheses)
|
|
587
|
+
* - Level 2 Functions: Technical indicators (MACD(), KDJ(), RSI(), BOLL(), etc.) and fundamental factors (PE(), ROE(), etc.)
|
|
601
588
|
*
|
|
602
589
|
* Variables vs Functions:
|
|
603
|
-
* - Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT
|
|
604
|
-
* - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20),
|
|
590
|
+
* - Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT
|
|
591
|
+
* - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20), PE(), ROE(), RSI(14), etc.
|
|
605
592
|
*
|
|
606
|
-
* @
|
|
607
|
-
* @returns Array of indicator data
|
|
593
|
+
* @returns Array of factor definitions with name, type, level, description, and optional fields
|
|
608
594
|
*
|
|
609
595
|
* @example
|
|
610
596
|
* ```typescript
|
|
611
|
-
*
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
* });
|
|
616
|
-
*
|
|
617
|
-
* // MACD indicator
|
|
618
|
-
* const data = await client.quant.indicatorsCompute({
|
|
619
|
-
* symbols: ['000001'],
|
|
620
|
-
* formula: 'MACD()'
|
|
621
|
-
* });
|
|
622
|
-
*
|
|
623
|
-
* // Standard deviation
|
|
624
|
-
* const data = await client.quant.indicatorsCompute({
|
|
625
|
-
* symbols: ['000001'],
|
|
626
|
-
* formula: 'STD(CLOSE, 20)'
|
|
597
|
+
* const factors = await client.quant.factors();
|
|
598
|
+
* factors.forEach(f => {
|
|
599
|
+
* console.log(`${f.name} (${f.type}, level ${f.level})`);
|
|
600
|
+
* if (f.fields) {
|
|
601
|
+
* console.log(` Fields: ${f.fields.join(', ')}`);
|
|
602
|
+
* }
|
|
627
603
|
* });
|
|
628
604
|
* ```
|
|
629
605
|
*/
|
|
630
|
-
async indicatorsCompute(params) {
|
|
631
|
-
const response = await this.client.post("/v1/quant/indicators/compute", {
|
|
632
|
-
symbols: params.symbols,
|
|
633
|
-
formula: params.formula,
|
|
634
|
-
market: params.market || "cn",
|
|
635
|
-
start_date: params.startDate,
|
|
636
|
-
end_date: params.endDate
|
|
637
|
-
});
|
|
638
|
-
return response.datas || [];
|
|
639
|
-
}
|
|
640
|
-
// ===========================================================================
|
|
641
|
-
// Factors
|
|
642
|
-
// ===========================================================================
|
|
643
|
-
/**
|
|
644
|
-
* Get list of available factors (variables and functions)
|
|
645
|
-
*
|
|
646
|
-
* Variables vs Functions:
|
|
647
|
-
* - Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT, PE_TTM, ROE_TTM, etc.
|
|
648
|
-
* - Functions (TongDaXin style: col first, n second): MA(CLOSE, 20), PE(), ROE(), RSI(14), etc.
|
|
649
|
-
*
|
|
650
|
-
* @returns Array of factor definitions organized by level
|
|
651
|
-
*/
|
|
652
606
|
async factors() {
|
|
653
607
|
return this.client.get("/v1/quant/factors");
|
|
654
608
|
}
|
|
@@ -666,25 +620,25 @@ var QuantModule = class {
|
|
|
666
620
|
*
|
|
667
621
|
* @example
|
|
668
622
|
* ```typescript
|
|
669
|
-
* //
|
|
623
|
+
* // Technical indicators (RSI, MACD, etc.)
|
|
670
624
|
* const data = await client.quant.factorsCompute({
|
|
671
625
|
* symbols: ['000001'],
|
|
672
626
|
* formula: 'RSI(14)'
|
|
673
627
|
* });
|
|
674
628
|
*
|
|
675
|
-
* // MACD
|
|
629
|
+
* // MACD indicator
|
|
676
630
|
* const data = await client.quant.factorsCompute({
|
|
677
631
|
* symbols: ['000001'],
|
|
678
632
|
* formula: 'MACD().dif'
|
|
679
633
|
* });
|
|
680
634
|
*
|
|
681
|
-
* //
|
|
635
|
+
* // Core functions
|
|
682
636
|
* const data = await client.quant.factorsCompute({
|
|
683
637
|
* symbols: ['000001'],
|
|
684
|
-
* formula: '
|
|
638
|
+
* formula: 'MA(CLOSE, 20)'
|
|
685
639
|
* });
|
|
686
640
|
*
|
|
687
|
-
* // Fundamental factors
|
|
641
|
+
* // Fundamental factors
|
|
688
642
|
* const data = await client.quant.factorsCompute({
|
|
689
643
|
* symbols: ['000001'],
|
|
690
644
|
* formula: 'PE()'
|
|
@@ -713,7 +667,7 @@ var QuantModule = class {
|
|
|
713
667
|
*
|
|
714
668
|
* @example
|
|
715
669
|
* ```typescript
|
|
716
|
-
* //
|
|
670
|
+
* // Technical screening
|
|
717
671
|
* const stocks = await client.quant.factorsScreen({
|
|
718
672
|
* formula: 'RSI(14) < 30'
|
|
719
673
|
* });
|
|
@@ -723,12 +677,7 @@ var QuantModule = class {
|
|
|
723
677
|
* formula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))'
|
|
724
678
|
* });
|
|
725
679
|
*
|
|
726
|
-
* //
|
|
727
|
-
* const stocks = await client.quant.factorsScreen({
|
|
728
|
-
* formula: '(CLOSE > MA(CLOSE, 20)) & (MA(CLOSE, 20) > MA(CLOSE, 60))'
|
|
729
|
-
* });
|
|
730
|
-
*
|
|
731
|
-
* // Fundamental screening (note: functions require parentheses)
|
|
680
|
+
* // Fundamental screening
|
|
732
681
|
* const stocks = await client.quant.factorsScreen({
|
|
733
682
|
* formula: '(PE() < 20) & (ROE() > 0.15)'
|
|
734
683
|
* });
|
|
@@ -937,7 +886,7 @@ var QuantModule = class {
|
|
|
937
886
|
* for data in datas:
|
|
938
887
|
* symbol = data.name
|
|
939
888
|
* if not context.portfolio.get_position(symbol):
|
|
940
|
-
* if data.pe < 20 and data.rsi < 30:
|
|
889
|
+
* if data.pe < 20 and data.rsi < 30: // Use pre-calculated factors
|
|
941
890
|
* context.order_target_percent(symbol, 0.2)
|
|
942
891
|
* elif data.rsi > 70:
|
|
943
892
|
* context.order_target_percent(symbol, 0)
|
|
@@ -984,6 +933,77 @@ var QuantModule = class {
|
|
|
984
933
|
}
|
|
985
934
|
return this.client.post("/v1/quant/backtest", body);
|
|
986
935
|
}
|
|
936
|
+
/**
|
|
937
|
+
* Upload an Excel file to run backtest
|
|
938
|
+
*
|
|
939
|
+
* Upload an Excel file (.xlsx/.xls) containing OHLCV data for backtesting.
|
|
940
|
+
* This allows you to use your own market data instead of the system's built-in data source.
|
|
941
|
+
*
|
|
942
|
+
* Excel file format requirements:
|
|
943
|
+
* - Required columns: date, open, high, low, close
|
|
944
|
+
* - Optional columns: symbol (required for multi-symbol), volume, amount
|
|
945
|
+
* - Custom fields: any ASCII-named columns with numeric values (e.g., pe, market_cap, pb_ratio)
|
|
946
|
+
*
|
|
947
|
+
* @param params - Upload backtest parameters
|
|
948
|
+
* @returns Backtest results
|
|
949
|
+
*
|
|
950
|
+
* @example
|
|
951
|
+
* ```typescript
|
|
952
|
+
* // Upload from file input
|
|
953
|
+
* const fileInput = document.getElementById('file') as HTMLInputElement;
|
|
954
|
+
* const result = await client.quant.backtestUpload({
|
|
955
|
+
* file: fileInput.files[0],
|
|
956
|
+
* entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))',
|
|
957
|
+
* exitFormula: 'CROSS(MA(CLOSE, 10), MA(CLOSE, 5))',
|
|
958
|
+
* initialCash: 100000,
|
|
959
|
+
* commission: 0.0003
|
|
960
|
+
* });
|
|
961
|
+
*
|
|
962
|
+
* console.log(`Total Return: ${(result.total_return_pct * 100).toFixed(2)}%`);
|
|
963
|
+
*
|
|
964
|
+
* // With custom strategy code
|
|
965
|
+
* const result2 = await client.quant.backtestUpload({
|
|
966
|
+
* file: fileInput.files[0],
|
|
967
|
+
* signalFactors: { ma5: 'MA(CLOSE, 5)', ma20: 'MA(CLOSE, 20)' },
|
|
968
|
+
* strategyCode: `
|
|
969
|
+
* def handle_data(context, datas):
|
|
970
|
+
* for data in datas:
|
|
971
|
+
* symbol = data.name
|
|
972
|
+
* if not context.portfolio.get_position(symbol):
|
|
973
|
+
* if data.ma5 > data.ma20:
|
|
974
|
+
* context.order_target_percent(symbol, 0.2)
|
|
975
|
+
* elif data.ma5 < data.ma20:
|
|
976
|
+
* context.order_target_percent(symbol, 0)
|
|
977
|
+
* `
|
|
978
|
+
* });
|
|
979
|
+
* ```
|
|
980
|
+
*/
|
|
981
|
+
async backtestUpload(params) {
|
|
982
|
+
const paramsJson = {
|
|
983
|
+
initial_cash: params.initialCash ?? 1e5,
|
|
984
|
+
commission: params.commission ?? 0,
|
|
985
|
+
position_size: params.positionSize ?? 0.2,
|
|
986
|
+
max_positions: params.maxPositions ?? 5,
|
|
987
|
+
min_volume: params.minVolume ?? 100,
|
|
988
|
+
auto_close: params.autoClose ?? true
|
|
989
|
+
};
|
|
990
|
+
if (params.entryFormula !== void 0) {
|
|
991
|
+
paramsJson.entry_formula = params.entryFormula;
|
|
992
|
+
}
|
|
993
|
+
if (params.strategyCode !== void 0) {
|
|
994
|
+
paramsJson.strategy_code = params.strategyCode;
|
|
995
|
+
}
|
|
996
|
+
if (params.exitFormula !== void 0) {
|
|
997
|
+
paramsJson.exit_formula = params.exitFormula;
|
|
998
|
+
}
|
|
999
|
+
if (params.signalFactors !== void 0) {
|
|
1000
|
+
paramsJson.signal_factors = params.signalFactors;
|
|
1001
|
+
}
|
|
1002
|
+
const formData = new FormData();
|
|
1003
|
+
formData.append("file", params.file);
|
|
1004
|
+
formData.append("params", JSON.stringify(paramsJson));
|
|
1005
|
+
return this.client.request("POST", "/v1/quant/backtest/upload", { formData });
|
|
1006
|
+
}
|
|
987
1007
|
};
|
|
988
1008
|
|
|
989
1009
|
// src/concepts.ts
|
|
@@ -2047,15 +2067,22 @@ var Reportify = class {
|
|
|
2047
2067
|
}
|
|
2048
2068
|
const controller = new AbortController();
|
|
2049
2069
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
2070
|
+
const headers = {
|
|
2071
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
2072
|
+
"User-Agent": "reportify-sdk-js/0.3.10"
|
|
2073
|
+
};
|
|
2074
|
+
let requestBody;
|
|
2075
|
+
if (options.formData) {
|
|
2076
|
+
requestBody = options.formData;
|
|
2077
|
+
} else {
|
|
2078
|
+
headers["Content-Type"] = "application/json";
|
|
2079
|
+
requestBody = options.body ? JSON.stringify(options.body) : void 0;
|
|
2080
|
+
}
|
|
2050
2081
|
try {
|
|
2051
2082
|
const response = await fetch(url.toString(), {
|
|
2052
2083
|
method,
|
|
2053
|
-
headers
|
|
2054
|
-
|
|
2055
|
-
"Content-Type": "application/json",
|
|
2056
|
-
"User-Agent": "reportify-sdk-js/0.3.10"
|
|
2057
|
-
},
|
|
2058
|
-
body: options.body ? JSON.stringify(options.body) : void 0,
|
|
2084
|
+
headers,
|
|
2085
|
+
body: requestBody,
|
|
2059
2086
|
signal: controller.signal
|
|
2060
2087
|
});
|
|
2061
2088
|
clearTimeout(timeoutId);
|