Fix Runtime by adding TotalRuntimeInSeconds
This commit is contained in:
@@ -105,6 +105,7 @@ const LogIn = () => {
|
||||
<label
|
||||
htmlFor="name"
|
||||
className="dark:text-white block mb-2 text-sm font-medium text-gray-900"
|
||||
hidden={true}
|
||||
>
|
||||
Name
|
||||
</label>
|
||||
|
||||
@@ -4491,7 +4491,8 @@ export interface UserStrategyDetailsViewModel {
|
||||
pnL?: number;
|
||||
netPnL?: number;
|
||||
roiPercentage?: number;
|
||||
runtime?: Date;
|
||||
runtime?: Date | null;
|
||||
totalRuntimeSeconds?: number;
|
||||
winRate?: number;
|
||||
totalVolumeTraded?: number;
|
||||
volumeLast24H?: number;
|
||||
|
||||
@@ -974,7 +974,8 @@ export interface UserStrategyDetailsViewModel {
|
||||
pnL?: number;
|
||||
netPnL?: number;
|
||||
roiPercentage?: number;
|
||||
runtime?: Date;
|
||||
runtime?: Date | null;
|
||||
totalRuntimeSeconds?: number;
|
||||
winRate?: number;
|
||||
totalVolumeTraded?: number;
|
||||
volumeLast24H?: number;
|
||||
|
||||
@@ -48,14 +48,10 @@ function AgentSearch({ index }: { index: number }) {
|
||||
)
|
||||
])
|
||||
|
||||
// Extract open positions from all strategies
|
||||
// Extract positions from all strategies (status not available in generated PositionViewModel)
|
||||
const allPositions = strategies.flatMap(strategy => strategy.positions || [])
|
||||
const openPositions = allPositions.filter(position =>
|
||||
position.status !== 'Finished' &&
|
||||
position.status !== 'Canceled'
|
||||
)
|
||||
|
||||
setAgentData({ strategies, balances, positions: openPositions })
|
||||
|
||||
setAgentData({ strategies, balances, positions: allPositions })
|
||||
} catch (err) {
|
||||
setError('Failed to fetch agent data. Please check the agent name and try again.')
|
||||
console.error('Error fetching agent data:', err)
|
||||
@@ -461,13 +457,20 @@ function AgentSearch({ index }: { index: number }) {
|
||||
{strategy.roiPercentage && strategy.roiPercentage >= 0 ? '+' : ''}{(strategy.roiPercentage || 0).toFixed(2)}%
|
||||
</span>
|
||||
<span>
|
||||
{strategy.runtime ? (() => {
|
||||
const runtime = new Date(strategy.runtime)
|
||||
const now = new Date()
|
||||
const diffHours = Math.floor((now.getTime() - runtime.getTime()) / (1000 * 60 * 60))
|
||||
const diffDays = Math.floor(diffHours / 24)
|
||||
return diffDays > 0 ? `${diffDays}d ${diffHours % 24}h` : `${diffHours}h`
|
||||
{strategy.totalRuntimeSeconds > 0 ? (() => {
|
||||
const totalSeconds = strategy.totalRuntimeSeconds
|
||||
const days = Math.floor(totalSeconds / 86400)
|
||||
const hours = Math.floor((totalSeconds % 86400) / 3600)
|
||||
const minutes = Math.floor((totalSeconds % 3600) / 60)
|
||||
if (days > 0) {
|
||||
return `${days}d ${hours}h`
|
||||
} else if (hours > 0) {
|
||||
return `${hours}h ${minutes}m`
|
||||
} else {
|
||||
return `${minutes}m`
|
||||
}
|
||||
})() : '-'}
|
||||
{strategy.state === BotStatus.Running && <span className="ml-1 text-green-500">●</span>}
|
||||
</span>
|
||||
<span>{(strategy.winRate || 0).toFixed(0)}%</span>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import React, {useEffect, useState} from 'react'
|
||||
import {PlayIcon, StopIcon} from '@heroicons/react/solid'
|
||||
import moment from 'moment'
|
||||
import {
|
||||
BotClient,
|
||||
BotStatus,
|
||||
DataClient,
|
||||
Position,
|
||||
TradeDirection,
|
||||
UserStrategyDetailsViewModel
|
||||
BotClient,
|
||||
BotStatus,
|
||||
DataClient,
|
||||
PositionViewModel,
|
||||
TradeDirection,
|
||||
UserStrategyDetailsViewModel
|
||||
} from '../../generated/ManagingApi'
|
||||
import useApiUrlStore from '../../app/store/apiStore'
|
||||
import {Toast} from '../../components/mollecules'
|
||||
@@ -62,16 +61,12 @@ const AgentStrategy: React.FC<AgentStrategyProps> = ({ index }) => {
|
||||
return `${value >= 0 ? '+' : ''}${value.toFixed(2)}%`
|
||||
}
|
||||
|
||||
const formatDuration = (runtime?: Date | null) => {
|
||||
if (!runtime) return '0h'
|
||||
const formatDuration = (totalRuntimeSeconds?: number | null) => {
|
||||
if (!totalRuntimeSeconds || totalRuntimeSeconds === 0) return '0h'
|
||||
|
||||
const start = moment(runtime)
|
||||
const now = moment()
|
||||
const duration = moment.duration(now.diff(start))
|
||||
|
||||
const days = Math.floor(duration.asDays())
|
||||
const hours = duration.hours()
|
||||
const minutes = duration.minutes()
|
||||
const days = Math.floor(totalRuntimeSeconds / 86400)
|
||||
const hours = Math.floor((totalRuntimeSeconds % 86400) / 3600)
|
||||
const minutes = Math.floor((totalRuntimeSeconds % 3600) / 60)
|
||||
|
||||
if (days > 0) {
|
||||
return `${days}d ${hours}h ${minutes}m`
|
||||
@@ -82,22 +77,22 @@ const AgentStrategy: React.FC<AgentStrategyProps> = ({ index }) => {
|
||||
}
|
||||
}
|
||||
|
||||
const getStatusBadge = (state: string | null | undefined) => {
|
||||
const badgeClass = state === 'Up'
|
||||
? 'badge badge-success'
|
||||
: state === 'Down'
|
||||
? 'badge badge-error'
|
||||
const getStatusBadge = (state: BotStatus | null | undefined) => {
|
||||
const badgeClass = state === BotStatus.Running
|
||||
? 'badge badge-success'
|
||||
: state === BotStatus.Stopped
|
||||
? 'badge badge-warning'
|
||||
: 'badge badge-neutral'
|
||||
|
||||
|
||||
return <span className={badgeClass}>{state}</span>
|
||||
}
|
||||
|
||||
const toggleStrategyStatus = (status: string | null | undefined, identifier: string) => {
|
||||
const isUp = status === 'Up'
|
||||
const t = new Toast(isUp ? 'Stopping strategy' : 'Starting strategy')
|
||||
const toggleStrategyStatus = (status: BotStatus | null | undefined, identifier: string) => {
|
||||
const isRunning = status === BotStatus.Running
|
||||
const t = new Toast(isRunning ? 'Stopping strategy' : 'Starting strategy')
|
||||
|
||||
console.log('toggleStrategyStatus', status, identifier)
|
||||
if (status === 'Up') {
|
||||
if (status === BotStatus.Running) {
|
||||
botClient
|
||||
.bot_Stop(identifier)
|
||||
.then(() => {
|
||||
@@ -108,7 +103,7 @@ const AgentStrategy: React.FC<AgentStrategyProps> = ({ index }) => {
|
||||
.catch((err) => {
|
||||
t.update('error', err)
|
||||
})
|
||||
} else if (status === 'Down' || status === 'None') {
|
||||
} else {
|
||||
botClient
|
||||
.bot_Restart(identifier)
|
||||
.then(() => {
|
||||
@@ -212,7 +207,7 @@ const AgentStrategy: React.FC<AgentStrategyProps> = ({ index }) => {
|
||||
</div>
|
||||
<div className="stat bg-base-200 rounded-lg">
|
||||
<div className="stat-title">Runtime</div>
|
||||
<div className="stat-value text-sm">{formatDuration(strategyData.runtime)}</div>
|
||||
<div className="stat-value text-sm">{formatDuration(strategyData.totalRuntimeSeconds)}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -292,7 +287,7 @@ const AgentStrategy: React.FC<AgentStrategyProps> = ({ index }) => {
|
||||
<div className="card bg-base-200">
|
||||
<div className="card-body">
|
||||
<h3 className="card-title">Total Runtime</h3>
|
||||
<div className="text-2xl font-bold">{formatDuration(strategyData.runtime)}</div>
|
||||
<div className="text-2xl font-bold">{formatDuration(strategyData.totalRuntimeSeconds)}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -302,7 +297,7 @@ const AgentStrategy: React.FC<AgentStrategyProps> = ({ index }) => {
|
||||
<div className="card bg-base-200">
|
||||
<div className="card-body">
|
||||
<h3 className="card-title">Trade History</h3>
|
||||
{strategyData.positions && Object.keys(strategyData.positions).length > 0 ? (
|
||||
{strategyData.positions && strategyData.positions.length > 0 ? (
|
||||
<div className="overflow-x-auto">
|
||||
<table className="table table-zebra">
|
||||
<thead>
|
||||
@@ -317,8 +312,7 @@ const AgentStrategy: React.FC<AgentStrategyProps> = ({ index }) => {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Object.values(strategyData.positions).map((position: Position, index: number) => (
|
||||
console.log(position),
|
||||
{(strategyData.positions || []).map((position: PositionViewModel, index: number) => (
|
||||
<tr key={index}>
|
||||
<td>{new Date(position.Open.date || '').toLocaleDateString()}</td>
|
||||
<td>{position.ticker}</td>
|
||||
|
||||
Reference in New Issue
Block a user