0.7.33
This commit is contained in:
@@ -52,6 +52,7 @@ pub(crate) use local_pipeline_diagnostics::LocalNonActionablePairDiagnosticSumma
|
||||
pub(crate) use local_pipeline_diagnostics::LocalPairActionabilityDiagnosticSummaryRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalPairDiagnosticSummaryRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalPairGapDiagnosticSampleRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalPairTradingReadinessDiagnosticSummaryRow;
|
||||
pub(crate) use local_pipeline_diagnostics::LocalPipelineDiagnosticCountersRow;
|
||||
|
||||
pub use analysis_signal::AnalysisSignalDto;
|
||||
@@ -79,6 +80,7 @@ pub use local_pipeline_diagnostics::LocalNonActionablePairDiagnosticSummaryDto;
|
||||
pub use local_pipeline_diagnostics::LocalPairActionabilityDiagnosticSummaryDto;
|
||||
pub use local_pipeline_diagnostics::LocalPairDiagnosticSummaryDto;
|
||||
pub use local_pipeline_diagnostics::LocalPairGapDiagnosticSampleDto;
|
||||
pub use local_pipeline_diagnostics::LocalPairTradingReadinessDiagnosticSummaryDto;
|
||||
pub use local_pipeline_diagnostics::LocalPipelineDiagnosticCountersDto;
|
||||
pub use local_pipeline_diagnostics::LocalPipelineDiagnosticSummaryDto;
|
||||
pub use observed_token::ObservedTokenDto;
|
||||
|
||||
@@ -105,6 +105,9 @@ pub struct LocalPipelineDiagnosticSummaryDto {
|
||||
/// Diagnostics grouped by pair materialization/actionability class.
|
||||
pub pair_actionability_summaries:
|
||||
std::vec::Vec<crate::LocalPairActionabilityDiagnosticSummaryDto>,
|
||||
/// Diagnostics grouped by pair trading readiness class.
|
||||
pub pair_trading_readiness_summaries:
|
||||
std::vec::Vec<crate::LocalPairTradingReadinessDiagnosticSummaryDto>,
|
||||
/// Diagnostics grouped by decoded event kind.
|
||||
pub decoded_event_summaries: std::vec::Vec<crate::LocalDecodedEventDiagnosticSummaryDto>,
|
||||
/// Diagnostics grouped by decoded event category, lifecycle kind and actionability.
|
||||
@@ -187,6 +190,12 @@ pub struct LocalPairDiagnosticSummaryDto {
|
||||
pub pair_candle_count: i64,
|
||||
/// Last known price.
|
||||
pub last_price_quote_per_base: std::option::Option<f64>,
|
||||
/// Pair trading-readiness class derived from base/quote orientation.
|
||||
pub pair_trading_readiness: std::string::String,
|
||||
/// Quote asset class used by the readiness classifier.
|
||||
pub quote_asset_class: std::string::String,
|
||||
/// Whether the pair likely requires a router or aggregator before direct bot execution.
|
||||
pub trading_route_required: bool,
|
||||
}
|
||||
|
||||
/// Local pair diagnostics grouped by materialization/actionability class.
|
||||
@@ -210,6 +219,27 @@ pub struct LocalPairActionabilityDiagnosticSummaryDto {
|
||||
pub pair_candle_count: i64,
|
||||
}
|
||||
|
||||
/// Local pair diagnostics grouped by trading readiness class.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct LocalPairTradingReadinessDiagnosticSummaryDto {
|
||||
/// Pair trading-readiness class.
|
||||
pub pair_trading_readiness: std::string::String,
|
||||
/// Quote asset class attached to this readiness group.
|
||||
pub quote_asset_class: std::string::String,
|
||||
/// Whether the group requires a router or aggregator before direct execution.
|
||||
pub trading_route_required: bool,
|
||||
/// Total pairs in this readiness group.
|
||||
pub pair_count: i64,
|
||||
/// Total decoded events attached to pairs in this readiness group.
|
||||
pub decoded_event_count: i64,
|
||||
/// Total decoded trade candidates attached to pairs in this readiness group.
|
||||
pub decoded_trade_candidate_count: i64,
|
||||
/// Total persisted trade events attached to pairs in this readiness group.
|
||||
pub trade_event_count: i64,
|
||||
/// Total persisted candle buckets attached to pairs in this readiness group.
|
||||
pub pair_candle_count: i64,
|
||||
}
|
||||
|
||||
/// Local decoded-event diagnostics summary.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct LocalDecodedEventDiagnosticSummaryDto {
|
||||
@@ -464,6 +494,9 @@ pub(crate) struct LocalPairDiagnosticSummaryRow {
|
||||
pub(crate) invalid_trade_event_count: i64,
|
||||
pub(crate) pair_candle_count: i64,
|
||||
pub(crate) last_price_quote_per_base: std::option::Option<f64>,
|
||||
pub(crate) pair_trading_readiness: std::string::String,
|
||||
pub(crate) quote_asset_class: std::string::String,
|
||||
pub(crate) trading_route_required: i64,
|
||||
}
|
||||
|
||||
/// SQL row for local pair actionability diagnostics.
|
||||
@@ -479,6 +512,19 @@ pub(crate) struct LocalPairActionabilityDiagnosticSummaryRow {
|
||||
pub(crate) pair_candle_count: i64,
|
||||
}
|
||||
|
||||
/// SQL row for local pair trading-readiness diagnostics.
|
||||
#[derive(Debug, Clone, sqlx::FromRow)]
|
||||
pub(crate) struct LocalPairTradingReadinessDiagnosticSummaryRow {
|
||||
pub(crate) pair_trading_readiness: std::string::String,
|
||||
pub(crate) quote_asset_class: std::string::String,
|
||||
pub(crate) trading_route_required: i64,
|
||||
pub(crate) pair_count: i64,
|
||||
pub(crate) decoded_event_count: i64,
|
||||
pub(crate) decoded_trade_candidate_count: i64,
|
||||
pub(crate) trade_event_count: i64,
|
||||
pub(crate) pair_candle_count: i64,
|
||||
}
|
||||
|
||||
/// SQL row for local decoded-event diagnostics.
|
||||
#[derive(Debug, Clone, sqlx::FromRow)]
|
||||
pub(crate) struct LocalDecodedEventDiagnosticSummaryRow {
|
||||
|
||||
@@ -90,6 +90,7 @@ pub use local_pipeline_diagnostics::query_local_multi_trade_signature_pair_diagn
|
||||
pub use local_pipeline_diagnostics::query_local_non_actionable_pair_diagnostic_list_summaries;
|
||||
pub use local_pipeline_diagnostics::query_local_pair_actionability_diagnostic_list_summaries;
|
||||
pub use local_pipeline_diagnostics::query_local_pair_diagnostic_list_summaries;
|
||||
pub use local_pipeline_diagnostics::query_local_pair_trading_readiness_diagnostic_list_summaries;
|
||||
pub use local_pipeline_diagnostics::query_local_pair_without_candle_diagnostic_list_samples;
|
||||
pub use local_pipeline_diagnostics::query_local_pair_without_trade_diagnostic_list_samples;
|
||||
pub use local_pipeline_diagnostics::query_local_pipeline_diagnostic_get_counters;
|
||||
|
||||
@@ -555,7 +555,56 @@ SELECT
|
||||
WHERE te_last.pair_id = pair.id
|
||||
ORDER BY te_last.id DESC
|
||||
LIMIT 1
|
||||
) AS last_price_quote_per_base
|
||||
) AS last_price_quote_per_base,
|
||||
CASE
|
||||
WHEN COUNT(DISTINCT te.id) = 0 THEN 'non_trade_materialized'
|
||||
WHEN quote_token.mint = 'So11111111111111111111111111111111111111112' THEN 'direct_wsol_quote'
|
||||
WHEN quote_token.mint IN (
|
||||
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||
'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
||||
'USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB',
|
||||
'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD'
|
||||
) THEN 'direct_stable_quote'
|
||||
WHEN base_token.mint = 'So11111111111111111111111111111111111111112' THEN 'inverse_wsol_base'
|
||||
WHEN base_token.mint IN (
|
||||
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||
'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
||||
'USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB',
|
||||
'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD'
|
||||
) THEN 'inverse_stable_base'
|
||||
WHEN quote_token.mint IS NULL OR quote_token.mint = '' THEN 'unknown_quote'
|
||||
ELSE 'cross_quote_requires_router'
|
||||
END AS pair_trading_readiness,
|
||||
CASE
|
||||
WHEN quote_token.mint = 'So11111111111111111111111111111111111111112' THEN 'wsol'
|
||||
WHEN quote_token.mint IN (
|
||||
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||
'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
||||
'USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB',
|
||||
'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD'
|
||||
) THEN 'stable'
|
||||
WHEN quote_token.mint IS NULL OR quote_token.mint = '' THEN 'unknown'
|
||||
ELSE 'other'
|
||||
END AS quote_asset_class,
|
||||
CASE
|
||||
WHEN COUNT(DISTINCT te.id) = 0 THEN 0
|
||||
WHEN quote_token.mint IS NULL OR quote_token.mint = '' THEN 1
|
||||
WHEN quote_token.mint = 'So11111111111111111111111111111111111111112' THEN 0
|
||||
WHEN quote_token.mint IN (
|
||||
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||
'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
||||
'USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB',
|
||||
'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD'
|
||||
) THEN 0
|
||||
WHEN base_token.mint = 'So11111111111111111111111111111111111111112' THEN 0
|
||||
WHEN base_token.mint IN (
|
||||
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||
'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
||||
'USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB',
|
||||
'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD'
|
||||
) THEN 0
|
||||
ELSE 1
|
||||
END AS trading_route_required
|
||||
FROM k_sol_pairs pair
|
||||
JOIN k_sol_pools p ON p.id = pair.pool_id
|
||||
JOIN k_sol_dexes d ON d.id = p.dex_id
|
||||
@@ -605,6 +654,9 @@ ORDER BY pair.id
|
||||
invalid_trade_event_count: row.invalid_trade_event_count,
|
||||
pair_candle_count: row.pair_candle_count,
|
||||
last_price_quote_per_base: row.last_price_quote_per_base,
|
||||
pair_trading_readiness: row.pair_trading_readiness,
|
||||
quote_asset_class: row.quote_asset_class,
|
||||
trading_route_required: row.trading_route_required != 0,
|
||||
});
|
||||
}
|
||||
return Ok(summaries);
|
||||
@@ -716,6 +768,146 @@ ORDER BY
|
||||
return Ok(summaries);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Lists local pair trading-readiness summaries.
|
||||
pub async fn query_local_pair_trading_readiness_diagnostic_list_summaries(
|
||||
database: &crate::Database,
|
||||
) -> Result<std::vec::Vec<crate::LocalPairTradingReadinessDiagnosticSummaryDto>, crate::Error> {
|
||||
match database.connection() {
|
||||
crate::DatabaseConnection::Sqlite(pool) => {
|
||||
let rows_result = sqlx::query_as::<
|
||||
sqlx::Sqlite,
|
||||
crate::db::dtos::LocalPairTradingReadinessDiagnosticSummaryRow,
|
||||
>(
|
||||
r#"
|
||||
WITH pair_state AS (
|
||||
SELECT
|
||||
pair.id AS pair_id,
|
||||
base_token.mint AS base_mint,
|
||||
quote_token.mint AS quote_mint,
|
||||
COUNT(DISTINCT dde.id) AS decoded_event_count,
|
||||
COUNT(DISTINCT CASE WHEN json_extract(dde.payload_json, '$.tradeCandidate') = 1 THEN dde.id END) AS decoded_trade_candidate_count,
|
||||
COUNT(DISTINCT te.id) AS trade_event_count,
|
||||
COUNT(DISTINCT pc.bucket_start_unix || ':' || pc.timeframe_seconds) AS pair_candle_count
|
||||
FROM k_sol_pairs pair
|
||||
JOIN k_sol_pools p ON p.id = pair.pool_id
|
||||
JOIN k_sol_tokens base_token ON base_token.id = pair.base_token_id
|
||||
JOIN k_sol_tokens quote_token ON quote_token.id = pair.quote_token_id
|
||||
LEFT JOIN k_sol_dex_decoded_events dde ON dde.pool_account = p.address
|
||||
LEFT JOIN k_sol_trade_events te ON te.pair_id = pair.id
|
||||
LEFT JOIN k_sol_pair_candles pc ON pc.pair_id = pair.id
|
||||
GROUP BY pair.id, base_token.mint, quote_token.mint
|
||||
), classified AS (
|
||||
SELECT
|
||||
CASE
|
||||
WHEN trade_event_count = 0 THEN 'non_trade_materialized'
|
||||
WHEN quote_mint = 'So11111111111111111111111111111111111111112' THEN 'direct_wsol_quote'
|
||||
WHEN quote_mint IN (
|
||||
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||
'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
||||
'USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB',
|
||||
'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD'
|
||||
) THEN 'direct_stable_quote'
|
||||
WHEN base_mint = 'So11111111111111111111111111111111111111112' THEN 'inverse_wsol_base'
|
||||
WHEN base_mint IN (
|
||||
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||
'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
||||
'USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB',
|
||||
'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD'
|
||||
) THEN 'inverse_stable_base'
|
||||
WHEN quote_mint IS NULL OR quote_mint = '' THEN 'unknown_quote'
|
||||
ELSE 'cross_quote_requires_router'
|
||||
END AS pair_trading_readiness,
|
||||
CASE
|
||||
WHEN quote_mint = 'So11111111111111111111111111111111111111112' THEN 'wsol'
|
||||
WHEN quote_mint IN (
|
||||
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||
'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
||||
'USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB',
|
||||
'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD'
|
||||
) THEN 'stable'
|
||||
WHEN quote_mint IS NULL OR quote_mint = '' THEN 'unknown'
|
||||
ELSE 'other'
|
||||
END AS quote_asset_class,
|
||||
CASE
|
||||
WHEN trade_event_count = 0 THEN 0
|
||||
WHEN quote_mint IS NULL OR quote_mint = '' THEN 1
|
||||
WHEN quote_mint = 'So11111111111111111111111111111111111111112' THEN 0
|
||||
WHEN quote_mint IN (
|
||||
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||
'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
||||
'USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB',
|
||||
'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD'
|
||||
) THEN 0
|
||||
WHEN base_mint = 'So11111111111111111111111111111111111111112' THEN 0
|
||||
WHEN base_mint IN (
|
||||
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||
'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
||||
'USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB',
|
||||
'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD'
|
||||
) THEN 0
|
||||
ELSE 1
|
||||
END AS trading_route_required,
|
||||
pair_id,
|
||||
decoded_event_count,
|
||||
decoded_trade_candidate_count,
|
||||
trade_event_count,
|
||||
pair_candle_count
|
||||
FROM pair_state
|
||||
)
|
||||
SELECT
|
||||
pair_trading_readiness AS pair_trading_readiness,
|
||||
quote_asset_class AS quote_asset_class,
|
||||
trading_route_required AS trading_route_required,
|
||||
COUNT(pair_id) AS pair_count,
|
||||
SUM(decoded_event_count) AS decoded_event_count,
|
||||
SUM(decoded_trade_candidate_count) AS decoded_trade_candidate_count,
|
||||
SUM(trade_event_count) AS trade_event_count,
|
||||
SUM(pair_candle_count) AS pair_candle_count
|
||||
FROM classified
|
||||
GROUP BY pair_trading_readiness, quote_asset_class, trading_route_required
|
||||
ORDER BY
|
||||
CASE pair_trading_readiness
|
||||
WHEN 'direct_wsol_quote' THEN 1
|
||||
WHEN 'direct_stable_quote' THEN 2
|
||||
WHEN 'inverse_wsol_base' THEN 3
|
||||
WHEN 'inverse_stable_base' THEN 4
|
||||
WHEN 'cross_quote_requires_router' THEN 5
|
||||
WHEN 'unknown_quote' THEN 6
|
||||
ELSE 7
|
||||
END,
|
||||
pair_trading_readiness,
|
||||
quote_asset_class
|
||||
"#,
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await;
|
||||
let rows = match rows_result {
|
||||
Ok(rows) => rows,
|
||||
Err(error) => {
|
||||
return Err(crate::Error::Db(format!(
|
||||
"cannot list local pair trading readiness diagnostic summaries on sqlite: {}",
|
||||
error
|
||||
)));
|
||||
},
|
||||
};
|
||||
let mut summaries = std::vec::Vec::new();
|
||||
for row in rows {
|
||||
summaries.push(crate::LocalPairTradingReadinessDiagnosticSummaryDto {
|
||||
pair_trading_readiness: row.pair_trading_readiness,
|
||||
quote_asset_class: row.quote_asset_class,
|
||||
trading_route_required: row.trading_route_required != 0,
|
||||
pair_count: row.pair_count,
|
||||
decoded_event_count: row.decoded_event_count,
|
||||
decoded_trade_candidate_count: row.decoded_trade_candidate_count,
|
||||
trade_event_count: row.trade_event_count,
|
||||
pair_candle_count: row.pair_candle_count,
|
||||
});
|
||||
}
|
||||
return Ok(summaries);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Lists local decoded-event diagnostic summaries.
|
||||
|
||||
Reference in New Issue
Block a user