183 lines
7.7 KiB
PowerShell
183 lines
7.7 KiB
PowerShell
param(
|
||
[switch]$Force,
|
||
[switch]$DryRun
|
||
)
|
||
|
||
$ErrorActionPreference = 'Stop'
|
||
|
||
$Workspace = 'C:\Users\12637\Desktop\hermes\焦煤'
|
||
$ReportDir = Join-Path $Workspace '日报'
|
||
$LogDir = Join-Path $Workspace '日志'
|
||
$Today = Get-Date -Format 'yyyy-MM-dd'
|
||
$RunAt = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
|
||
$ReportPath = Join-Path $ReportDir "$Today`_焦煤日报.md"
|
||
$LogPath = Join-Path $LogDir 'auto_daily_report.log'
|
||
|
||
New-Item -ItemType Directory -Force -Path $ReportDir, $LogDir | Out-Null
|
||
|
||
function Write-AutoLog {
|
||
param([string]$Message)
|
||
$line = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') $Message"
|
||
Add-Content -LiteralPath $LogPath -Value $line -Encoding UTF8
|
||
}
|
||
|
||
function To-DecimalOrNull {
|
||
param([string]$Value)
|
||
if ([string]::IsNullOrWhiteSpace($Value)) { return $null }
|
||
$style = [Globalization.NumberStyles]::Float
|
||
$culture = [Globalization.CultureInfo]::InvariantCulture
|
||
return [decimal]::Parse($Value, $style, $culture)
|
||
}
|
||
|
||
function Format-Price {
|
||
param([object]$Value)
|
||
if ($null -eq $Value -or [string]::IsNullOrWhiteSpace([string]$Value)) { return '待核验' }
|
||
$number = [decimal]$Value
|
||
return $number.ToString('0.0', [Globalization.CultureInfo]::InvariantCulture)
|
||
}
|
||
|
||
function Format-Int {
|
||
param([object]$Value)
|
||
if ($null -eq $Value -or [string]::IsNullOrWhiteSpace([string]$Value)) { return '待核验' }
|
||
$number = [decimal]$Value
|
||
return ([int]$number).ToString('N0', [Globalization.CultureInfo]::GetCultureInfo('zh-CN'))
|
||
}
|
||
|
||
try {
|
||
$url = 'https://hq.sinajs.cn/list=nf_JM2609,nf_JM0'
|
||
$headers = @{
|
||
Referer = 'https://finance.sina.com.cn/futures/quotes/JM0.shtml'
|
||
'User-Agent' = 'Mozilla/5.0'
|
||
}
|
||
$response = Invoke-WebRequest -Uri $url -Headers $headers -TimeoutSec 30
|
||
$content = $response.Content
|
||
|
||
$match = [regex]::Match($content, 'hq_str_nf_JM2609="(?<body>[^"]+)"')
|
||
if (-not $match.Success) {
|
||
$match = [regex]::Match($content, 'hq_str_nf_JM0="(?<body>[^"]+)"')
|
||
}
|
||
if (-not $match.Success) {
|
||
throw '未能从新浪行情接口解析 JM2609/JM0 行情串。'
|
||
}
|
||
|
||
$fields = $match.Groups['body'].Value -split ','
|
||
if ($fields.Count -lt 18) {
|
||
throw "行情字段数量不足:$($fields.Count)。"
|
||
}
|
||
|
||
$quoteDate = $fields[17]
|
||
if (($quoteDate -ne $Today) -and (-not $Force)) {
|
||
Write-AutoLog "跳过:行情日期 $quoteDate 与本机日期 $Today 不一致,可能为非交易日或数据未更新。"
|
||
exit 0
|
||
}
|
||
|
||
$contractName = $fields[0]
|
||
$quoteTimeRaw = $fields[1]
|
||
$quoteTime = if ($quoteTimeRaw.Length -eq 6) { "$($quoteTimeRaw.Substring(0,2)):$($quoteTimeRaw.Substring(2,2)):$($quoteTimeRaw.Substring(4,2))" } else { $quoteTimeRaw }
|
||
$open = To-DecimalOrNull $fields[2]
|
||
$high = To-DecimalOrNull $fields[3]
|
||
$low = To-DecimalOrNull $fields[4]
|
||
$last = To-DecimalOrNull $fields[8]
|
||
if ($null -eq $last -or $last -eq 0) { $last = To-DecimalOrNull $fields[5] }
|
||
$settle = To-DecimalOrNull $fields[9]
|
||
$prevSettle = To-DecimalOrNull $fields[10]
|
||
$openInterest = To-DecimalOrNull $fields[13]
|
||
$volume = To-DecimalOrNull $fields[14]
|
||
|
||
$change = $null
|
||
$pct = $null
|
||
if ($null -ne $last -and $null -ne $prevSettle -and $prevSettle -ne 0) {
|
||
$change = $last - $prevSettle
|
||
$pct = [math]::Round((([double]$change / [double]$prevSettle) * 100), 2)
|
||
}
|
||
|
||
$direction = '持平'
|
||
if ($null -ne $change) {
|
||
if ($change -gt 0) { $direction = '上涨' }
|
||
elseif ($change -lt 0) { $direction = '下跌' }
|
||
}
|
||
|
||
$closeLocation = '待核验'
|
||
if ($null -ne $last -and $null -ne $high -and $null -ne $low -and $high -gt $low) {
|
||
$pos = ([double]($last - $low) / [double]($high - $low))
|
||
if ($pos -ge 0.67) { $closeLocation = '收在日内偏高区间' }
|
||
elseif ($pos -le 0.33) { $closeLocation = '收在日内偏低区间' }
|
||
else { $closeLocation = '收在日内中部区间' }
|
||
}
|
||
|
||
$changeText = if ($null -ne $change) { $change.ToString('+0.0;-0.0;0.0', [Globalization.CultureInfo]::InvariantCulture) } else { '待核验' }
|
||
$pctText = if ($null -ne $pct) { $pct.ToString('+0.00;-0.00;0.00', [Globalization.CultureInfo]::InvariantCulture) + '%' } else { '待核验' }
|
||
|
||
$report = @"
|
||
# $Today 焦煤期货日报(自动生成)
|
||
|
||
> 自动生成时间:$RunAt
|
||
> 数据边界:盘面来自新浪期货行情接口;现货、基差、供需、重点新闻需用 finance-mcp / 妙想 MCP 或人工源二次补充。自动版不编写未核验数字。
|
||
|
||
## 主要结论
|
||
|
||
- 主力合约:$contractName,收报 $(Format-Price $last) 元/吨,较昨结 $changeText($pctText),日内区间 $(Format-Price $low)-$(Format-Price $high) 元/吨,$closeLocation。
|
||
- 量仓结构:成交量 $(Format-Int $volume) 手,持仓量 $(Format-Int $openInterest) 手。字段口径按新浪行情串解析为“持仓量在成交量前”,如交易所或第三方口径冲突,以交易所/可靠第三方二次核验为准。
|
||
- 盘面判断:当日盘面$direction,短线仍需观察价格能否站稳日内高位;若回落至昨结或日内低位附近,则说明上涨动能减弱。
|
||
|
||
## 关键数据
|
||
|
||
| 指标 | 数值 | 备注 |
|
||
|---|---:|---|
|
||
| 主力合约 | $contractName | 新浪行情 |
|
||
| 最新/收盘价 | $(Format-Price $last) 元/吨 | 行情时间 $quoteTime |
|
||
| 开盘价 | $(Format-Price $open) 元/吨 | 自动抓取 |
|
||
| 最高价 | $(Format-Price $high) 元/吨 | 自动抓取 |
|
||
| 最低价 | $(Format-Price $low) 元/吨 | 自动抓取 |
|
||
| 昨结 | $(Format-Price $prevSettle) 元/吨 | 自动抓取 |
|
||
| 结算价 | $(Format-Price $settle) 元/吨 | 自动抓取 |
|
||
| 涨跌 | $changeText | 相对昨结 |
|
||
| 涨跌幅 | $pctText | 相对昨结 |
|
||
| 成交量 | $(Format-Int $volume) 手 | 新浪字段 14 |
|
||
| 持仓量 | $(Format-Int $openInterest) 手 | 新浪字段 13 |
|
||
|
||
日内区间:$(Format-Price $low) ├──────── $(Format-Price $last) ────────┤ $(Format-Price $high)
|
||
|
||
## 重点新闻
|
||
|
||
- 【待补充】近三日煤矿安监、复产、停产、事故、政策扰动。
|
||
- 【待补充】蒙煤通关、口岸库存、进口煤报价变化。
|
||
- 【待补充】焦化利润、钢厂铁水、成材成交及负反馈风险。
|
||
|
||
## 现货、基差与供需
|
||
|
||
| 模块 | 状态 | 结论 |
|
||
|---|---|---|
|
||
| 现货价格 | 待 MCP / 人工核验 | 不自动填数 |
|
||
| 基差 | 待 MCP / 人工核验 | 不自动填数 |
|
||
| 供给 | 待 MCP / 人工核验 | 关注山西安监、煤矿复产、蒙煤通关 |
|
||
| 需求 | 待 MCP / 人工核验 | 关注铁水、焦炭利润、钢厂补库 |
|
||
| 库存 | 待 MCP / 人工核验 | 关注港口、煤矿、焦钢企业库存 |
|
||
|
||
## 下个交易日预测
|
||
|
||
- 基准情形:若价格维持在 $(Format-Price $last) 元/吨附近并放量不破日内低点,短线偏强震荡。
|
||
- 上行情形:若突破并站稳 $(Format-Price $high) 元/吨上方,说明多头延续,关注整数关口及前高压力。
|
||
- 回落情形:若跌回昨结 $(Format-Price $prevSettle) 元/吨附近,说明当日上涨被消化,关注资金离场和现货跟涨不足风险。
|
||
|
||
## 数据与来源
|
||
|
||
- 盘面:新浪期货行情 nf_JM2609,nf_JM0,行情日期 $quoteDate,行情时间 $quoteTime。
|
||
- 自动任务:Windows 任务计划程序工作日 15:30 触发。
|
||
- 质量控制:现货、新闻、供需未核验时必须保留“待补充/待核验”,不得编写具体数值。
|
||
"@
|
||
|
||
if ($DryRun) {
|
||
Write-Output $report
|
||
Write-AutoLog "DryRun:已生成预览,未写入 $ReportPath。"
|
||
}
|
||
else {
|
||
Set-Content -LiteralPath $ReportPath -Value $report -Encoding UTF8
|
||
Write-AutoLog "完成:已写入 $ReportPath。"
|
||
}
|
||
}
|
||
catch {
|
||
Write-AutoLog "失败:$($_.Exception.Message)"
|
||
throw
|
||
}
|