cyberhybridhub/server/test/trading/rule_engine_guess_weekly_move_test.dart
2026-05-31 11:17:12 -05:00

98 lines
2.9 KiB
Dart

import 'package:cyberhybridhub_server/trading/market_history_query.dart';
import 'package:cyberhybridhub_server/trading/rule_engine.dart';
import 'package:cyberhybridhub_server/trading/trading_config.dart';
import 'package:test/test.dart';
void main() {
late TradingRuleConfig guessRule;
late DateTime now;
setUp(() {
guessRule = TradingRuleConfig.fromJson(<String, dynamic>{
'id': 'guess_weekly_move',
'type': 'guess_weekly_move',
'symbol': '*',
'question_template':
'{{token}} was {{ref_price}} {{ref_days_ago}} days ago. +10 up, -10 down.',
});
now = DateTime.utc(2026, 5, 26, 12);
});
WeeklyMover mover({
required num openClose,
required num currentClose,
int days = 5,
}) {
return WeeklyMover(
symbol: 'SPY',
openClose: openClose,
currentClose: currentClose,
days: days,
);
}
group('RuleEngine.evaluateGuessWeeklyMove', () {
test('up move produces ASSET_A token and correct_answer 10', () {
final RuleEngine engine = RuleEngine();
final RuleEvaluation result = engine.evaluateGuessWeeklyMove(
rule: guessRule,
mover: mover(openClose: 500, currentClose: 510),
symbolToken: 'ASSET_A',
now: now,
);
expect(result.fired, isTrue);
expect(result.symbolToken, 'ASSET_A');
expect(result.guessSymbol, 'SPY');
expect(result.correctAnswer, 10);
expect(result.refPrice, 500);
expect(result.observedPrice, 510);
expect(result.refDaysAgo, 5);
expect(
result.questionText,
'ASSET_A was 500.00 5 days ago. +10 up, -10 down.',
);
expect(result.questionText, isNot(contains('SPY')));
expect(result.questionText, isNot(contains('{{symbol}}')));
});
test('down move produces correct_answer -10', () {
final RuleEngine engine = RuleEngine();
final RuleEvaluation result = engine.evaluateGuessWeeklyMove(
rule: guessRule,
mover: mover(openClose: 510, currentClose: 500),
symbolToken: 'ASSET_A',
now: now,
);
expect(result.fired, isTrue);
expect(result.correctAnswer, -10);
});
test('insufficient bars (no mover) does not fire', () {
final RuleEngine engine = RuleEngine();
final RuleEvaluation result = engine.evaluateGuessWeeklyMove(
rule: guessRule,
mover: null,
symbolToken: null,
now: now,
);
expect(result.fired, isFalse);
expect(result.skipReason, RuleSkipReason.insufficientBars);
});
test('guessSymbol is exposed for pipeline metadata', () {
final RuleEngine engine = RuleEngine();
final RuleEvaluation result = engine.evaluateGuessWeeklyMove(
rule: guessRule,
mover: mover(openClose: 500, currentClose: 510),
symbolToken: 'ASSET_A',
now: now,
);
expect(result.guessSymbol, 'SPY');
});
});
}