update position count to open position only
This commit is contained in:
@@ -159,7 +159,9 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
|
|||||||
|
|
||||||
_state.State.PositionCountByAsset[ticker]++;
|
_state.State.PositionCountByAsset[ticker]++;
|
||||||
|
|
||||||
// Position count breakdown by direction - update state directly
|
// Position count breakdown by direction - only count finished positions
|
||||||
|
if (!position.IsFinished())
|
||||||
|
{
|
||||||
if (!_state.State.PositionCountByDirection.ContainsKey(direction))
|
if (!_state.State.PositionCountByDirection.ContainsKey(direction))
|
||||||
{
|
{
|
||||||
_state.State.PositionCountByDirection[direction] = 0;
|
_state.State.PositionCountByDirection[direction] = 0;
|
||||||
@@ -167,6 +169,7 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
|
|||||||
|
|
||||||
_state.State.PositionCountByDirection[direction]++;
|
_state.State.PositionCountByDirection[direction]++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_state.State.TotalPlatformVolume = totalVolume;
|
_state.State.TotalPlatformVolume = totalVolume;
|
||||||
_state.State.TotalPlatformFees = totalFees;
|
_state.State.TotalPlatformFees = totalFees;
|
||||||
|
|||||||
@@ -16,12 +16,6 @@ interface AgentData {
|
|||||||
positions: Position[]
|
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 }) {
|
function AgentSearch({ index }: { index: number }) {
|
||||||
const { apiUrl } = useApiUrlStore()
|
const { apiUrl } = useApiUrlStore()
|
||||||
@@ -29,7 +23,6 @@ function AgentSearch({ index }: { index: number }) {
|
|||||||
const [agentData, setAgentData] = useState<AgentData | null>(null)
|
const [agentData, setAgentData] = useState<AgentData | null>(null)
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [error, setError] = useState<string | null>(null)
|
const [error, setError] = useState<string | null>(null)
|
||||||
const [selectedFilter, setSelectedFilter] = useState('Total')
|
|
||||||
|
|
||||||
const searchAgent = async () => {
|
const searchAgent = async () => {
|
||||||
if (!agentName.trim()) return
|
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
|
// Calculate current total balance
|
||||||
const getCurrentBalance = () => {
|
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
|
// Calculate summary statistics from strategies
|
||||||
const calculateSummary = () => {
|
const calculateSummary = () => {
|
||||||
if (!agentData?.strategies.length) return null
|
if (!agentData?.strategies.length) return null
|
||||||
|
|
||||||
const totalPnL = agentData.strategies.reduce((sum, strategy) => sum + (strategy.pnL || 0), 0)
|
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 totalVolume = agentData.strategies.reduce((sum, strategy) => sum + (strategy.totalVolumeTraded || 0), 0)
|
||||||
const totalWins = agentData.strategies.reduce((sum, strategy) => sum + (strategy.wins || 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)
|
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
|
? agentData.strategies.reduce((sum, strategy) => sum + (strategy.winRate || 0), 0) / agentData.strategies.length
|
||||||
: 0
|
: 0
|
||||||
|
|
||||||
// Calculate filtered PnL based on selected time period
|
|
||||||
const filteredPnL = calculateFilteredPnL()
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
totalPnL,
|
totalPnL,
|
||||||
filteredPnL,
|
totalNetPnL,
|
||||||
totalVolume,
|
totalVolume,
|
||||||
totalWins,
|
totalWins,
|
||||||
totalLosses,
|
totalLosses,
|
||||||
@@ -252,18 +216,6 @@ function AgentSearch({ index }: { index: number }) {
|
|||||||
|
|
||||||
{summary && (
|
{summary && (
|
||||||
<GridTile title={`Agent Stats - ${agentName}`}>
|
<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 */}
|
{/* Current Balance Display */}
|
||||||
{currentBalance && (
|
{currentBalance && (
|
||||||
@@ -303,21 +255,6 @@ function AgentSearch({ index }: { index: number }) {
|
|||||||
</div>
|
</div>
|
||||||
</Card>
|
</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">
|
<Card name="Active Strategies">
|
||||||
<div className="stat">
|
<div className="stat">
|
||||||
@@ -331,8 +268,8 @@ function AgentSearch({ index }: { index: number }) {
|
|||||||
<div className="stat">
|
<div className="stat">
|
||||||
<div className="stat-title text-xs">ROI</div>
|
<div className="stat-title text-xs">ROI</div>
|
||||||
<div className="stat-value text-lg">
|
<div className="stat-value text-lg">
|
||||||
<span className={summary.totalPnL >= 0 ? 'text-green-500' : 'text-red-500'}>
|
<span className={summary.totalNetPnL >= 0 ? 'text-green-500' : 'text-red-500'}>
|
||||||
{((summary.totalPnL / (summary.totalVolume || 1)) * 100).toFixed(2)}%
|
{((summary.totalNetPnL / (summary.totalVolume || 1)) * 100).toFixed(2)}%
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="stat-desc text-xs">Return on Investment</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 })}
|
{summary.totalPnL >= 0 ? '+' : ''}${summary.totalPnL.toLocaleString(undefined, { maximumFractionDigits: 2 })}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
@@ -361,7 +312,7 @@ function AgentSearch({ index }: { index: number }) {
|
|||||||
<span>Name</span>
|
<span>Name</span>
|
||||||
<span>Ticker</span>
|
<span>Ticker</span>
|
||||||
<span>Status</span>
|
<span>Status</span>
|
||||||
<span>PnL</span>
|
<span>Net PnL</span>
|
||||||
<span>ROI</span>
|
<span>ROI</span>
|
||||||
<span>Runtime</span>
|
<span>Runtime</span>
|
||||||
<span>Avg Winrate</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'}`}>
|
<span className={`badge ${strategy.state == BotStatus.Running ? 'badge-success' : 'badge-warning'}`}>
|
||||||
{strategy.state}
|
{strategy.state}
|
||||||
</span>
|
</span>
|
||||||
<span className={strategy.pnL && strategy.pnL >= 0 ? 'text-green-500' : 'text-red-500'}>
|
<span className={strategy.netPnL && strategy.netPnL >= 0 ? 'text-green-500' : 'text-red-500'}>
|
||||||
{strategy.pnL && strategy.pnL >= 0 ? '+' : ''}${(strategy.pnL || 0).toFixed(2)}
|
{strategy.netPnL && strategy.netPnL >= 0 ? '+' : ''}${(strategy.netPnL || 0).toFixed(2)}
|
||||||
</span>
|
</span>
|
||||||
<span className={strategy.roiPercentage && strategy.roiPercentage >= 0 ? 'text-green-500' : 'text-red-500'}>
|
<span className={strategy.roiPercentage && strategy.roiPercentage >= 0 ? 'text-green-500' : 'text-red-500'}>
|
||||||
{strategy.roiPercentage && strategy.roiPercentage >= 0 ? '+' : ''}{(strategy.roiPercentage || 0).toFixed(2)}%
|
{strategy.roiPercentage && strategy.roiPercentage >= 0 ? '+' : ''}{(strategy.roiPercentage || 0).toFixed(2)}%
|
||||||
|
|||||||
Reference in New Issue
Block a user