|
|
@@ -88,9 +88,11 @@ class CandleController {
|
|
88
|
88
|
});
|
|
89
|
89
|
|
|
90
|
90
|
if (!candle) {
|
|
91
|
|
- const error = new Error('No candle data found for this symbol');
|
|
92
|
|
- error.statusCode = 404;
|
|
93
|
|
- return next(error);
|
|
|
91
|
+ return res.json({
|
|
|
92
|
+ success: true,
|
|
|
93
|
+ data: null,
|
|
|
94
|
+ message: 'No candle data found for this symbol'
|
|
|
95
|
+ });
|
|
94
|
96
|
}
|
|
95
|
97
|
|
|
96
|
98
|
res.json({
|
|
|
@@ -165,7 +167,12 @@ class CandleController {
|
|
165
|
167
|
}
|
|
166
|
168
|
|
|
167
|
169
|
// Verify all symbols exist
|
|
168
|
|
- const symbolIds = [...new Set(candles.map(c => c.symbolId))];
|
|
|
170
|
+ const processedCandles = candles.map(candle => ({
|
|
|
171
|
+ ...candle,
|
|
|
172
|
+ symbolId: parseInt(candle.symbolId)
|
|
|
173
|
+ }));
|
|
|
174
|
+
|
|
|
175
|
+ const symbolIds = [...new Set(processedCandles.map(c => c.symbolId))];
|
|
169
|
176
|
const existingSymbols = await Symbol.findAll({
|
|
170
|
177
|
where: { id: symbolIds },
|
|
171
|
178
|
attributes: ['id']
|
|
|
@@ -180,7 +187,35 @@ class CandleController {
|
|
180
|
187
|
return next(error);
|
|
181
|
188
|
}
|
|
182
|
189
|
|
|
183
|
|
- const createdCandles = await Candle1h.bulkCreate(candles);
|
|
|
190
|
+ // Check for existing candles to identify duplicates
|
|
|
191
|
+ const existingCandles = await Candle1h.findAll({
|
|
|
192
|
+ where: {
|
|
|
193
|
+ [Op.or]: processedCandles.map(candle => ({
|
|
|
194
|
+ symbolId: candle.symbolId,
|
|
|
195
|
+ openTime: candle.openTime
|
|
|
196
|
+ }))
|
|
|
197
|
+ },
|
|
|
198
|
+ attributes: ['symbolId', 'openTime']
|
|
|
199
|
+ });
|
|
|
200
|
+
|
|
|
201
|
+ // Create a set of existing keys for quick lookup
|
|
|
202
|
+ const existingKeys = new Set(
|
|
|
203
|
+ existingCandles.map(c => `${c.symbolId}-${c.openTime.toISOString()}`)
|
|
|
204
|
+ );
|
|
|
205
|
+
|
|
|
206
|
+ // Filter out duplicates
|
|
|
207
|
+ const newCandles = processedCandles.filter(candle =>
|
|
|
208
|
+ !existingKeys.has(`${candle.symbolId}-${candle.openTime.toISOString()}`)
|
|
|
209
|
+ );
|
|
|
210
|
+
|
|
|
211
|
+ const duplicateCount = processedCandles.length - newCandles.length;
|
|
|
212
|
+
|
|
|
213
|
+ // Log duplicates if any
|
|
|
214
|
+ if (duplicateCount > 0) {
|
|
|
215
|
+ console.log(`Bulk create candles: ${duplicateCount} duplicates skipped`);
|
|
|
216
|
+ }
|
|
|
217
|
+
|
|
|
218
|
+ const createdCandles = await Candle1h.bulkCreate(newCandles);
|
|
184
|
219
|
|
|
185
|
220
|
// Emit WebSocket events for real-time updates
|
|
186
|
221
|
const io = req.app.get('io');
|
|
|
@@ -226,7 +261,7 @@ class CandleController {
|
|
226
|
261
|
res.status(201).json({
|
|
227
|
262
|
success: true,
|
|
228
|
263
|
data: createdCandles,
|
|
229
|
|
- message: `${createdCandles.length} candles created successfully`
|
|
|
264
|
+ message: `${createdCandles.length} candles created successfully${duplicateCount > 0 ? `, ${duplicateCount} duplicates skipped` : ''}`
|
|
230
|
265
|
});
|
|
231
|
266
|
} catch (error) {
|
|
232
|
267
|
next(error);
|