Fix bot things
This commit is contained in:
@@ -73,11 +73,11 @@ public class DataController : ControllerBase
|
|||||||
public ActionResult<SpotlightOverview> GetSpotlight()
|
public ActionResult<SpotlightOverview> GetSpotlight()
|
||||||
{
|
{
|
||||||
var overview = _cacheService.GetOrSave(nameof(SpotlightOverview),
|
var overview = _cacheService.GetOrSave(nameof(SpotlightOverview),
|
||||||
() => { return _statisticService.GetLastSpotlight(DateTime.Now.AddHours(-3)); }, TimeSpan.FromMinutes(2));
|
() => { return _statisticService.GetLastSpotlight(DateTime.Now.AddDays(-2)); }, TimeSpan.FromMinutes(2));
|
||||||
|
|
||||||
if (overview?.Spotlights.Count < overview?.ScenarioCount)
|
if (overview?.Spotlights.Count < overview?.ScenarioCount || overview == null)
|
||||||
{
|
{
|
||||||
overview = _statisticService.GetLastSpotlight(DateTime.Now.AddHours(-3));
|
overview = _statisticService.GetLastSpotlight(DateTime.Now.AddDays(-2));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(overview);
|
return Ok(overview);
|
||||||
|
|||||||
@@ -32,4 +32,5 @@ public interface IBotService
|
|||||||
Task<bool> DeleteBot(string requestName);
|
Task<bool> DeleteBot(string requestName);
|
||||||
Task<string> RestartBot(string requestName);
|
Task<string> RestartBot(string requestName);
|
||||||
void DeleteBotBackup(string backupBotName);
|
void DeleteBotBackup(string backupBotName);
|
||||||
|
void ToggleIsForWatchingOnly(string botName);
|
||||||
}
|
}
|
||||||
@@ -210,6 +210,17 @@ namespace Managing.Application.ManageBot
|
|||||||
_botRepository.DeleteBotBackup(backupBotName);
|
_botRepository.DeleteBotBackup(backupBotName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ToggleIsForWatchingOnly(string botName)
|
||||||
|
{
|
||||||
|
if (_botTasks.TryGetValue(botName, out var botWrapper))
|
||||||
|
{
|
||||||
|
if (botWrapper.BotInstance is ITradingBot bot)
|
||||||
|
{
|
||||||
|
bot.IsForWatchingOnly = !bot.IsForWatchingOnly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ITradingBot CreateScalpingBot(string accountName, MoneyManagement moneyManagement, string name,
|
public ITradingBot CreateScalpingBot(string accountName, MoneyManagement moneyManagement, string name,
|
||||||
Enums.Ticker ticker, string scenario, Enums.Timeframe interval, bool isForWatchingOnly)
|
Enums.Ticker ticker, string scenario, Enums.Timeframe interval, bool isForWatchingOnly)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ namespace Managing.Application.ManageBot
|
|||||||
{
|
{
|
||||||
public class ToggleIsForWatchingCommandHandler : IRequestHandler<ToggleIsForWatchingCommand, string>
|
public class ToggleIsForWatchingCommandHandler : IRequestHandler<ToggleIsForWatchingCommand, string>
|
||||||
{
|
{
|
||||||
private readonly ITaskCache _taskCache;
|
private readonly IBotService _botService;
|
||||||
|
|
||||||
public ToggleIsForWatchingCommandHandler(ITaskCache taskCache)
|
public ToggleIsForWatchingCommandHandler(IBotService botService)
|
||||||
{
|
{
|
||||||
_taskCache = taskCache;
|
_botService = botService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> Handle(ToggleIsForWatchingCommand request, CancellationToken cancellationToken)
|
public Task<string> Handle(ToggleIsForWatchingCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var bot = _taskCache.Get<ITradingBot>(request.Name);
|
_botService.ToggleIsForWatchingOnly(request.Name);
|
||||||
await bot.ToggleIsForWatchOnly();
|
var bot = _botService.GetActiveBots().FirstOrDefault(b => b.Name == request.Name);
|
||||||
return bot.GetStatus();
|
return Task.FromResult(bot?.IsForWatchingOnly.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,25 +31,36 @@ namespace Managing.Domain.Bots
|
|||||||
|
|
||||||
public async Task InitWorker(Func<Task> action)
|
public async Task InitWorker(Func<Task> action)
|
||||||
{
|
{
|
||||||
await Task.Run(async () =>
|
try
|
||||||
{
|
{
|
||||||
while (Status == BotStatus.Up)
|
await Task.Run(async () =>
|
||||||
{
|
{
|
||||||
try
|
while (Status == BotStatus.Up && !CancellationToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
await action();
|
try
|
||||||
|
{
|
||||||
|
await action();
|
||||||
|
ExecutionCount++;
|
||||||
|
await Task.Delay(Interval, CancellationToken.Token);
|
||||||
|
if (CancellationToken.IsCancellationRequested)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (TaskCanceledException) when (CancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
// Graceful shutdown when cancellation is requested
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
}, CancellationToken.Token);
|
||||||
{
|
}
|
||||||
Console.WriteLine(ex.Message);
|
catch (TaskCanceledException)
|
||||||
}
|
{
|
||||||
|
Console.WriteLine();
|
||||||
ExecutionCount++;
|
}
|
||||||
await Task.Delay(Interval, CancellationToken.Token);
|
|
||||||
if (CancellationToken.IsCancellationRequested)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}, CancellationToken.Token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
|
|||||||
@@ -7,16 +7,11 @@ type UseAccountsProps = {
|
|||||||
callback?: (data: Account[]) => void | undefined
|
callback?: (data: Account[]) => void | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const useAcconuts = ({ callback }: UseAccountsProps) => {
|
const useAccounts = ({ }: UseAccountsProps) => {
|
||||||
const { apiUrl } = useApiUrlStore()
|
const { apiUrl } = useApiUrlStore()
|
||||||
const accountClient = new AccountClient({}, apiUrl)
|
const accountClient = new AccountClient({}, apiUrl)
|
||||||
|
|
||||||
const query = useQuery({
|
const query = useQuery({
|
||||||
onSuccess: (data) => {
|
|
||||||
if (data && callback) {
|
|
||||||
callback(data)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
queryFn: () => accountClient.account_GetAccounts(),
|
queryFn: () => accountClient.account_GetAccounts(),
|
||||||
queryKey: ['accounts'],
|
queryKey: ['accounts'],
|
||||||
})
|
})
|
||||||
@@ -24,4 +19,4 @@ const useAcconuts = ({ callback }: UseAccountsProps) => {
|
|||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
export default useAcconuts
|
export default useAccounts
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ const BotList: React.FC<IBotList> = ({ list }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getMoneyManagementBadge(moneyManagement: MoneyManagement) {
|
function getMoneyManagementBadge(moneyManagement: MoneyManagement) {
|
||||||
const classes = baseBadgeClass() + 'bg-primary'
|
const classes = baseBadgeClass() + ' bg-primary'
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className={classes}
|
className={classes}
|
||||||
@@ -115,7 +115,7 @@ const BotList: React.FC<IBotList> = ({ list }) => {
|
|||||||
>
|
>
|
||||||
<p className="text-primary-content flex">
|
<p className="text-primary-content flex">
|
||||||
<EyeIcon width={15}></EyeIcon>
|
<EyeIcon width={15}></EyeIcon>
|
||||||
{moneyManagement.name}
|
MoneyManagement
|
||||||
</p>
|
</p>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
@@ -180,26 +180,13 @@ const BotList: React.FC<IBotList> = ({ list }) => {
|
|||||||
</figure>
|
</figure>
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<h2 className="card-title text-sm">
|
<h2 className="card-title text-sm">
|
||||||
{bot.name}
|
{bot.ticker}
|
||||||
{/* {exchangeBadge(bot.exchange)} */}
|
{getMoneyManagementBadge(bot.moneyManagement)}
|
||||||
{getIsForWatchingBadge(bot.isForWatchingOnly, bot.name)}
|
{getIsForWatchingBadge(bot.isForWatchingOnly, bot.name)}
|
||||||
{getToggleBotStatusBadge(bot.status, bot.name, bot.botType)}
|
{getToggleBotStatusBadge(bot.status, bot.name, bot.botType)}
|
||||||
{getDeleteBadge(bot.name)}
|
{getDeleteBadge(bot.name)}
|
||||||
{getMoneyManagementBadge(bot.moneyManagement)}
|
|
||||||
</h2>
|
</h2>
|
||||||
<div className="columns-2">
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<CardText title="Ticker" content={bot.ticker}></CardText>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<CardText
|
|
||||||
title="Timeframe"
|
|
||||||
content={bot.timeframe}
|
|
||||||
></CardText>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="columns-2">
|
<div className="columns-2">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -23,11 +23,9 @@ import {
|
|||||||
} from '../../generated/ManagingApi'
|
} from '../../generated/ManagingApi'
|
||||||
|
|
||||||
import BotList from './botList'
|
import BotList from './botList'
|
||||||
|
import { useQuery } from '@tanstack/react-query'
|
||||||
|
|
||||||
const Bots: React.FC = () => {
|
const Bots: React.FC = () => {
|
||||||
const [bots, setBots] = useState<TradingBot[]>([])
|
|
||||||
const [scenarios, setScenarios] = React.useState<Scenario[]>([])
|
|
||||||
const [accounts, setAccounts] = React.useState<Account[]>([])
|
|
||||||
const [showModal, setShowModal] = useState(false)
|
const [showModal, setShowModal] = useState(false)
|
||||||
const { register, handleSubmit } = useForm<StartBotRequest>()
|
const { register, handleSubmit } = useForm<StartBotRequest>()
|
||||||
const { apiUrl } = useApiUrlStore()
|
const { apiUrl } = useApiUrlStore()
|
||||||
@@ -46,42 +44,39 @@ const Bots: React.FC = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
const { data: bots } = useQuery({
|
||||||
setupHubConnection().then(() => {
|
queryFn: () => botClient.bot_GetActiveBots(),
|
||||||
if (bots.length == 0) {
|
queryKey: ['bots'],
|
||||||
botClient.bot_GetActiveBots().then((data) => {
|
})
|
||||||
setBots(data)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const scenarioClient = new ScenarioClient({}, apiUrl)
|
const scenarioClient = new ScenarioClient({}, apiUrl)
|
||||||
scenarioClient.scenario_GetScenarios().then((data) => {
|
const { data: scenarios } = useQuery({
|
||||||
setScenarios(data)
|
queryFn: () => scenarioClient.scenario_GetScenarios(),
|
||||||
})
|
queryKey: ['scenarios'],
|
||||||
|
})
|
||||||
|
|
||||||
const accountClient = new AccountClient({}, apiUrl)
|
const accountClient = new AccountClient({}, apiUrl)
|
||||||
accountClient.account_GetAccounts().then((data) => {
|
const { data: accounts } = useQuery({
|
||||||
setAccounts(data)
|
queryFn: () => accountClient.account_GetAccounts(),
|
||||||
})
|
queryKey: ['accounts'],
|
||||||
}, [])
|
})
|
||||||
|
|
||||||
const setupHubConnection = async () => {
|
// const setupHubConnection = async () => {
|
||||||
const hub = new Hub('bothub', apiUrl).hub
|
// const hub = new Hub('bothub', apiUrl).hub
|
||||||
|
|
||||||
hub.on('BotsSubscription', (bots: TradingBot[]) => {
|
// hub.on('BotsSubscription', (bots: TradingBot[]) => {
|
||||||
// eslint-disable-next-line no-console
|
// // eslint-disable-next-line no-console
|
||||||
console.log(
|
// console.log(
|
||||||
'bot List',
|
// 'bot List',
|
||||||
bots.map((bot) => {
|
// bots.map((bot) => {
|
||||||
return bot.name
|
// return bot.name
|
||||||
})
|
// })
|
||||||
)
|
// )
|
||||||
setBots(bots)
|
// setBots(bots)
|
||||||
})
|
// })
|
||||||
|
|
||||||
return hub
|
// return hub
|
||||||
}
|
// }
|
||||||
|
|
||||||
function openModal() {
|
function openModal() {
|
||||||
setShowModal(true)
|
setShowModal(true)
|
||||||
@@ -136,7 +131,7 @@ const Bots: React.FC = () => {
|
|||||||
<PlayIcon width="20"></PlayIcon>
|
<PlayIcon width="20"></PlayIcon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<BotList list={bots} />
|
<BotList list={bots || []} />
|
||||||
{showModal ? (
|
{showModal ? (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user