update position count to open position only
This commit is contained in:
@@ -159,13 +159,16 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
|
||||
|
||||
_state.State.PositionCountByAsset[ticker]++;
|
||||
|
||||
// Position count breakdown by direction - update state directly
|
||||
if (!_state.State.PositionCountByDirection.ContainsKey(direction))
|
||||
// Position count breakdown by direction - only count finished positions
|
||||
if (!position.IsFinished())
|
||||
{
|
||||
_state.State.PositionCountByDirection[direction] = 0;
|
||||
}
|
||||
if (!_state.State.PositionCountByDirection.ContainsKey(direction))
|
||||
{
|
||||
_state.State.PositionCountByDirection[direction] = 0;
|
||||
}
|
||||
|
||||
_state.State.PositionCountByDirection[direction]++;
|
||||
_state.State.PositionCountByDirection[direction]++;
|
||||
}
|
||||
}
|
||||
|
||||
_state.State.TotalPlatformVolume = totalVolume;
|
||||
|
||||
@@ -16,12 +16,6 @@ interface AgentData {
|
||||
positions: Position[]
|
||||
}
|
||||
|
||||
const FILTERS = [
|
||||
{ label: '1D', value: '1D', days: 1 },
|
||||
{ label: '1W', value: '1W', days: 7 },
|
||||
{ label: '1M', value: '1M', days: 30 },
|
||||
{ label: 'Total', value: 'Total', days: null },
|
||||
]
|
||||
|
||||
function AgentSearch({ index }: { index: number }) {
|
||||
const { apiUrl } = useApiUrlStore()
|
||||
@@ -29,7 +23,6 @@ function AgentSearch({ index }: { index: number }) {
|
||||
const [agentData, setAgentData] = useState<AgentData | null>(null)
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [selectedFilter, setSelectedFilter] = useState('Total')
|
||||
|
||||
const searchAgent = async () => {
|
||||
if (!agentName.trim()) return
|
||||
@@ -75,20 +68,6 @@ function AgentSearch({ index }: { index: number }) {
|
||||
}
|
||||
}
|
||||
|
||||
// Filter balances based on selected time period
|
||||
const getFilteredBalances = () => {
|
||||
if (!agentData?.balances?.agentBalances) return []
|
||||
|
||||
const filterObj = FILTERS.find(f => f.value === selectedFilter)
|
||||
if (!filterObj?.days) return agentData.balances.agentBalances // Total - return all
|
||||
|
||||
const now = new Date()
|
||||
const cutoff = new Date(now.getTime() - filterObj.days * 24 * 60 * 60 * 1000)
|
||||
|
||||
return agentData.balances.agentBalances.filter(balance =>
|
||||
balance.time && new Date(balance.time) >= cutoff
|
||||
)
|
||||
}
|
||||
|
||||
// Calculate current total balance
|
||||
const getCurrentBalance = () => {
|
||||
@@ -104,25 +83,13 @@ function AgentSearch({ index }: { index: number }) {
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate PnL for the selected time period
|
||||
const calculateFilteredPnL = () => {
|
||||
const filteredBalances = getFilteredBalances()
|
||||
if (filteredBalances.length < 2) return 0
|
||||
|
||||
const startBalance = filteredBalances[0]
|
||||
const endBalance = filteredBalances[filteredBalances.length - 1]
|
||||
|
||||
const startValue = startBalance.totalValue || 0
|
||||
const endValue = endBalance.totalValue || 0
|
||||
|
||||
return endValue - startValue
|
||||
}
|
||||
|
||||
// Calculate summary statistics from strategies
|
||||
const calculateSummary = () => {
|
||||
if (!agentData?.strategies.length) return null
|
||||
|
||||
const totalPnL = agentData.strategies.reduce((sum, strategy) => sum + (strategy.pnL || 0), 0)
|
||||
const totalNetPnL = agentData.strategies.reduce((sum, strategy) => sum + (strategy.netPnL || 0), 0)
|
||||
const totalVolume = agentData.strategies.reduce((sum, strategy) => sum + (strategy.totalVolumeTraded || 0), 0)
|
||||
const totalWins = agentData.strategies.reduce((sum, strategy) => sum + (strategy.wins || 0), 0)
|
||||
const totalLosses = agentData.strategies.reduce((sum, strategy) => sum + (strategy.losses || 0), 0)
|
||||
@@ -130,12 +97,9 @@ function AgentSearch({ index }: { index: number }) {
|
||||
? agentData.strategies.reduce((sum, strategy) => sum + (strategy.winRate || 0), 0) / agentData.strategies.length
|
||||
: 0
|
||||
|
||||
// Calculate filtered PnL based on selected time period
|
||||
const filteredPnL = calculateFilteredPnL()
|
||||
|
||||
return {
|
||||
totalPnL,
|
||||
filteredPnL,
|
||||
totalNetPnL,
|
||||
totalVolume,
|
||||
totalWins,
|
||||
totalLosses,
|
||||
@@ -252,18 +216,6 @@ function AgentSearch({ index }: { index: number }) {
|
||||
|
||||
{summary && (
|
||||
<GridTile title={`Agent Stats - ${agentName}`}>
|
||||
{/* Time Filter Buttons */}
|
||||
<div className="flex gap-2 mb-4">
|
||||
{FILTERS.map(f => (
|
||||
<button
|
||||
key={f.value}
|
||||
className={`px-3 py-1 text-sm rounded ${selectedFilter === f.value ? 'bg-primary text-primary-content' : 'bg-base-200 hover:bg-base-300'}`}
|
||||
onClick={() => setSelectedFilter(f.value)}
|
||||
>
|
||||
{f.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Current Balance Display */}
|
||||
{currentBalance && (
|
||||
@@ -303,21 +255,6 @@ function AgentSearch({ index }: { index: number }) {
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card name={`PnL (${selectedFilter})`}>
|
||||
<div className="stat">
|
||||
<div className="stat-title text-xs">PnL ({selectedFilter})</div>
|
||||
<div className="stat-value text-lg">
|
||||
<span className={summary.filteredPnL >= 0 ? 'text-green-500' : 'text-red-500'}>
|
||||
{summary.filteredPnL >= 0 ? '+' : ''}${summary.filteredPnL.toLocaleString(undefined, { maximumFractionDigits: 2 })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="stat-desc text-xs">
|
||||
<span className={summary.filteredPnL >= 0 ? 'text-green-500' : 'text-red-500'}>
|
||||
{currentBalance ? `${((summary.filteredPnL / currentBalance.totalValue) * 100).toFixed(2)}%` : ''}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card name="Active Strategies">
|
||||
<div className="stat">
|
||||
@@ -331,8 +268,8 @@ function AgentSearch({ index }: { index: number }) {
|
||||
<div className="stat">
|
||||
<div className="stat-title text-xs">ROI</div>
|
||||
<div className="stat-value text-lg">
|
||||
<span className={summary.totalPnL >= 0 ? 'text-green-500' : 'text-red-500'}>
|
||||
{((summary.totalPnL / (summary.totalVolume || 1)) * 100).toFixed(2)}%
|
||||
<span className={summary.totalNetPnL >= 0 ? 'text-green-500' : 'text-red-500'}>
|
||||
{((summary.totalNetPnL / (summary.totalVolume || 1)) * 100).toFixed(2)}%
|
||||
</span>
|
||||
</div>
|
||||
<div className="stat-desc text-xs">Return on Investment</div>
|
||||
@@ -347,7 +284,21 @@ function AgentSearch({ index }: { index: number }) {
|
||||
{summary.totalPnL >= 0 ? '+' : ''}${summary.totalPnL.toLocaleString(undefined, { maximumFractionDigits: 2 })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="stat-desc text-xs">All time P&L</div>
|
||||
<div className="stat-desc text-xs">
|
||||
Net: <span className={summary.totalNetPnL >= 0 ? 'text-green-500' : 'text-red-500'}>
|
||||
{summary.totalNetPnL >= 0 ? '+' : ''}${summary.totalNetPnL.toLocaleString(undefined, { maximumFractionDigits: 2 })}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card name="Total Fees">
|
||||
<div className="stat">
|
||||
<div className="stat-title text-xs">Total Fees</div>
|
||||
<div className="stat-value text-lg text-orange-500">
|
||||
${(summary.totalPnL - summary.totalNetPnL).toLocaleString(undefined, { maximumFractionDigits: 2 })}
|
||||
</div>
|
||||
<div className="stat-desc text-xs">Fees paid across all strategies</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
@@ -361,7 +312,7 @@ function AgentSearch({ index }: { index: number }) {
|
||||
<span>Name</span>
|
||||
<span>Ticker</span>
|
||||
<span>Status</span>
|
||||
<span>PnL</span>
|
||||
<span>Net PnL</span>
|
||||
<span>ROI</span>
|
||||
<span>Runtime</span>
|
||||
<span>Avg Winrate</span>
|
||||
@@ -374,8 +325,8 @@ function AgentSearch({ index }: { index: number }) {
|
||||
<span className={`badge ${strategy.state == BotStatus.Running ? 'badge-success' : 'badge-warning'}`}>
|
||||
{strategy.state}
|
||||
</span>
|
||||
<span className={strategy.pnL && strategy.pnL >= 0 ? 'text-green-500' : 'text-red-500'}>
|
||||
{strategy.pnL && strategy.pnL >= 0 ? '+' : ''}${(strategy.pnL || 0).toFixed(2)}
|
||||
<span className={strategy.netPnL && strategy.netPnL >= 0 ? 'text-green-500' : 'text-red-500'}>
|
||||
{strategy.netPnL && strategy.netPnL >= 0 ? '+' : ''}${(strategy.netPnL || 0).toFixed(2)}
|
||||
</span>
|
||||
<span className={strategy.roiPercentage && strategy.roiPercentage >= 0 ? 'text-green-500' : 'text-red-500'}>
|
||||
{strategy.roiPercentage && strategy.roiPercentage >= 0 ? '+' : ''}{(strategy.roiPercentage || 0).toFixed(2)}%
|
||||
|
||||
Reference in New Issue
Block a user