feat: bandar and broker totals for one investor side

IPOT's investor filter splits each broker row by client domicile, but its
footer then gives only that side's buying (BBCA 2026-10-16: foreign 1.7 T,
domestic 4.9 T of 6.6 T). The foreign net gives the selling on all boards:
foreign 1.7 + 2.3 = 4.0 T (IDX: about 3.95 T regular), domestic
4.9 - 2.3 = 2.6 T.

- BrokerSummary gains buy_value and sell_value: the total for all
  investors, the footer and the derived selling for one side (selling is
  null with a board filter, where the net covers other boards).
- Bandar weighs the top N buyers' share of the value bought against the
  top N sellers' share of the value sold, so `--investor foreign|domestic`
  reads that side alone; for all investors the readings are unchanged.
  One side on one board is refused, as there is no selling to weigh.
- Tables print what the side bought and sold; fixtures for foreign and
  domestic on all boards were recorded from IPOT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3syn2fN2LNo5pvTSqc6eh
This commit is contained in:
hermes 2026-10-18 06:08:02 +00:00
commit 5f64319157
23 changed files with 717 additions and 86 deletions

View file

@ -2,10 +2,13 @@
//! brokers than selling? No network; see docs/ARCHITECTURE.md.
//!
//! The summary lists the top 10 buyers and the top 10 sellers by gross lots.
//! For N in 1, 3, 5 and 10 the top N buyers' value is set against the top N
//! sellers' value, as a share of the value traded:
//! For N in 1, 3, 5 and 10 the top N buyers' share of the value bought is set
//! against the top N sellers' share of the value sold. For all investors both
//! are the value traded, so this is the top N's buy value less their sell
//! value as a share of it; for one investor side (foreign or domestic), each
//! is that side's own buying or selling.
//!
//! | top-N buy - sell value, % of value | signal |
//! | top-N buy share - sell share, % | signal |
//! |------------------------------------|--------------------|
//! | >= +15 | `big_accumulation` |
//! | +5 to +15 | `accumulation` |
@ -79,11 +82,12 @@ pub struct BandarTier {
pub sell_value: Option<i64>,
/// `buy_value - sell_value`, whole IDR.
pub imbalance_value: Option<i64>,
/// `buy_share_bps - sell_share_bps`, computed exactly: for all investors,
/// `imbalance_value` in basis points of the value traded.
pub imbalance_bps: Option<i64>,
/// The top N buyers' share of the value traded, basis points.
/// The top N buyers' share of the value bought, basis points.
pub buy_share_bps: Option<i64>,
/// The top N sellers' share of the value traded, basis points.
/// The top N sellers' share of the value sold, basis points.
pub sell_share_bps: Option<i64>,
/// Volume-weighted average price the top N buyers paid, whole IDR.
pub buy_average: Option<i64>,
@ -109,8 +113,12 @@ pub struct BandarReport {
/// The headline tier's imbalance, basis points of value traded.
pub imbalance_bps: Option<i64>,
pub tiers: Vec<BandarTier>,
/// Value traded over the range, whole IDR.
/// Value traded over the range, whole IDR; `None` for one investor side.
pub total_value: Option<i64>,
/// Value the selected investors bought, whole IDR.
pub buy_value: Option<i64>,
/// Value the selected investors sold, whole IDR.
pub sell_value: Option<i64>,
/// Average traded price, whole IDR.
pub average_price: Option<i64>,
/// Foreign net value, whole IDR; `None` for a filtered summary.
@ -175,15 +183,28 @@ pub fn bandar_tier(summary: &BrokerSummary, top: u8) -> BandarTier {
let imbalance_value = buy_value
.zip(sell_value)
.and_then(|(buy, sell)| buy.checked_sub(sell));
let imbalance_bps = imbalance_value.and_then(|value| bps(value, summary.total_value));
let imbalance_bps = match (buy_value, sell_value, summary.buy_value, summary.sell_value) {
(Some(buy), Some(sell), Some(bought), Some(sold)) if bought > 0 && sold > 0 => {
// buy/bought - sell/sold over one denominator, so equal totals
// give exactly (buy - sell) / total.
let (buy, sell, bought, sold) = (
i128::from(buy),
i128::from(sell),
i128::from(bought),
i128::from(sold),
);
i64::try_from((buy * sold - sell * bought) * 10_000 / (bought * sold)).ok()
}
_ => None,
};
BandarTier {
top,
buy_value,
sell_value,
imbalance_value,
imbalance_bps,
buy_share_bps: buy_value.and_then(|value| bps(value, summary.total_value)),
sell_share_bps: sell_value.and_then(|value| bps(value, summary.total_value)),
buy_share_bps: buy_value.and_then(|value| bps(value, summary.buy_value)),
sell_share_bps: sell_value.and_then(|value| bps(value, summary.sell_value)),
buy_average: vwap(buyers),
sell_average: vwap(sellers),
signal: imbalance_bps.map(BandarSignal::from_imbalance_bps),
@ -223,6 +244,8 @@ pub fn analyze_bandar(summary: &BrokerSummary, top: u8) -> BandarReport {
imbalance_bps: headline.imbalance_bps,
tiers,
total_value: summary.total_value,
buy_value: summary.buy_value,
sell_value: summary.sell_value,
average_price: summary.average_price,
foreign_net_value: summary.foreign_net_value,
foreign_net_bps: summary
@ -262,6 +285,8 @@ mod tests {
total_value: Some(total),
total_lots: None,
average_price: None,
buy_value: Some(total),
sell_value: Some(total),
foreign_net_value: Some(-total / 10),
rounded: false,
}
@ -359,6 +384,36 @@ mod tests {
);
}
#[test]
fn test_bandar_tier_weighs_one_side_against_its_own_buying_and_selling() {
// Foreign investors bought 1,000 and sold 4,000: the top buyer took
// half of the buying, the top seller a quarter of the selling.
let mut s = summary(
vec![flow("AA", Some(500), 100)],
vec![flow("BB", Some(1_000), 100)],
0,
);
s.investor = BrokerInvestor::Foreign;
s.total_value = None;
s.buy_value = Some(1_000);
s.sell_value = Some(4_000);
s.foreign_net_value = Some(-3_000);
let report = analyze_bandar(&s, 1);
let tier = &report.tiers[0];
assert_eq!(
(tier.buy_share_bps, tier.sell_share_bps),
(Some(5000), Some(2500))
);
assert_eq!(tier.imbalance_bps, Some(2500));
assert_eq!(tier.imbalance_value, Some(-500));
assert_eq!(report.signal, Some(BandarSignal::BigAccumulation));
assert_eq!(report.foreign_net_bps, None, "no total to weigh it against");
// Without the selling total (one side on one board) there is no reading.
s.sell_value = None;
assert_eq!(analyze_bandar(&s, 1).signal, None);
}
#[test]
fn test_analyze_bandar_never_counts_a_missing_figure_as_zero() {
let s = summary(

View file

@ -31,14 +31,15 @@ pub struct Comparison {
pub failures: Vec<(String, IdxError)>,
}
/// Readings weigh brokers against the value traded, which the source does
/// not total for one investor side.
fn check_investor(investor: BrokerInvestor) -> Result<(), IdxError> {
if investor == BrokerInvestor::All {
/// One investor side is weighed against its own selling, which the source
/// gives only across all boards.
fn check_scope(investor: BrokerInvestor, board: BrokerBoard) -> Result<(), IdxError> {
if investor == BrokerInvestor::All || board == BrokerBoard::All {
Ok(())
} else {
Err(IdxError::InvalidInput(format!(
"bandar needs --investor all: the broker summary has no total for {} investors alone",
"bandar for {} investors needs --board all: the broker summary gives one side's \
selling only across all boards",
investor.as_str()
)))
}
@ -70,7 +71,7 @@ impl Analysis<'_> {
policy: CachePolicy,
) -> Result<Fetched<BandarReport>, IdxError> {
let top = check_top(query.top)?;
check_investor(query.investor)?;
check_scope(query.investor, query.board)?;
let summary =
self.idx
.broker()
@ -87,7 +88,7 @@ impl Analysis<'_> {
policy: CachePolicy,
) -> Result<BandarScreen, IdxError> {
check_top(query.top)?;
check_investor(query.investor)?;
check_scope(query.investor, query.board)?;
let mut reports = Vec::new();
let mut failures = Vec::new();
for symbol in symbols {

View file

@ -155,13 +155,27 @@ impl Broker<'_> {
}
}
/// The public summary of one parsed page. With one investor side selected,
/// the page's footer covers only part of the trades the lists show (foreign
/// buying, not foreign selling), so no totals are given; `F. NVal` ignores
/// both filters, so the foreign net goes with any filter.
/// The public summary of one parsed page.
///
/// With one investor side selected, the page's footer (`T. Val`) covers only
/// that side's buying, so it is the side's `buy_value`, not a total of the
/// trades the lists show. `F. NVal`, the foreign net, ignores both filters:
/// on all boards it gives the side's selling (foreign buying less the foreign
/// net; domestic buying plus it), and with a board filter it is dropped.
fn summary_from_raw(symbol: &str, query: &BrokerQuery, raw: BrokerSummaryRaw) -> BrokerSummary {
let one_side = query.investor != BrokerInvestor::All;
let filtered = one_side || query.board != BrokerBoard::All;
let all_boards = query.board == BrokerBoard::All;
let foreign_net = raw.foreign_net_value.filter(|_| all_boards);
let buy_value = raw.total_value;
let sell_value = match query.investor {
BrokerInvestor::All => raw.total_value,
BrokerInvestor::Foreign => buy_value
.zip(foreign_net)
.and_then(|(buy, net)| buy.checked_sub(net)),
BrokerInvestor::Domestic => buy_value
.zip(foreign_net)
.and_then(|(buy, net)| buy.checked_add(net)),
};
let mut summary = BrokerSummary {
symbol: symbol.to_string(),
from: raw.from.unwrap_or(query.from),
@ -173,7 +187,9 @@ fn summary_from_raw(symbol: &str, query: &BrokerQuery, raw: BrokerSummaryRaw) ->
total_value: raw.total_value.filter(|_| !one_side),
total_lots: raw.total_lots.filter(|_| !one_side),
average_price: raw.average_price.filter(|_| !one_side),
foreign_net_value: raw.foreign_net_value.filter(|_| !filtered),
buy_value,
sell_value,
foreign_net_value: foreign_net,
rounded: raw.rounded,
};
for flow in summary.buyers.iter_mut().chain(summary.sellers.iter_mut()) {
@ -228,7 +244,7 @@ mod tests {
}
#[test]
fn test_summary_from_raw_drops_totals_that_do_not_cover_the_lists() {
fn test_summary_from_raw_gives_each_side_its_own_totals() {
let day = date(2026, 10, 16);
let read = |name: &str| {
let html = std::fs::read_to_string(format!("tests/fixtures/{name}")).unwrap();
@ -243,26 +259,68 @@ mod tests {
assert_eq!(all.foreign_net_value, Some(-2_300_000_000_000));
assert_eq!(all.sellers[0].name.as_deref(), Some("MANDIRI SEKURITAS"));
// Foreign, regular board: the footer's 1.6 T is less than the 2.0 T
// its top seller alone sold.
let foreign = BrokerQuery {
investor: BrokerInvestor::Foreign,
board: BrokerBoard::Regular,
..query(day, day)
assert_eq!(
(all.buy_value, all.sell_value),
(all.total_value, all.total_value)
);
// Foreign on all boards: the footer's 1.7 T is foreign buying; with
// the -2.3 T foreign net, foreign selling is 4.0 T (IDX: about
// 3.95 T). Domestic buying 4.9 T makes up the rest of 6.6 T, and its
// selling is 2.6 T.
let side = |investor, board, name: &str| {
let query = BrokerQuery {
investor,
board,
..query(day, day)
};
summary_from_raw("BBCA.JK", &query, read(name))
};
let foreign = side(
BrokerInvestor::Foreign,
BrokerBoard::All,
"ipot_brokersummary_bbca_20261016_foreign_all.html",
);
assert_eq!(
(foreign.buy_value, foreign.sell_value),
(Some(1_700_000_000_000), Some(4_000_000_000_000))
);
assert_eq!(foreign.total_value, None);
assert_eq!(foreign.foreign_net_value, Some(-2_300_000_000_000));
let domestic = side(
BrokerInvestor::Domestic,
BrokerBoard::All,
"ipot_brokersummary_bbca_20261016_domestic_all.html",
);
assert_eq!(
(domestic.buy_value, domestic.sell_value),
(Some(4_900_000_000_000), Some(2_600_000_000_000))
);
// Foreign, regular board: the footer's 1.6 T is regular foreign
// buying, less than the 2.0 T its top seller alone sold, and the net
// covers all boards, so selling cannot be derived.
let raw = read("ipot_brokersummary_bbca_20261016_foreign_regular.html");
assert!(raw.total_value < raw.sellers[0].value);
let filtered = summary_from_raw("BBCA.JK", &foreign, raw);
let regular = side(
BrokerInvestor::Foreign,
BrokerBoard::Regular,
"ipot_brokersummary_bbca_20261016_foreign_regular.html",
);
assert_eq!(
(
filtered.total_value,
filtered.total_lots,
filtered.average_price
regular.total_value,
regular.total_lots,
regular.average_price
),
(None, None, None)
);
assert_eq!(filtered.foreign_net_value, None);
assert_eq!(filtered.sellers[0].value, Some(2_000_000_000_000));
assert_eq!(
(regular.buy_value, regular.sell_value),
(Some(1_600_000_000_000), None)
);
assert_eq!(regular.foreign_net_value, None);
assert_eq!(regular.sellers[0].value, Some(2_000_000_000_000));
}
#[test]

View file

@ -215,9 +215,18 @@ pub struct BrokerSummary {
/// Average traded price, whole IDR; `None` when nothing traded, or as
/// for `total_value`.
pub average_price: Option<i64>,
/// Value the selected investors bought over the range on the selected
/// board, whole IDR: `total_value` for all investors, and for one side
/// the source's footer, which then covers that side's buying.
pub buy_value: Option<i64>,
/// Value the selected investors sold, whole IDR: `total_value` for all
/// investors; for one side on all boards, its buying less its net
/// (foreign net, or its negative for domestic investors). `None` for one
/// side on one board, where the source gives no net to derive it from.
pub sell_value: Option<i64>,
/// Foreign buy value minus foreign sell value over the range, whole IDR,
/// across all boards. The source does not apply the investor or board
/// filter to it, so it is `None` for a filtered summary.
/// across all boards. The source does not apply the board filter to it,
/// so it is `None` for a summary of one board.
pub foreign_net_value: Option<i64>,
/// True when the source abbreviated at least one figure (`1.6 M` lots,
/// `841.2 B` IDR), so those figures carry only one decimal of precision.

View file

@ -0,0 +1,181 @@
<div id="modContentBrokerSum"></div>
<!--DATA BROKER SUMMARY-->
<div class="pa5">
<div class="row mincol-3">
<div class="col col-xs-5 col-sm-3">
<input class="form-control input-xs text-center" id="startDateBrokerSummary" name="startDate" placeholder="DD Month YYYY" value="10/16/2026" type="text">
</div>
<div class="col col-xs-5 col-sm-3">
<input class="form-control input-xs text-center" id="endDateBrokerSummary" name="endDate" placeholder="DD Month YYYY" value="10/16/2026" type="text">
</div>
<div class="mt15 visible-xs">&nbsp;</div>
<div class="col col-xs-5 col-sm-3">
<select class="form-control input-xs" id="FDBrokerSummary">
<option value="all">All</option>
<option value="F" >Foreign</option>
<option value="D" selected>Domestic</option>
</select>
</div>
<div class="col col-xs-5 col-sm-2">
<select class="form-control input-xs" id="boardBrokerSummary">
<option value="all">All Trade</option>
<option value="RG" >Regular</option>
<option value="TN" >Tunai</option>
<option value="NG" >Nego</option>
</select>
</div>
<div class="col col-xs-2 col-sm-1">
<button type="button" class="btn btn-default btn-block btn-xs-input" onClick="quickinfo_brokersummary($('#stockPageCode').val()!==undefined?$('#stockPageCode').val():$('#stockInfoCode').val(),$('#startDateBrokerSummary').val(),$('#endDateBrokerSummary').val(),$('#FDBrokerSummary').val(),$('#boardBrokerSummary').val());">GO</button>
</div>
</div>
</div>
<div class="table-responsive">
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="table table-summary table-hover noborder nm">
<thead>
<tr>
<th align="center">Buyer</th>
<th align="right">B.Lot</th>
<th align="right">B.Val</th>
<th align="right">B.Avg</th>
<th align="center">#</th>
<th align="center">Seller</th>
<th align="right">S.Lot</th>
<th align="right">S.Val</th>
<th align="right">S.Avg</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center"><span class="text-local">MG</span></td>
<td align="right"><span class="text-up">1.6 M</span></td>
<td align="right"><span class="text-up">841.2 B</span></td>
<td align="right"><span class="text-up">5,191 </span></td>
<td align="center">1</td>
<td align="center"><span class="text-local">MG</span></td>
<td align="right"><span class="text-down">1.5 M</span></td>
<td align="right"><span class="text-down">799.4 B</span></td>
<td align="right"><span class="text-down">5,238 </span></td>
</tr>
<tr>
<td align="center"><span class="text-local">XL</span></td>
<td align="right"><span class="text-up">1.1 M</span></td>
<td align="right"><span class="text-up">595.0 B</span></td>
<td align="right"><span class="text-up">5,229 </span></td>
<td align="center">2</td>
<td align="center"><span class="text-local">BB</span></td>
<td align="right"><span class="text-down">577,558 </span></td>
<td align="right"><span class="text-down">300.5 B</span></td>
<td align="right"><span class="text-down">5,203 </span></td>
</tr>
<tr>
<td align="center"><span class="text-bumn">CC</span></td>
<td align="right"><span class="text-up">841,738 </span></td>
<td align="right"><span class="text-up">439.2 B</span></td>
<td align="right"><span class="text-up">5,217 </span></td>
<td align="center">3</td>
<td align="center"><span class="text-bumn">CC</span></td>
<td align="right"><span class="text-down">448,606 </span></td>
<td align="right"><span class="text-down">233.8 B</span></td>
<td align="right"><span class="text-down">5,211 </span></td>
</tr>
<tr>
<td align="center"><span class="text-foreign">YP</span></td>
<td align="right"><span class="text-up">824,562 </span></td>
<td align="right"><span class="text-up">430.3 B</span></td>
<td align="right"><span class="text-up">5,218 </span></td>
<td align="center">4</td>
<td align="center"><span class="text-bumn">NI</span></td>
<td align="right"><span class="text-down">356,533 </span></td>
<td align="right"><span class="text-down">185.8 B</span></td>
<td align="right"><span class="text-down">5,212 </span></td>
</tr>
<tr>
<td align="center"><span class="text-local">SQ</span></td>
<td align="right"><span class="text-up">824,521 </span></td>
<td align="right"><span class="text-up">430.5 B</span></td>
<td align="right"><span class="text-up">5,221 </span></td>
<td align="center">5</td>
<td align="center"><span class="text-local">XL</span></td>
<td align="right"><span class="text-down">296,269 </span></td>
<td align="right"><span class="text-down">155.0 B</span></td>
<td align="right"><span class="text-down">5,232 </span></td>
</tr>
<tr>
<td align="center"><span class="text-local">PD</span></td>
<td align="right"><span class="text-up">587,559 </span></td>
<td align="right"><span class="text-up">306.6 B</span></td>
<td align="right"><span class="text-up">5,217 </span></td>
<td align="center">6</td>
<td align="center"><span class="text-foreign">YP</span></td>
<td align="right"><span class="text-down">264,188 </span></td>
<td align="right"><span class="text-down">138.5 B</span></td>
<td align="right"><span class="text-down">5,242 </span></td>
</tr>
<tr>
<td align="center"><span class="text-local">CP</span></td>
<td align="right"><span class="text-up">347,229 </span></td>
<td align="right"><span class="text-up">181.1 B</span></td>
<td align="right"><span class="text-up">5,216 </span></td>
<td align="center">7</td>
<td align="center"><span class="text-local">CP</span></td>
<td align="right"><span class="text-down">188,644 </span></td>
<td align="right"><span class="text-down">98.9 B</span></td>
<td align="right"><span class="text-down">5,245 </span></td>
</tr>
<tr>
<td align="center"><span class="text-local">XC</span></td>
<td align="right"><span class="text-up">336,997 </span></td>
<td align="right"><span class="text-up">176.1 B</span></td>
<td align="right"><span class="text-up">5,226 </span></td>
<td align="center">8</td>
<td align="center"><span class="text-foreign">YU</span></td>
<td align="right"><span class="text-down">166,603 </span></td>
<td align="right"><span class="text-down">86.6 B</span></td>
<td align="right"><span class="text-down">5,201 </span></td>
</tr>
<tr>
<td align="center"><span class="text-foreign">KK</span></td>
<td align="right"><span class="text-up">302,943 </span></td>
<td align="right"><span class="text-up">157.9 B</span></td>
<td align="right"><span class="text-up">5,211 </span></td>
<td align="center">9</td>
<td align="center"><span class="text-local">BQ</span></td>
<td align="right"><span class="text-down">142,119 </span></td>
<td align="right"><span class="text-down">74.7 B</span></td>
<td align="right"><span class="text-down">5,254 </span></td>
</tr>
<tr>
<td align="center"><span class="text-local">BQ</span></td>
<td align="right"><span class="text-up">245,981 </span></td>
<td align="right"><span class="text-up">128.6 B</span></td>
<td align="right"><span class="text-up">5,228 </span></td>
<td align="center">10</td>
<td align="center"><span class="text-foreign">KK</span></td>
<td align="right"><span class="text-down">133,633 </span></td>
<td align="right"><span class="text-down">70.0 B</span></td>
<td align="right"><span class="text-down">5,236 </span></td>
</tr>
</tbody>
<tfoot>
<tr class="bdr-t">
<th colspan="9" align="center">
<div class="text-center pt20 valign-middle" style="height:50px;">
<span class="fsize12 ml5 mr5">T. Val : 4.9 T</span>
<span class="fsize12 ml5 mr5">F. NVal : -2.3 T</span>
<span class="fsize12 ml5 mr5">T.Lot : 9.3 M</span>
<span class="fsize12 ml5 mr5">Avg : 5,216 </span>
</div>
</th>
</tr>
</tfoot>
</table>
</div>
<!-- =======================
======SCRIPT MODULE=========
============================-->
<script src="../../../../module/saham/include/js/data-brokersummary.js"></script>

View file

@ -0,0 +1,181 @@
<div id="modContentBrokerSum"></div>
<!--DATA BROKER SUMMARY-->
<div class="pa5">
<div class="row mincol-3">
<div class="col col-xs-5 col-sm-3">
<input class="form-control input-xs text-center" id="startDateBrokerSummary" name="startDate" placeholder="DD Month YYYY" value="10/16/2026" type="text">
</div>
<div class="col col-xs-5 col-sm-3">
<input class="form-control input-xs text-center" id="endDateBrokerSummary" name="endDate" placeholder="DD Month YYYY" value="10/16/2026" type="text">
</div>
<div class="mt15 visible-xs">&nbsp;</div>
<div class="col col-xs-5 col-sm-3">
<select class="form-control input-xs" id="FDBrokerSummary">
<option value="all">All</option>
<option value="F" selected>Foreign</option>
<option value="D" >Domestic</option>
</select>
</div>
<div class="col col-xs-5 col-sm-2">
<select class="form-control input-xs" id="boardBrokerSummary">
<option value="all">All Trade</option>
<option value="RG" >Regular</option>
<option value="TN" >Tunai</option>
<option value="NG" >Nego</option>
</select>
</div>
<div class="col col-xs-2 col-sm-1">
<button type="button" class="btn btn-default btn-block btn-xs-input" onClick="quickinfo_brokersummary($('#stockPageCode').val()!==undefined?$('#stockPageCode').val():$('#stockInfoCode').val(),$('#startDateBrokerSummary').val(),$('#endDateBrokerSummary').val(),$('#FDBrokerSummary').val(),$('#boardBrokerSummary').val());">GO</button>
</div>
</div>
</div>
<div class="table-responsive">
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="table table-summary table-hover noborder nm">
<thead>
<tr>
<th align="center">Buyer</th>
<th align="right">B.Lot</th>
<th align="right">B.Val</th>
<th align="right">B.Avg</th>
<th align="center">#</th>
<th align="center">Seller</th>
<th align="right">S.Lot</th>
<th align="right">S.Val</th>
<th align="right">S.Avg</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center"><span class="text-foreign">KZ</span></td>
<td align="right"><span class="text-up">1.0 M</span></td>
<td align="right"><span class="text-up">521.3 B</span></td>
<td align="right"><span class="text-up">5,198 </span></td>
<td align="center">1</td>
<td align="center"><span class="text-bumn">CC</span></td>
<td align="right"><span class="text-down">3.9 M</span></td>
<td align="right"><span class="text-down">2.0 T</span></td>
<td align="right"><span class="text-down">5,211 </span></td>
</tr>
<tr>
<td align="center"><span class="text-foreign">YU</span></td>
<td align="right"><span class="text-up">575,965 </span></td>
<td align="right"><span class="text-up">298.4 B</span></td>
<td align="right"><span class="text-up">5,181 </span></td>
<td align="center">2</td>
<td align="center"><span class="text-foreign">RX</span></td>
<td align="right"><span class="text-down">1.7 M</span></td>
<td align="right"><span class="text-down">908.2 B</span></td>
<td align="right"><span class="text-down">5,282 </span></td>
</tr>
<tr>
<td align="center"><span class="text-foreign">BK</span></td>
<td align="right"><span class="text-up">369,446 </span></td>
<td align="right"><span class="text-up">196.0 B</span></td>
<td align="right"><span class="text-up">5,304 </span></td>
<td align="center">3</td>
<td align="center"><span class="text-foreign">ZP</span></td>
<td align="right"><span class="text-down">474,808 </span></td>
<td align="right"><span class="text-down">247.1 B</span></td>
<td align="right"><span class="text-down">5,203 </span></td>
</tr>
<tr>
<td align="center"><span class="text-foreign">AK</span></td>
<td align="right"><span class="text-up">366,209 </span></td>
<td align="right"><span class="text-up">193.1 B</span></td>
<td align="right"><span class="text-up">5,274 </span></td>
<td align="center">4</td>
<td align="center"><span class="text-foreign">AK</span></td>
<td align="right"><span class="text-down">444,447 </span></td>
<td align="right"><span class="text-down">233.4 B</span></td>
<td align="right"><span class="text-down">5,251 </span></td>
</tr>
<tr>
<td align="center"><span class="text-foreign">ZP</span></td>
<td align="right"><span class="text-up">287,065 </span></td>
<td align="right"><span class="text-up">150.0 B</span></td>
<td align="right"><span class="text-up">5,226 </span></td>
<td align="center">5</td>
<td align="center"><span class="text-foreign">BK</span></td>
<td align="right"><span class="text-down">419,266 </span></td>
<td align="right"><span class="text-down">218.8 B</span></td>
<td align="right"><span class="text-down">5,219 </span></td>
</tr>
<tr>
<td align="center"><span class="text-bumn">CC</span></td>
<td align="right"><span class="text-up">198,140 </span></td>
<td align="right"><span class="text-up">104.4 B</span></td>
<td align="right"><span class="text-up">5,267 </span></td>
<td align="center">6</td>
<td align="center"><span class="text-foreign">YU</span></td>
<td align="right"><span class="text-down">252,383 </span></td>
<td align="right"><span class="text-down">131.3 B</span></td>
<td align="right"><span class="text-down">5,203 </span></td>
</tr>
<tr>
<td align="center"><span class="text-foreign">RX</span></td>
<td align="right"><span class="text-up">162,162 </span></td>
<td align="right"><span class="text-up">97.1 B</span></td>
<td align="right"><span class="text-up">5,987 </span></td>
<td align="center">7</td>
<td align="center"><span class="text-bumn">DX</span></td>
<td align="right"><span class="text-down">252,100 </span></td>
<td align="right"><span class="text-down">130.5 B</span></td>
<td align="right"><span class="text-down">5,175 </span></td>
</tr>
<tr>
<td align="center"><span class="text-local">BB</span></td>
<td align="right"><span class="text-up">123,966 </span></td>
<td align="right"><span class="text-up">64.8 B</span></td>
<td align="right"><span class="text-up">5,225 </span></td>
<td align="center">8</td>
<td align="center"><span class="text-foreign">KZ</span></td>
<td align="right"><span class="text-down">115,380 </span></td>
<td align="right"><span class="text-down">60.1 B</span></td>
<td align="right"><span class="text-down">5,212 </span></td>
</tr>
<tr>
<td align="center"><span class="text-local">TP</span></td>
<td align="right"><span class="text-up">70,621 </span></td>
<td align="right"><span class="text-up">36.6 B</span></td>
<td align="right"><span class="text-up">5,189 </span></td>
<td align="center">9</td>
<td align="center"><span class="text-local">BB</span></td>
<td align="right"><span class="text-down">109,509 </span></td>
<td align="right"><span class="text-down">56.9 B</span></td>
<td align="right"><span class="text-down">5,200 </span></td>
</tr>
<tr>
<td align="center"><span class="text-bumn">DX</span></td>
<td align="right"><span class="text-up">15,000 </span></td>
<td align="right"><span class="text-up">7.8 B</span></td>
<td align="right"><span class="text-up">5,181 </span></td>
<td align="center">10</td>
<td align="center"><span class="text-local">TP</span></td>
<td align="right"><span class="text-down">34,490 </span></td>
<td align="right"><span class="text-down">17.9 B</span></td>
<td align="right"><span class="text-down">5,195 </span></td>
</tr>
</tbody>
<tfoot>
<tr class="bdr-t">
<th colspan="9" align="center">
<div class="text-center pt20 valign-middle" style="height:50px;">
<span class="fsize12 ml5 mr5">T. Val : 1.7 T</span>
<span class="fsize12 ml5 mr5">F. NVal : -2.3 T</span>
<span class="fsize12 ml5 mr5">T.Lot : 3.2 M</span>
<span class="fsize12 ml5 mr5">Avg : 5,263 </span>
</div>
</th>
</tr>
</tfoot>
</table>
</div>
<!-- =======================
======SCRIPT MODULE=========
============================-->
<script src="../../../../module/saham/include/js/data-brokersummary.js"></script>