Add isLiveTrading helper to fix bug

This commit is contained in:
2025-12-04 23:42:09 +07:00
parent b44e1f66a7
commit 78edd850fe
8 changed files with 123 additions and 106 deletions

View File

@@ -14,6 +14,7 @@ using Managing.Domain.Bots;
using Managing.Domain.Indicators; using Managing.Domain.Indicators;
using Managing.Domain.MoneyManagements; using Managing.Domain.MoneyManagements;
using Managing.Domain.Scenarios; using Managing.Domain.Scenarios;
using Managing.Domain.Shared.Helpers;
using Managing.Domain.Strategies; using Managing.Domain.Strategies;
using Managing.Domain.Trades; using Managing.Domain.Trades;
using Managing.Domain.Users; using Managing.Domain.Users;
@@ -955,13 +956,6 @@ public class BotController : BaseController
} }
} }
var tradingType = request.Config.TradingType switch
{
TradingType.BacktestFutures => TradingType.Futures,
TradingType.BacktestSpot => TradingType.Spot,
_ => TradingType.Futures
};
// Map the request to the full TradingBotConfig // Map the request to the full TradingBotConfig
var config = new TradingBotConfig var config = new TradingBotConfig
{ {
@@ -985,7 +979,7 @@ public class BotController : BaseController
// Set computed/default properties // Set computed/default properties
FlipPosition = request.Config.FlipPosition, FlipPosition = request.Config.FlipPosition,
Name = request.Config.Name, Name = request.Config.Name,
TradingType = tradingType TradingType = TradingBox.GetLiveTradingType(request.Config.TradingType)
}; };
return (config, user); return (config, user);

View File

@@ -13,8 +13,8 @@ public interface ICandleStoreGrain : IGrainWithStringKey
/// <summary> /// <summary>
/// Gets the current list of historical candles (up to 500 most recent) /// Gets the current list of historical candles (up to 500 most recent)
/// </summary> /// </summary>
/// <returns>List of candles ordered by date</returns> /// <returns>Read-only list of candles ordered by date</returns>
Task<HashSet<Candle>> GetCandlesAsync(); Task<IReadOnlyList<Candle>> GetCandlesAsync();
/// <summary> /// <summary>
/// Gets the X latest candles from the store /// Gets the X latest candles from the store
/// </summary> /// </summary>

View File

@@ -68,7 +68,7 @@ public abstract class TradingBotBase : ITradingBot
public virtual async Task Start(BotStatus previousStatus) public virtual async Task Start(BotStatus previousStatus)
{ {
if (Config.TradingType == TradingType.Futures) if (TradingBox.IsLiveTrading(Config.TradingType))
{ {
// Start async initialization in the background without blocking // Start async initialization in the background without blocking
try try
@@ -111,8 +111,8 @@ public abstract class TradingBotBase : ITradingBot
case BotStatus.Stopped: case BotStatus.Stopped:
// If status was Stopped we log a message to inform the user that the bot is restarting // If status was Stopped we log a message to inform the user that the bot is restarting
await LogInformationAsync($"🔄 Bot Restarted\n" + await LogInformationAsync($"🔄 Bot Restarted\n" +
$"📊 Resuming operations with {Signals.Count} signals and {Positions.Count} positions\n" + $"📊 Resuming operations with {Signals.Count} signals and {Positions.Count} positions\n" +
$"✅ Ready to continue trading"); $"✅ Ready to continue trading");
break; break;
default: default:
@@ -235,7 +235,7 @@ public abstract class TradingBotBase : ITradingBot
await ManagePositions(); await ManagePositions();
UpdateWalletBalances(); UpdateWalletBalances();
if (Config.TradingType == TradingType.Futures) if (TradingBox.IsLiveTrading(Config.TradingType))
{ {
ExecutionCount++; ExecutionCount++;
@@ -436,7 +436,9 @@ public abstract class TradingBotBase : ITradingBot
protected void UpdateWalletBalances() protected void UpdateWalletBalances()
{ {
var date = Config.TradingType == TradingType.BacktestFutures ? LastCandle?.Date ?? DateTime.UtcNow : DateTime.UtcNow; var date = Config.TradingType == TradingType.BacktestFutures
? LastCandle?.Date ?? DateTime.UtcNow
: DateTime.UtcNow;
if (WalletBalances.Count == 0) if (WalletBalances.Count == 0)
{ {
@@ -474,7 +476,7 @@ public abstract class TradingBotBase : ITradingBot
// Common position status handling // Common position status handling
if (internalPosition.Status == PositionStatus.Finished || if (internalPosition.Status == PositionStatus.Finished ||
internalPosition.Status == PositionStatus.Flipped) internalPosition.Status == PositionStatus.Flipped)
{ {
await HandleClosedPosition(positionForSignal); await HandleClosedPosition(positionForSignal);
} }
@@ -636,7 +638,7 @@ public abstract class TradingBotBase : ITradingBot
} }
// Synth risk monitoring (only for live trading) // Synth risk monitoring (only for live trading)
if (Config.UseSynthApi && Config.TradingType == TradingType.Futures && if (Config.UseSynthApi && TradingBox.IsLiveTrading(Config.TradingType) &&
positionForSignal.Status == PositionStatus.Filled) positionForSignal.Status == PositionStatus.Filled)
{ {
await MonitorSynthRisk(signal, positionForSignal); await MonitorSynthRisk(signal, positionForSignal);
@@ -644,19 +646,22 @@ public abstract class TradingBotBase : ITradingBot
} }
catch (Exception ex) catch (Exception ex)
{ {
await LogWarningAsync($"Cannot update position {positionForSignal.Identifier}: {ex.Message}, {ex.StackTrace}"); await LogWarningAsync(
$"Cannot update position {positionForSignal.Identifier}: {ex.Message}, {ex.StackTrace}");
SentrySdk.CaptureException(ex); SentrySdk.CaptureException(ex);
return; return;
} }
} }
// Virtual methods for trading mode-specific behavior // Virtual methods for trading mode-specific behavior
protected virtual async Task SynchronizeWithBrokerPositions(Position internalPosition, Position positionForSignal, List<Position> brokerPositions) protected virtual async Task SynchronizeWithBrokerPositions(Position internalPosition, Position positionForSignal,
List<Position> brokerPositions)
{ {
// Default implementation: do nothing (for backtest) // Default implementation: do nothing (for backtest)
} }
protected virtual async Task HandleOrderManagementAndPositionStatus(LightSignal signal, Position internalPosition, Position positionForSignal) protected virtual async Task HandleOrderManagementAndPositionStatus(LightSignal signal, Position internalPosition,
Position positionForSignal)
{ {
// Default implementation: do nothing (for backtest) // Default implementation: do nothing (for backtest)
} }
@@ -957,44 +962,44 @@ public abstract class TradingBotBase : ITradingBot
LightSignal previousSignal, decimal lastPrice) LightSignal previousSignal, decimal lastPrice)
{ {
// Default implementation - subclasses should override // Default implementation - subclasses should override
if (Config.FlipPosition) if (Config.FlipPosition)
{ {
var isPositionInProfit = (openedPosition.ProfitAndLoss?.Realized ?? 0) > 0; var isPositionInProfit = (openedPosition.ProfitAndLoss?.Realized ?? 0) > 0;
var shouldFlip = !Config.FlipOnlyWhenInProfit || isPositionInProfit; var shouldFlip = !Config.FlipOnlyWhenInProfit || isPositionInProfit;
if (shouldFlip) if (shouldFlip)
{ {
var flipReason = Config.FlipOnlyWhenInProfit var flipReason = Config.FlipOnlyWhenInProfit
? "current position is in profit" ? "current position is in profit"
: "FlipOnlyWhenInProfit is disabled"; : "FlipOnlyWhenInProfit is disabled";
await LogInformation( await LogInformation(
$"🔄 Position Flip Initiated\nFlipping position due to opposite signal\nReason: {flipReason}"); $"🔄 Position Flip Initiated\nFlipping position due to opposite signal\nReason: {flipReason}");
await CloseTrade(previousSignal, openedPosition, openedPosition.Open, lastPrice, true); await CloseTrade(previousSignal, openedPosition, openedPosition.Open, lastPrice, true);
await SetPositionStatus(previousSignal.Identifier, PositionStatus.Flipped); await SetPositionStatus(previousSignal.Identifier, PositionStatus.Flipped);
var newPosition = await OpenPosition(signal); var newPosition = await OpenPosition(signal);
await LogInformation( await LogInformation(
$"✅ Position Flipped\nPosition: `{previousSignal.Identifier}` → `{signal.Identifier}`\nPrice: `${lastPrice}`"); $"✅ Position Flipped\nPosition: `{previousSignal.Identifier}` → `{signal.Identifier}`\nPrice: `${lastPrice}`");
return newPosition; return newPosition;
}
else
{
var currentPnl = openedPosition.ProfitAndLoss?.Realized ?? 0;
await LogInformation(
$"💸 Flip Blocked - Not Profitable\nPosition `{previousSignal.Identifier}` PnL: `${currentPnl:F2}`\nSignal `{signal.Identifier}` will wait for profitability");
SetSignalStatus(signal.Identifier, SignalStatus.Expired);
return null;
}
}
else
{
await LogInformation(
$"🚫 Flip Disabled\nPosition already open for: `{previousSignal.Identifier}`\nFlipping disabled, new signal expired");
SetSignalStatus(signal.Identifier, SignalStatus.Expired);
return null;
}
} }
else
{
var currentPnl = openedPosition.ProfitAndLoss?.Realized ?? 0;
await LogInformation(
$"💸 Flip Blocked - Not Profitable\nPosition `{previousSignal.Identifier}` PnL: `${currentPnl:F2}`\nSignal `{signal.Identifier}` will wait for profitability");
SetSignalStatus(signal.Identifier, SignalStatus.Expired);
return null;
}
}
else
{
await LogInformation(
$"🚫 Flip Disabled\nPosition already open for: `{previousSignal.Identifier}`\nFlipping disabled, new signal expired");
SetSignalStatus(signal.Identifier, SignalStatus.Expired);
return null;
}
}
/// <summary> /// <summary>
/// Executes the actual position opening logic. /// Executes the actual position opening logic.
@@ -1003,34 +1008,34 @@ public abstract class TradingBotBase : ITradingBot
protected virtual async Task<Position> ExecuteOpenPosition(LightSignal signal, decimal lastPrice) protected virtual async Task<Position> ExecuteOpenPosition(LightSignal signal, decimal lastPrice)
{ {
// Default implementation - subclasses should override // Default implementation - subclasses should override
// Verify actual balance before opening position // Verify actual balance before opening position
await VerifyAndUpdateBalanceAsync(); await VerifyAndUpdateBalanceAsync();
var command = new OpenPositionRequest( var command = new OpenPositionRequest(
Config.AccountName, Config.AccountName,
Config.MoneyManagement, Config.MoneyManagement,
signal.Direction, signal.Direction,
Config.Ticker, Config.Ticker,
PositionInitiator.Bot, PositionInitiator.Bot,
signal.Date, signal.Date,
Account.User, Account.User,
Config.BotTradingBalance, Config.BotTradingBalance,
Config.TradingType == TradingType.BacktestFutures, Config.TradingType == TradingType.BacktestFutures,
lastPrice, lastPrice,
signalIdentifier: signal.Identifier, signalIdentifier: signal.Identifier,
initiatorIdentifier: Identifier, initiatorIdentifier: Identifier,
tradingType: Config.TradingType); tradingType: Config.TradingType);
var position = await ServiceScopeHelpers var position = await ServiceScopeHelpers
.WithScopedServices<IExchangeService, IAccountService, ITradingService, Position>( .WithScopedServices<IExchangeService, IAccountService, ITradingService, Position>(
_scopeFactory, _scopeFactory,
async (exchangeService, accountService, tradingService) => async (exchangeService, accountService, tradingService) =>
{ {
return await new OpenPositionCommandHandler(exchangeService, accountService, tradingService) return await new OpenPositionCommandHandler(exchangeService, accountService, tradingService)
.Handle(command); .Handle(command);
}); });
return position; return position;
} }
private async Task SendPositionToCopyTrading(Position position) private async Task SendPositionToCopyTrading(Position position)
@@ -1175,7 +1180,7 @@ public abstract class TradingBotBase : ITradingBot
var brokerHistoryReconciled = await ReconcileWithBrokerHistory(position, currentCandle); var brokerHistoryReconciled = await ReconcileWithBrokerHistory(position, currentCandle);
if (brokerHistoryReconciled && !forceMarketClose) if (brokerHistoryReconciled && !forceMarketClose)
{ {
goto SkipCandleBasedCalculation; goto SkipCandleBasedCalculation;
} }
// Calculate position closing details using subclass-specific logic // Calculate position closing details using subclass-specific logic
@@ -1217,7 +1222,7 @@ public abstract class TradingBotBase : ITradingBot
$"Total Fees: `${position.GasFees + position.UiFees:F2}`\n" + $"Total Fees: `${position.GasFees + position.UiFees:F2}`\n" +
$"Net P&L (after fees): `${position.ProfitAndLoss.Net:F2}`"; $"Net P&L (after fees): `${position.ProfitAndLoss.Net:F2}`";
if (Config.TradingType == TradingType.Futures) if (TradingBox.IsLiveTrading(Config.TradingType))
{ {
await LogDebugAsync(logMessage); await LogDebugAsync(logMessage);
} }
@@ -1227,7 +1232,7 @@ public abstract class TradingBotBase : ITradingBot
await SetPositionStatus(position.SignalIdentifier, PositionStatus.Finished); await SetPositionStatus(position.SignalIdentifier, PositionStatus.Finished);
// Update position in database with all trade changes // Update position in database with all trade changes
if (Config.TradingType == TradingType.Futures) if (TradingBox.IsLiveTrading(Config.TradingType))
{ {
position.Status = PositionStatus.Finished; position.Status = PositionStatus.Finished;
await UpdatePositionDatabase(position); await UpdatePositionDatabase(position);
@@ -1240,7 +1245,9 @@ public abstract class TradingBotBase : ITradingBot
// Update the last position closing time for cooldown period tracking // Update the last position closing time for cooldown period tracking
// Only update if position was actually filled // Only update if position was actually filled
LastPositionClosingTime = Config.TradingType == TradingType.BacktestFutures ? currentCandle.Date : DateTime.UtcNow; LastPositionClosingTime = Config.TradingType == TradingType.BacktestFutures
? currentCandle.Date
: DateTime.UtcNow;
} }
else else
{ {
@@ -1283,7 +1290,7 @@ public abstract class TradingBotBase : ITradingBot
private async Task CancelAllOrders() private async Task CancelAllOrders()
{ {
if (Config.TradingType == TradingType.Futures && !Config.IsForWatchingOnly) if (TradingBox.IsLiveTrading(Config.TradingType) && !Config.IsForWatchingOnly)
{ {
try try
{ {
@@ -1465,7 +1472,7 @@ public abstract class TradingBotBase : ITradingBot
try try
{ {
// Set signal status based on configuration // Set signal status based on configuration
if (Config.IsForWatchingOnly || (ExecutionCount < 1 && Config.TradingType == TradingType.Futures)) if (Config.IsForWatchingOnly || (ExecutionCount < 1 && TradingBox.IsLiveTrading(Config.TradingType)))
{ {
signal.Status = SignalStatus.Expired; signal.Status = SignalStatus.Expired;
} }
@@ -1480,7 +1487,7 @@ public abstract class TradingBotBase : ITradingBot
$"🆔 Signal ID: `{signal.Identifier}`"; $"🆔 Signal ID: `{signal.Identifier}`";
// Apply Synth-based signal filtering if enabled // Apply Synth-based signal filtering if enabled
if (Config.UseSynthApi && Config.TradingType == TradingType.Futures && ExecutionCount > 0) if (Config.UseSynthApi && TradingBox.IsLiveTrading(Config.TradingType) && ExecutionCount > 0)
{ {
await ServiceScopeHelpers.WithScopedServices<ITradingService, IExchangeService>(_scopeFactory, await ServiceScopeHelpers.WithScopedServices<ITradingService, IExchangeService>(_scopeFactory,
async (tradingService, exchangeService) => async (tradingService, exchangeService) =>
@@ -1513,7 +1520,7 @@ public abstract class TradingBotBase : ITradingBot
await LogInformation(signalText); await LogInformation(signalText);
if (Config.IsForWatchingOnly && Config.TradingType == TradingType.Futures && ExecutionCount > 0) if (Config.IsForWatchingOnly && TradingBox.IsLiveTrading(Config.TradingType) && ExecutionCount > 0)
{ {
await ServiceScopeHelpers.WithScopedService<IMessengerService>(_scopeFactory, async messengerService => await ServiceScopeHelpers.WithScopedService<IMessengerService>(_scopeFactory, async messengerService =>
{ {
@@ -1852,7 +1859,8 @@ public abstract class TradingBotBase : ITradingBot
// Calculate cooldown end time based on last position closing time // Calculate cooldown end time based on last position closing time
var cooldownEndTime = var cooldownEndTime =
TradingBox.CalculateCooldownEndTime(LastPositionClosingTime.Value, Config.Timeframe, Config.CooldownPeriod); TradingBox.CalculateCooldownEndTime(LastPositionClosingTime.Value, Config.Timeframe, Config.CooldownPeriod);
var isInCooldown = (Config.TradingType == TradingType.BacktestFutures ? LastCandle.Date : DateTime.UtcNow) < cooldownEndTime; var isInCooldown = (Config.TradingType == TradingType.BacktestFutures ? LastCandle.Date : DateTime.UtcNow) <
cooldownEndTime;
if (isInCooldown) if (isInCooldown)
{ {
@@ -1937,7 +1945,8 @@ public abstract class TradingBotBase : ITradingBot
await agentGrain.OnPositionOpenedAsync(positionOpenEvent); await agentGrain.OnPositionOpenedAsync(positionOpenEvent);
await platformGrain.OnPositionOpenAsync(positionOpenEvent); await platformGrain.OnPositionOpenAsync(positionOpenEvent);
await LogDebugAsync($"Sent position opened event to both grains for position {position.Identifier}"); await LogDebugAsync(
$"Sent position opened event to both grains for position {position.Identifier}");
break; break;
case NotificationEventType.PositionClosed: case NotificationEventType.PositionClosed:
@@ -1952,7 +1961,8 @@ public abstract class TradingBotBase : ITradingBot
await agentGrain.OnPositionClosedAsync(positionClosedEvent); await agentGrain.OnPositionClosedAsync(positionClosedEvent);
await platformGrain.OnPositionClosedAsync(positionClosedEvent); await platformGrain.OnPositionClosedAsync(positionClosedEvent);
await LogDebugAsync($"Sent position closed event to both grains for position {position.Identifier}"); await LogDebugAsync(
$"Sent position closed event to both grains for position {position.Identifier}");
break; break;
case NotificationEventType.PositionUpdated: case NotificationEventType.PositionUpdated:
@@ -2109,7 +2119,7 @@ public abstract class TradingBotBase : ITradingBot
protected virtual async Task SendTradeMessageAsync(string message, bool isBadBehavior = false) protected virtual async Task SendTradeMessageAsync(string message, bool isBadBehavior = false)
{ {
if (Config.TradingType == TradingType.Futures) if (TradingBox.IsLiveTrading(Config.TradingType))
{ {
var user = Account.User; var user = Account.User;
var messageWithBotName = $"🤖 {user.AgentName} - {Config.Name}\n{message}"; var messageWithBotName = $"🤖 {user.AgentName} - {Config.Name}\n{message}";

View File

@@ -121,7 +121,7 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
await base.OnDeactivateAsync(reason, cancellationToken); await base.OnDeactivateAsync(reason, cancellationToken);
} }
public Task<HashSet<Candle>> GetCandlesAsync() public Task<IReadOnlyList<Candle>> GetCandlesAsync()
{ {
try try
{ {
@@ -130,15 +130,16 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver<Candle>
{ {
_logger.LogWarning("State not initialized for grain {GrainKey}, returning empty list", _logger.LogWarning("State not initialized for grain {GrainKey}, returning empty list",
this.GetPrimaryKeyString()); this.GetPrimaryKeyString());
return Task.FromResult(new HashSet<Candle>()); return Task.FromResult<IReadOnlyList<Candle>>(new List<Candle>());
} }
return Task.FromResult(_state.State.Candles.ToHashSet()); // Return a readonly wrapper to preserve order and prevent external modifications
return Task.FromResult<IReadOnlyList<Candle>>(_state.State.Candles.AsReadOnly());
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Error retrieving candles for grain {GrainKey}", this.GetPrimaryKeyString()); _logger.LogError(ex, "Error retrieving candles for grain {GrainKey}", this.GetPrimaryKeyString());
return Task.FromResult(new HashSet<Candle>()); return Task.FromResult<IReadOnlyList<Candle>>(new List<Candle>());
} }
} }

View File

@@ -32,11 +32,11 @@ public class ScenarioRunnerGrain : Grain, IScenarioRunnerGrain
_scopeFactory = scopeFactory; _scopeFactory = scopeFactory;
} }
private async Task<HashSet<Candle>> GetCandlesAsync(TradingExchanges tradingExchange, TradingBotConfig config) private async Task<IReadOnlyList<Candle>> GetCandlesAsync(TradingExchanges tradingExchange, TradingBotConfig config)
{ {
try try
{ {
var newCandles = await ServiceScopeHelpers.WithScopedService<IGrainFactory, HashSet<Candle>>( var newCandles = await ServiceScopeHelpers.WithScopedService<IGrainFactory, IReadOnlyList<Candle>>(
_scopeFactory, async grainFactory => _scopeFactory, async grainFactory =>
{ {
var priceGrainKey = var priceGrainKey =
@@ -66,9 +66,8 @@ public class ScenarioRunnerGrain : Grain, IScenarioRunnerGrain
return null; return null;
} }
var candlesHashSet = await GetCandlesAsync(tradingExchanges, config); // Get candles as ordered List (already ordered by date from CandleStoreGrain)
// Convert to ordered List to preserve chronological order for indicators var candlesList = await GetCandlesAsync(tradingExchanges, config);
var candlesList = candlesHashSet.OrderBy(c => c.Date).ToList();
if (candlesList.Count == 0) if (candlesList.Count == 0)
{ {

View File

@@ -66,7 +66,7 @@ public class Backtest
Timeframe = Config.Timeframe, Timeframe = Config.Timeframe,
IsForWatchingOnly = false, // Always start as active bot IsForWatchingOnly = false, // Always start as active bot
BotTradingBalance = initialTradingBalance, BotTradingBalance = initialTradingBalance,
TradingType = TradingType.Futures, // Always Futures for live bots TradingType = Config.TradingType,
CooldownPeriod = Config.CooldownPeriod, CooldownPeriod = Config.CooldownPeriod,
MaxLossStreak = Config.MaxLossStreak, MaxLossStreak = Config.MaxLossStreak,
MaxPositionTimeHours = Config.MaxPositionTimeHours, // Properly copy nullable value MaxPositionTimeHours = Config.MaxPositionTimeHours, // Properly copy nullable value

View File

@@ -69,12 +69,6 @@ public static class TradingBox
preCalculatedIndicatorValues); preCalculatedIndicatorValues);
} }
public static LightSignal GetSignal(IReadOnlyList<Candle> newCandles, LightScenario lightScenario,
Dictionary<string, LightSignal> previousSignal, IndicatorComboConfig config, int? loopbackPeriod = 1)
{
return GetSignal(newCandles, lightScenario, previousSignal, config, loopbackPeriod, null);
}
public static LightSignal GetSignal(IReadOnlyList<Candle> newCandles, LightScenario lightScenario, public static LightSignal GetSignal(IReadOnlyList<Candle> newCandles, LightScenario lightScenario,
Dictionary<string, LightSignal> previousSignal, IndicatorComboConfig config, int? loopbackPeriod, Dictionary<string, LightSignal> previousSignal, IndicatorComboConfig config, int? loopbackPeriod,
Dictionary<IndicatorType, IndicatorsResultBase> preCalculatedIndicatorValues) Dictionary<IndicatorType, IndicatorsResultBase> preCalculatedIndicatorValues)
@@ -1343,4 +1337,23 @@ public static class TradingBox
} }
#endregion #endregion
public static bool IsLiveTrading(TradingType tradingType)
{
return tradingType switch
{
TradingType.Futures => true,
TradingType.Spot => true,
_ => false
};
}
public static TradingType GetLiveTradingType(TradingType tradingType)
{
return tradingType switch {
TradingType.BacktestFutures => TradingType.Futures,
TradingType.BacktestSpot => TradingType.Spot,
_ => throw new InvalidOperationException($"Unsupported TradingType for live trading: {tradingType}")
};
}
} }

View File

@@ -13,9 +13,9 @@ describe('swap tokens implementation', () => {
console.log('Account', sdk.account) console.log('Account', sdk.account)
const result = await swapGmxTokensImpl( const result = await swapGmxTokensImpl(
sdk, sdk,
Ticker.ETH, Ticker.BTC,
Ticker.USDC, Ticker.USDC,
0.0042 0.00006733
) )
assert.strictEqual(typeof result, 'string') assert.strictEqual(typeof result, 'string')