78 lines
2.4 KiB
Dart
78 lines
2.4 KiB
Dart
@Tags(['alpaca'])
|
|
library;
|
|
|
|
import 'package:cyberhybridhub_server/alpaca/alpaca_env.dart';
|
|
import 'package:cyberhybridhub_server/alpaca/alpaca_models.dart';
|
|
import 'package:cyberhybridhub_server/alpaca/alpaca_trading_client.dart';
|
|
import 'package:dotenv/dotenv.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
void main() {
|
|
late AlpacaEnv env;
|
|
AlpacaTradingClient? client;
|
|
|
|
setUpAll(() {
|
|
final DotEnv dotenv = DotEnv(includePlatformEnvironment: true)
|
|
..load(['.env']);
|
|
const List<String> alpacaKeys = <String>[
|
|
'ALPACA_API_KEY_ID',
|
|
'ALPACA_API_SECRET_KEY',
|
|
'ALPACA_TRADING_BASE_URL',
|
|
'ALPACA_DATA_BASE_URL',
|
|
'ALPACA_DATA_FEED',
|
|
'ALPACA_ALLOW_LIVE',
|
|
];
|
|
final Map<String, String> envMap = <String, String>{
|
|
for (final String key in alpacaKeys)
|
|
if (dotenv[key] != null && dotenv[key]!.isNotEmpty) key: dotenv[key]!,
|
|
};
|
|
env = AlpacaEnv.fromMap(envMap);
|
|
if (env.hasCredentials) {
|
|
client = AlpacaTradingClient(env: env);
|
|
}
|
|
});
|
|
|
|
tearDownAll(() {
|
|
client?.close();
|
|
});
|
|
|
|
test('paper submitOrder + getOrderByClientOrderId roundtrip', () async {
|
|
if (!env.hasCredentials) {
|
|
markTestSkipped(
|
|
'Set ALPACA_API_KEY_ID and ALPACA_API_SECRET_KEY in server/.env',
|
|
);
|
|
return;
|
|
}
|
|
// Refuse only on the *exact* live host. Substring matching breaks for
|
|
// paper-api.alpaca.markets (which includes "api.alpaca.markets").
|
|
final Uri tradingUri = Uri.parse(env.tradingBaseUrl);
|
|
if (tradingUri.host == AlpacaEnv.liveTradingHost && !env.allowLive) {
|
|
markTestSkipped(
|
|
'Refusing to run live test on live trading host '
|
|
'(${tradingUri.host}) without ALPACA_ALLOW_LIVE=true',
|
|
);
|
|
return;
|
|
}
|
|
|
|
final String clientOrderId =
|
|
'live-test-${DateTime.now().toUtc().millisecondsSinceEpoch}';
|
|
final AlpacaOrderResponse submitted = await client!.submitOrder(
|
|
AlpacaOrderRequest(
|
|
symbol: 'SPY',
|
|
side: 'buy',
|
|
type: 'market',
|
|
timeInForce: 'day',
|
|
clientOrderId: clientOrderId,
|
|
notional: 1,
|
|
),
|
|
);
|
|
expect(submitted.id, isNotEmpty);
|
|
expect(submitted.clientOrderId, clientOrderId);
|
|
|
|
final AlpacaOrderResponse? fetched =
|
|
await client!.getOrderByClientOrderId(clientOrderId);
|
|
expect(fetched, isNotNull);
|
|
expect(fetched!.id, submitted.id);
|
|
}, timeout: const Timeout(Duration(seconds: 30)));
|
|
}
|