reportify-sdk 0.3.27 → 0.3.29
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 +63 -1
- package/dist/index.d.ts +63 -1
- package/dist/index.js +87 -6
- package/dist/index.mjs +87 -6
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -762,6 +762,21 @@ interface BatchMinuteParams {
|
|
|
762
762
|
endDateTime: string;
|
|
763
763
|
market?: StockMarket;
|
|
764
764
|
}
|
|
765
|
+
interface BacktestUploadParams {
|
|
766
|
+
file: File;
|
|
767
|
+
startDate?: string;
|
|
768
|
+
endDate?: string;
|
|
769
|
+
entryFormula?: string;
|
|
770
|
+
strategyCode?: string;
|
|
771
|
+
exitFormula?: string;
|
|
772
|
+
initialCash?: number;
|
|
773
|
+
commission?: number;
|
|
774
|
+
positionSize?: number;
|
|
775
|
+
maxPositions?: number;
|
|
776
|
+
minVolume?: number;
|
|
777
|
+
autoClose?: boolean;
|
|
778
|
+
signalFactors?: Record<string, string>;
|
|
779
|
+
}
|
|
765
780
|
interface BacktestResult {
|
|
766
781
|
success: boolean;
|
|
767
782
|
initial_cash: number;
|
|
@@ -1072,6 +1087,52 @@ declare class QuantModule {
|
|
|
1072
1087
|
* ```
|
|
1073
1088
|
*/
|
|
1074
1089
|
backtest(params: BacktestParams): Promise<BacktestResult>;
|
|
1090
|
+
/**
|
|
1091
|
+
* Upload an Excel file to run backtest
|
|
1092
|
+
*
|
|
1093
|
+
* Upload an Excel file (.xlsx/.xls) containing OHLCV data for backtesting.
|
|
1094
|
+
* This allows you to use your own market data instead of the system's built-in data source.
|
|
1095
|
+
*
|
|
1096
|
+
* Excel file format requirements:
|
|
1097
|
+
* - Required columns: date, open, high, low, close
|
|
1098
|
+
* - Optional columns: symbol (required for multi-symbol), volume, amount
|
|
1099
|
+
* - Custom fields: any ASCII-named columns with numeric values (e.g., pe, market_cap, pb_ratio)
|
|
1100
|
+
*
|
|
1101
|
+
* @param params - Upload backtest parameters
|
|
1102
|
+
* @returns Backtest results
|
|
1103
|
+
*
|
|
1104
|
+
* @example
|
|
1105
|
+
* ```typescript
|
|
1106
|
+
* // Upload from file input
|
|
1107
|
+
* const fileInput = document.getElementById('file') as HTMLInputElement;
|
|
1108
|
+
* const result = await client.quant.backtestUpload({
|
|
1109
|
+
* file: fileInput.files[0],
|
|
1110
|
+
* entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))',
|
|
1111
|
+
* exitFormula: 'CROSS(MA(CLOSE, 10), MA(CLOSE, 5))',
|
|
1112
|
+
* initialCash: 100000,
|
|
1113
|
+
* commission: 0.0003
|
|
1114
|
+
* });
|
|
1115
|
+
*
|
|
1116
|
+
* console.log(`Total Return: ${(result.total_return_pct * 100).toFixed(2)}%`);
|
|
1117
|
+
*
|
|
1118
|
+
* // With custom strategy code
|
|
1119
|
+
* const result2 = await client.quant.backtestUpload({
|
|
1120
|
+
* file: fileInput.files[0],
|
|
1121
|
+
* signalFactors: { ma5: 'MA(CLOSE, 5)', ma20: 'MA(CLOSE, 20)' },
|
|
1122
|
+
* strategyCode: `
|
|
1123
|
+
* def handle_data(context, datas):
|
|
1124
|
+
* for data in datas:
|
|
1125
|
+
* symbol = data.name
|
|
1126
|
+
* if not context.portfolio.get_position(symbol):
|
|
1127
|
+
* if data.ma5 > data.ma20:
|
|
1128
|
+
* context.order_target_percent(symbol, 0.2)
|
|
1129
|
+
* elif data.ma5 < data.ma20:
|
|
1130
|
+
* context.order_target_percent(symbol, 0)
|
|
1131
|
+
* `
|
|
1132
|
+
* });
|
|
1133
|
+
* ```
|
|
1134
|
+
*/
|
|
1135
|
+
backtestUpload(params: BacktestUploadParams): Promise<BacktestResult>;
|
|
1075
1136
|
}
|
|
1076
1137
|
|
|
1077
1138
|
/**
|
|
@@ -1894,6 +1955,7 @@ declare class Reportify {
|
|
|
1894
1955
|
request<T = unknown>(method: string, path: string, options?: {
|
|
1895
1956
|
params?: Record<string, unknown>;
|
|
1896
1957
|
body?: Record<string, unknown>;
|
|
1958
|
+
formData?: FormData;
|
|
1897
1959
|
}): Promise<T>;
|
|
1898
1960
|
/**
|
|
1899
1961
|
* Make a GET request
|
|
@@ -1917,4 +1979,4 @@ declare class Reportify {
|
|
|
1917
1979
|
getBytes(path: string): Promise<ArrayBuffer>;
|
|
1918
1980
|
}
|
|
1919
1981
|
|
|
1920
|
-
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 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 };
|
|
1982
|
+
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
|
@@ -762,6 +762,21 @@ interface BatchMinuteParams {
|
|
|
762
762
|
endDateTime: string;
|
|
763
763
|
market?: StockMarket;
|
|
764
764
|
}
|
|
765
|
+
interface BacktestUploadParams {
|
|
766
|
+
file: File;
|
|
767
|
+
startDate?: string;
|
|
768
|
+
endDate?: string;
|
|
769
|
+
entryFormula?: string;
|
|
770
|
+
strategyCode?: string;
|
|
771
|
+
exitFormula?: string;
|
|
772
|
+
initialCash?: number;
|
|
773
|
+
commission?: number;
|
|
774
|
+
positionSize?: number;
|
|
775
|
+
maxPositions?: number;
|
|
776
|
+
minVolume?: number;
|
|
777
|
+
autoClose?: boolean;
|
|
778
|
+
signalFactors?: Record<string, string>;
|
|
779
|
+
}
|
|
765
780
|
interface BacktestResult {
|
|
766
781
|
success: boolean;
|
|
767
782
|
initial_cash: number;
|
|
@@ -1072,6 +1087,52 @@ declare class QuantModule {
|
|
|
1072
1087
|
* ```
|
|
1073
1088
|
*/
|
|
1074
1089
|
backtest(params: BacktestParams): Promise<BacktestResult>;
|
|
1090
|
+
/**
|
|
1091
|
+
* Upload an Excel file to run backtest
|
|
1092
|
+
*
|
|
1093
|
+
* Upload an Excel file (.xlsx/.xls) containing OHLCV data for backtesting.
|
|
1094
|
+
* This allows you to use your own market data instead of the system's built-in data source.
|
|
1095
|
+
*
|
|
1096
|
+
* Excel file format requirements:
|
|
1097
|
+
* - Required columns: date, open, high, low, close
|
|
1098
|
+
* - Optional columns: symbol (required for multi-symbol), volume, amount
|
|
1099
|
+
* - Custom fields: any ASCII-named columns with numeric values (e.g., pe, market_cap, pb_ratio)
|
|
1100
|
+
*
|
|
1101
|
+
* @param params - Upload backtest parameters
|
|
1102
|
+
* @returns Backtest results
|
|
1103
|
+
*
|
|
1104
|
+
* @example
|
|
1105
|
+
* ```typescript
|
|
1106
|
+
* // Upload from file input
|
|
1107
|
+
* const fileInput = document.getElementById('file') as HTMLInputElement;
|
|
1108
|
+
* const result = await client.quant.backtestUpload({
|
|
1109
|
+
* file: fileInput.files[0],
|
|
1110
|
+
* entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))',
|
|
1111
|
+
* exitFormula: 'CROSS(MA(CLOSE, 10), MA(CLOSE, 5))',
|
|
1112
|
+
* initialCash: 100000,
|
|
1113
|
+
* commission: 0.0003
|
|
1114
|
+
* });
|
|
1115
|
+
*
|
|
1116
|
+
* console.log(`Total Return: ${(result.total_return_pct * 100).toFixed(2)}%`);
|
|
1117
|
+
*
|
|
1118
|
+
* // With custom strategy code
|
|
1119
|
+
* const result2 = await client.quant.backtestUpload({
|
|
1120
|
+
* file: fileInput.files[0],
|
|
1121
|
+
* signalFactors: { ma5: 'MA(CLOSE, 5)', ma20: 'MA(CLOSE, 20)' },
|
|
1122
|
+
* strategyCode: `
|
|
1123
|
+
* def handle_data(context, datas):
|
|
1124
|
+
* for data in datas:
|
|
1125
|
+
* symbol = data.name
|
|
1126
|
+
* if not context.portfolio.get_position(symbol):
|
|
1127
|
+
* if data.ma5 > data.ma20:
|
|
1128
|
+
* context.order_target_percent(symbol, 0.2)
|
|
1129
|
+
* elif data.ma5 < data.ma20:
|
|
1130
|
+
* context.order_target_percent(symbol, 0)
|
|
1131
|
+
* `
|
|
1132
|
+
* });
|
|
1133
|
+
* ```
|
|
1134
|
+
*/
|
|
1135
|
+
backtestUpload(params: BacktestUploadParams): Promise<BacktestResult>;
|
|
1075
1136
|
}
|
|
1076
1137
|
|
|
1077
1138
|
/**
|
|
@@ -1894,6 +1955,7 @@ declare class Reportify {
|
|
|
1894
1955
|
request<T = unknown>(method: string, path: string, options?: {
|
|
1895
1956
|
params?: Record<string, unknown>;
|
|
1896
1957
|
body?: Record<string, unknown>;
|
|
1958
|
+
formData?: FormData;
|
|
1897
1959
|
}): Promise<T>;
|
|
1898
1960
|
/**
|
|
1899
1961
|
* Make a GET request
|
|
@@ -1917,4 +1979,4 @@ declare class Reportify {
|
|
|
1917
1979
|
getBytes(path: string): Promise<ArrayBuffer>;
|
|
1918
1980
|
}
|
|
1919
1981
|
|
|
1920
|
-
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 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 };
|
|
1982
|
+
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
|
@@ -977,6 +977,80 @@ var QuantModule = class {
|
|
|
977
977
|
}
|
|
978
978
|
return this.client.post("/v1/quant/backtest", body);
|
|
979
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 formData = new FormData();
|
|
1027
|
+
formData.append("file", params.file);
|
|
1028
|
+
formData.append("initial_cash", String(params.initialCash ?? 1e5));
|
|
1029
|
+
formData.append("commission", String(params.commission ?? 0));
|
|
1030
|
+
formData.append("position_size", String(params.positionSize ?? 0.2));
|
|
1031
|
+
formData.append("max_positions", String(params.maxPositions ?? 5));
|
|
1032
|
+
formData.append("min_volume", String(params.minVolume ?? 100));
|
|
1033
|
+
formData.append("auto_close", String(params.autoClose ?? true));
|
|
1034
|
+
if (params.startDate !== void 0) {
|
|
1035
|
+
formData.append("start_date", params.startDate);
|
|
1036
|
+
}
|
|
1037
|
+
if (params.endDate !== void 0) {
|
|
1038
|
+
formData.append("end_date", params.endDate);
|
|
1039
|
+
}
|
|
1040
|
+
if (params.entryFormula !== void 0) {
|
|
1041
|
+
formData.append("entry_formula", params.entryFormula);
|
|
1042
|
+
}
|
|
1043
|
+
if (params.strategyCode !== void 0) {
|
|
1044
|
+
formData.append("strategy_code", params.strategyCode);
|
|
1045
|
+
}
|
|
1046
|
+
if (params.exitFormula !== void 0) {
|
|
1047
|
+
formData.append("exit_formula", params.exitFormula);
|
|
1048
|
+
}
|
|
1049
|
+
if (params.signalFactors !== void 0) {
|
|
1050
|
+
formData.append("signal_factors", JSON.stringify(params.signalFactors));
|
|
1051
|
+
}
|
|
1052
|
+
return this.client.request("POST", "/v1/quant/backtest/upload", { formData });
|
|
1053
|
+
}
|
|
980
1054
|
};
|
|
981
1055
|
|
|
982
1056
|
// src/concepts.ts
|
|
@@ -2040,15 +2114,22 @@ var Reportify = class {
|
|
|
2040
2114
|
}
|
|
2041
2115
|
const controller = new AbortController();
|
|
2042
2116
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
2117
|
+
const headers = {
|
|
2118
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
2119
|
+
"User-Agent": "reportify-sdk-js/0.3.10"
|
|
2120
|
+
};
|
|
2121
|
+
let requestBody;
|
|
2122
|
+
if (options.formData) {
|
|
2123
|
+
requestBody = options.formData;
|
|
2124
|
+
} else {
|
|
2125
|
+
headers["Content-Type"] = "application/json";
|
|
2126
|
+
requestBody = options.body ? JSON.stringify(options.body) : void 0;
|
|
2127
|
+
}
|
|
2043
2128
|
try {
|
|
2044
2129
|
const response = await fetch(url.toString(), {
|
|
2045
2130
|
method,
|
|
2046
|
-
headers
|
|
2047
|
-
|
|
2048
|
-
"Content-Type": "application/json",
|
|
2049
|
-
"User-Agent": "reportify-sdk-js/0.3.10"
|
|
2050
|
-
},
|
|
2051
|
-
body: options.body ? JSON.stringify(options.body) : void 0,
|
|
2131
|
+
headers,
|
|
2132
|
+
body: requestBody,
|
|
2052
2133
|
signal: controller.signal
|
|
2053
2134
|
});
|
|
2054
2135
|
clearTimeout(timeoutId);
|
package/dist/index.mjs
CHANGED
|
@@ -933,6 +933,80 @@ var QuantModule = class {
|
|
|
933
933
|
}
|
|
934
934
|
return this.client.post("/v1/quant/backtest", body);
|
|
935
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 formData = new FormData();
|
|
983
|
+
formData.append("file", params.file);
|
|
984
|
+
formData.append("initial_cash", String(params.initialCash ?? 1e5));
|
|
985
|
+
formData.append("commission", String(params.commission ?? 0));
|
|
986
|
+
formData.append("position_size", String(params.positionSize ?? 0.2));
|
|
987
|
+
formData.append("max_positions", String(params.maxPositions ?? 5));
|
|
988
|
+
formData.append("min_volume", String(params.minVolume ?? 100));
|
|
989
|
+
formData.append("auto_close", String(params.autoClose ?? true));
|
|
990
|
+
if (params.startDate !== void 0) {
|
|
991
|
+
formData.append("start_date", params.startDate);
|
|
992
|
+
}
|
|
993
|
+
if (params.endDate !== void 0) {
|
|
994
|
+
formData.append("end_date", params.endDate);
|
|
995
|
+
}
|
|
996
|
+
if (params.entryFormula !== void 0) {
|
|
997
|
+
formData.append("entry_formula", params.entryFormula);
|
|
998
|
+
}
|
|
999
|
+
if (params.strategyCode !== void 0) {
|
|
1000
|
+
formData.append("strategy_code", params.strategyCode);
|
|
1001
|
+
}
|
|
1002
|
+
if (params.exitFormula !== void 0) {
|
|
1003
|
+
formData.append("exit_formula", params.exitFormula);
|
|
1004
|
+
}
|
|
1005
|
+
if (params.signalFactors !== void 0) {
|
|
1006
|
+
formData.append("signal_factors", JSON.stringify(params.signalFactors));
|
|
1007
|
+
}
|
|
1008
|
+
return this.client.request("POST", "/v1/quant/backtest/upload", { formData });
|
|
1009
|
+
}
|
|
936
1010
|
};
|
|
937
1011
|
|
|
938
1012
|
// src/concepts.ts
|
|
@@ -1996,15 +2070,22 @@ var Reportify = class {
|
|
|
1996
2070
|
}
|
|
1997
2071
|
const controller = new AbortController();
|
|
1998
2072
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
2073
|
+
const headers = {
|
|
2074
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
2075
|
+
"User-Agent": "reportify-sdk-js/0.3.10"
|
|
2076
|
+
};
|
|
2077
|
+
let requestBody;
|
|
2078
|
+
if (options.formData) {
|
|
2079
|
+
requestBody = options.formData;
|
|
2080
|
+
} else {
|
|
2081
|
+
headers["Content-Type"] = "application/json";
|
|
2082
|
+
requestBody = options.body ? JSON.stringify(options.body) : void 0;
|
|
2083
|
+
}
|
|
1999
2084
|
try {
|
|
2000
2085
|
const response = await fetch(url.toString(), {
|
|
2001
2086
|
method,
|
|
2002
|
-
headers
|
|
2003
|
-
|
|
2004
|
-
"Content-Type": "application/json",
|
|
2005
|
-
"User-Agent": "reportify-sdk-js/0.3.10"
|
|
2006
|
-
},
|
|
2007
|
-
body: options.body ? JSON.stringify(options.body) : void 0,
|
|
2087
|
+
headers,
|
|
2088
|
+
body: requestBody,
|
|
2008
2089
|
signal: controller.signal
|
|
2009
2090
|
});
|
|
2010
2091
|
clearTimeout(timeoutId);
|