基于tushare的A股市场行情维护程序

基于tushare的A股市场行情维护程序

  • 1 开发背景:
  • 2 tushare 简介
  • 3 功能需求
    • 3.1 tushare数据获取接口封装
    • 3.2 A股全市场股票日线数据的批量下载和更新
  • 4 软件设计
  • 5 程序实现
    • 5.1 AshareDailyData.py
    • 5.2 TuShare.py
  • 6 运行界面截图
  • 7 参考资料

1 开发背景:

笔者刚接触量化投资,对量化投资挺感兴趣,在闲暇时间进行量化投资的学习,只能进行少量资金进行量化实践。目前在进行基于vnpy的A股市场的量化策略学习,主要尝试攻克的技术难点在:A股市场日线数据的免费获取维护、自动下单交易、全市场选股程序、选股策略的回测程序、基于机器学习的股票趋势预测。
github仓库:https://github.com/PanAndy/quant_share

觉得文章有收获,欢迎关注公众号鼓励一下作者呀~
在学习的过程中,也搜集了一些量化、技术的视频及书籍资源,欢迎大家关注公众号获取
百度网盘资源百度网盘资源

2 tushare 简介

tushare是一个基于Python的金融数据接口,拥有丰富的数据内容,如股票、基金、期货、数字货币等行情数据,也有公司财务、基金经理等基本面数据等。特别重要的是,tushare提供的数据是免费的!!!个人开发需要的是A股日线数据,所以tushare是首选。

3 功能需求

3.1 tushare数据获取接口封装

  1. tushare初始化参数相关设置
  2. 参考rqdata模块的代码,实现适用于vnpy的tushare历史行情接口
  3. 历史数据获取过程中,注意考虑tushare每次获取数据上限的规则

3.2 A股全市场股票日线数据的批量下载和更新

  1. 能获取A股全市场股票代码
  2. 能获取A股所有交易日
  3. 按tushare的规则进行日线数据批量下载,存储到sqlite数据库中
  4. 每日定时更新股票日线数据

4 软件设计

description

5 程序实现

5.1 AshareDailyData.py

import multiprocessing
import os
import sys
import traceback
from datetime import datetime, timedelta, time
from time import sleepfrom tqdm import tqdm
from vnpy.trader.constant import Interval
from vnpy.trader.database import database_manager
from vnpy.trader.object import HistoryRequestfrom utils import logsys.path.append(os.getcwd())from TuShare import tushare_client, to_split_ts_codes, TS_DATE_FORMATEclass AShareDailyDataManager:def __init__(self):""""""self.tushare_client = tushare_clientself.symbols = Noneself.trade_cal = Noneself.init()def init(self):""""""self.tushare_client.init()self.symbols = self.tushare_client.symbolsself.trade_cal = self.tushare_client.trade_caldef download_all(self):"""使用tushare下载A股股票全市场日线数据:return:"""log.info("开始下载A股股票全市场日线数据")if self.symbols is not None:with tqdm(total=len(self.symbols)) as pbar:for tscode, list_date in zip(self.symbols['ts_code'], self.symbols['list_date']):symbol, exchange = to_split_ts_codes(tscode)pbar.set_description_str("下载A股日线数据股票代码:" + tscode)start_date = datetime.strptime(list_date, TS_DATE_FORMATE)req = HistoryRequest(symbol=symbol,exchange=exchange,start=start_date,end=datetime.now(),interval=Interval.DAILY)bardata = self.tushare_client.query_history(req=req)if bardata:try:database_manager.save_bar_data(bardata)except Exception as ex:log.error(tscode + "数据存入数据库异常")log.error(ex)traceback.print_exc()pbar.update(1)log.info(pbar.desc)log.info("A股股票全市场日线数据下载完毕")def update_newest(self):"""使用tushare更新本地数据库中的最新数据,默认本地数据库中原最新的数据之前的数据都是完备的:return:"""log.info("开始更新最新的A股股票全市场日线数据")if self.symbols is not None:with tqdm(total=len(self.symbols)) as pbar:for tscode, list_date in zip(self.symbols['ts_code'], self.symbols['list_date']):symbol, exchange = to_split_ts_codes(tscode)newest_local_bar = database_manager.get_newest_bar_data(symbol=symbol,exchange=exchange,interval=Interval.DAILY)if newest_local_bar is not None:pbar.set_description_str("正在处理股票代码:" + tscode + "本地最新数据:" +newest_local_bar.datetime.strftime(TS_DATE_FORMATE))start_date = newest_local_bar.datetime + timedelta(days=1)else:pbar.set_description_str("正在处理股票代码:" + tscode + "无本地数据")start_date = datetime.strptime(list_date, TS_DATE_FORMATE)req = HistoryRequest(symbol=symbol,exchange=exchange,start=start_date,end=datetime.now(),interval=Interval.DAILY)bardata = self.tushare_client.query_history(req=req)if bardata:try:database_manager.save_bar_data(bardata)except Exception as ex:log.error(tscode + "数据存入数据库异常")log.error(ex)traceback.print_exc()pbar.update(1)log.info(pbar.desc)log.info("A股股票全市场日线数据更新完毕")def check_update_all(self):"""这个方法太慢了,不建议调用。这个方法用于本地数据库已经建立,但可能有部分数据缺失时使用使用tushare检查更新所有的A股股票全市场日线数据检查哪一个交易日的数据是缺失的,补全它检查上市后是否每个交易日都有数据,若存在某一交易日无数据,尝试从tushare查询该日数据,若仍无,则说明当天停盘:return:"""log.info("开始检查更新所有的A股股票全市场日线数据")if self.symbols is not None:with tqdm(total=len(self.symbols)) as pbar:for tscode, list_date in zip(self.symbols['ts_code'], self.symbols['list_date']):pbar.set_description_str("正在检查A股日线数据,股票代码:" + tscode)symbol, exchange = to_split_ts_codes(tscode)local_bar = database_manager.load_bar_data(symbol=symbol,exchange=exchange,interval=Interval.DAILY,start=datetime.strptime(list_date, TS_DATE_FORMATE),end=datetime.now())local_bar_dates = [bar.datetime.strftime(TS_DATE_FORMATE) for bar in local_bar]index = (self.trade_cal[exchange.value][(self.trade_cal[exchange.value].cal_date == list_date)])trade_cal = self.trade_cal[exchange.value].iloc[index.index[0]:]for trade_date in trade_cal['cal_date']:if trade_date not in local_bar_dates:req = HistoryRequest(symbol=symbol,exchange=exchange,start=datetime.strptime(trade_date, TS_DATE_FORMATE),end=datetime.strptime(trade_date, TS_DATE_FORMATE),interval=Interval.DAILY)bardata = self.tushare_client.query_history(req=req)if bardata:log.info(tscode + "本地数据库缺失:" + trade_date)try:database_manager.save_bar_data(bardata)except Exception as ex:log.error(tscode + "数据存入数据库异常")log.error(ex)traceback.print_exc()pbar.update(1)log.info(pbar.desc)log.info("A股股票全市场日线数据检查更新完毕")a_share_daily_data_manager = AShareDailyDataManager()def auto_update(start_time: time = time(18, 0)):"""每日盘后自动更新最新日线数据到本地数据库"""log.info("启动A股股票全市场日线数据定时更新")run_parent(start_time=start_time)def run_parent(start_time: time = time(18, 0)):"""运行父进程,定时启动子进程下载任务:return:"""log.info("启动A股股票全市场日线数据定时更新父进程")# 每天晚上18:30从tushare更新当时K线数据UPDATE_TIME = start_timechild_process = Nonewhile True:current_time = datetime.now().time()if current_time.hour == UPDATE_TIME.hour and current_time.minute == UPDATE_TIME.minute and child_process is None:log.info("启动日线数据更新子进程")child_process = multiprocessing.Process(target=run_child)child_process.start()log.info("日线数据更新子进程启动成功")if (not (current_time.hour == UPDATE_TIME.hour and current_time.minute == UPDATE_TIME.minute)) \and child_process is not None:child_process.join()child_process = Nonelog.info("数据更新子进程关闭成功")log.info("进入A股股票全市场日线数据定时更新父进程")sleep(10)def run_child():"""子线程下载数据:return:"""log.info("启动A股股票全市场日线数据定时更新子进程")try:a_share_daily_data_manager.update_newest()except Exception:log.info("子进程异常")traceback.print_exc()if __name__ == '__main__':log.info("自动更新A股股票全市场日线数据")# a_share_daily_data_manager.download_all()# a_share_daily_data_manager.update_newest()# a_share_daily_data_manager.check_update_all()auto_update(start_time=time(18, 00))

5.2 TuShare.py

import requests
import tushare as ts
from tushare.pro import client
from pytz import timezone
from typing import List, Optional, Dict
import pandas as pd
from datetime import datetime, timedelta
import time
import tracebackfrom vnpy.trader.object import HistoryRequest, BarData
from vnpy.trader.constant import Exchange, Intervalfrom utils import logCHINA_TZ = timezone("Asia/Shanghai")tushare_token: str = ""MAX_QUERY_SIZE: int = 5000
TS_DATE_FORMATE: str = '%Y%m%d'
MAX_QUERY_TIMES: int = 500EXCHANGE_TS2VT: Dict[str, Exchange] = {'SH': Exchange.SSE,'SZ': Exchange.SZSE
}EXCHANGE_VT2TS: Dict[Exchange, str] = {v: k for k, v in EXCHANGE_TS2VT.items()}def to_ts_symbol(symbol: str, exchange: Exchange):"""转换合约代码为tushare查询代码"""if exchange == Exchange.SSE:tcode = f'{symbol}' + '.' + f'{EXCHANGE_VT2TS[exchange]}'elif exchange == Exchange.SZSE:tcode = f'{symbol}' + '.' + f'{EXCHANGE_VT2TS[exchange]}'else:print("目前只研究深圳证券交易所和上海证券交易所A股股票!")raise TypeError("目前只研究深圳证券交易所和上海证券交易所A股股票!")return tcodedef to_split_ts_codes(tscode: str):symbol, exchange_ts = tscode.split('.')exchange = EXCHANGE_TS2VT[exchange_ts]return symbol, exchangeclass TuShareClient:"""从TuShare中查询历史数据的Clienttushare日线数据说明:交易日每天15点~16点之间更新数据,daily接口是未复权行情,停牌期间不提供数据。tushare调取说明:基础积分每分钟内最多调取500次,每次5000条数据"""def __init__(self):""""""self.pro: client.DataApi = Noneself.inited: bool = False# 获得所有股票代码self.symbols: pd.DataFrame = None# 获得交易日历self.trade_cal: Dict[str, pd.DataFrame] = Nonedef init(self, token: str = "") -> bool:""""""if self.inited:return Trueif token:ts.set_token(tushare_token)else:ts.set_token(tushare_token)try:self.pro = ts.pro_api()self.stock_list()self.trade_day_list()except (BaseException, "tushare连接失败"):return Falseself.inited = Truereturn Truedef query_history(self, req: HistoryRequest) -> Optional[List[BarData]]:"""从tushare里查询历史数据:param req:查询请求:return: Optional[List[BarData]]"""if self.symbols is None:return Nonesymbol = req.symbolexchange = req.exchangeinterval = req.intervalstart = req.start.strftime(TS_DATE_FORMATE)end = req.end.strftime(TS_DATE_FORMATE)if interval is not Interval.DAILY:return Noneif exchange not in [Exchange.SSE, Exchange.SZSE]:return Nonetscode = to_ts_symbol(symbol, exchange)# 修改查询数据逻辑,在每次5000条数据的限制下,很可能一次无法读取完cnt = 0df: pd.DataFrame = Nonewhile datetime.strptime(start, TS_DATE_FORMATE) <= datetime.strptime(end, TS_DATE_FORMATE):# 保证每次查询最多5000天数据start_date = datetime.strptime(start, TS_DATE_FORMATE)simulate_end_date = min(datetime.strptime(end, TS_DATE_FORMATE),start_date + timedelta(days=MAX_QUERY_SIZE))simulate_end = simulate_end_date.strftime(TS_DATE_FORMATE)# 保证每次调用时间在60/500=0.12秒内,以保证每分钟调用次数少于500次# begin_time = time.time()tushare_df = Nonewhile True:try:tushare_df = self.pro.query('daily', ts_code=tscode, start_date=start, end_date=simulate_end)except (requests.exceptions.SSLError, requests.exceptions.ConnectionError) as e:log.error(e)# traceback.print_exc()# ('Connection aborted.', ConnectionResetError(10054, '远程主机强迫关闭了一个现有的连接。', None, 10054, None))if '10054' in str(e):sleep_time = 60.0log.info("请求过于频繁,sleep:" + str(sleep_time) + "s")time.sleep(sleep_time)log.info("继续发送请求:" + tscode)continue  # 继续发请求else:raise Exception(e)  # 其他异常,抛出来breakif tushare_df is not None:if df is None:df = tushare_dfelse:df = pd.concat([df, tushare_df], ignore_index=True)# end_time = time.time()# delta = round(end_time - begin_time, 3)# if delta < 60 / MAX_QUERY_TIMES:sleep_time = 0.5log.info("sleep:" + str(sleep_time) + "s")time.sleep(sleep_time)cnt += 1start = (simulate_end_date + timedelta(days=1)).strftime(TS_DATE_FORMATE)data: List[BarData] = []if df is not None:for ix, row in df.iterrows():date = datetime.strptime(row.trade_date, '%Y%m%d')date = CHINA_TZ.localize(date)if pd.isnull(row['open']):log.info(symbol + '.' + EXCHANGE_VT2TS[exchange] + row['trade_date'] + "open_price为None")elif pd.isnull(row['high']):log.info(symbol + '.' + EXCHANGE_VT2TS[exchange] + row['trade_date'] + "high_price为None")elif pd.isnull(row['low']):log.info(symbol + '.' + EXCHANGE_VT2TS[exchange] + row['trade_date'] + "low_price为None")elif pd.isnull(row['close']):log.info(symbol + '.' + EXCHANGE_VT2TS[exchange] + row['trade_date'] + "close_price为None")elif pd.isnull(row['amount']):log.info(symbol + '.' + EXCHANGE_VT2TS[exchange] + row['trade_date'] + "volume为None")row.fillna(0)bar = BarData(symbol=symbol,exchange=exchange,interval=interval,datetime=date,open_price=row['open'],high_price=row['high'],low_price=row['low'],close_price=row['close'],volume=row['amount'],gateway_name='tushare')data.append(bar)return datadef stock_list(self):"""调用tushare stock_basic 接口获得上海证券交易所和深圳证券交易所所有股票代码获取基础信息数据,包括股票代码、名称、上市日期、退市日期等:return:"""if self.symbols is None:symbols_sse = self.pro.query('stock_basic', exchange=Exchange.SSE.value, fields='ts_code,symbol,name,''fullname,enname,market,''list_status,list_date,''delist_date,is_hs')symbols_szse = self.pro.query('stock_basic', exchange=Exchange.SZSE.value, fields='ts_code,symbol,name,''fullname,enname,market,''list_status,list_date,''delist_date,is_hs')self.symbols = pd.concat([symbols_sse, symbols_szse], axis=0, ignore_index=True)def trade_day_list(self):"""查询交易日历:return:"""if self.trade_cal is None:self.trade_cal = dict()self.trade_cal[Exchange.SSE.value] = self.pro.query('trade_cal', exchange=Exchange.SSE.value, is_open='1')self.trade_cal[Exchange.SZSE.value] = self.pro.query('trade_cal', exchange=Exchange.SZSE.value, is_open='1')tushare_client = TuShareClient()if __name__ == "__main__":print("测试TuShare数据接口")# tushare_client = TuShareClient()tushare_client.init()# print(tushare_client.symbols)# print(tushare_client.trade_cal)req = HistoryRequest(symbol='600600', exchange=Exchange.SSE,start=datetime(year=1999, month=11, day=10), end=datetime.now(), interval=Interval.DAILY)ts_data = tushare_client.query_history(req)print(len(ts_data))

5.3 utils.py

import loggingclass logger:def __init__(self, path, clevel=logging.INFO, Flevel=logging.INFO):self.logger = logging.getLogger(path)self.logger.setLevel(logging.DEBUG)fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')# 设置CMD日志sh = logging.StreamHandler()sh.setFormatter(fmt)sh.setLevel(clevel)# 设置文件日志fh = logging.FileHandler(path, encoding='utf-8')fh.setFormatter(fmt)fh.setLevel(Flevel)self.logger.addHandler(sh)self.logger.addHandler(fh)def debug(self, message):self.logger.debug(message)def info(self, message):self.logger.info(message)def war(self, message):self.logger.warn(message)def error(self, message):self.logger.error(message)def cri(self, message):self.logger.critical(message)log = logger("log.txt")

6 运行界面截图

description

7 参考资料

  1. 全市场期货数据的批量下载和更新
  2. 使用免费的天勤SDK数据,替换付费的RQData
  3. vnpy不使用rqdata,尝试tushare
  4. tushare文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/29615.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用Tushare获取股票数据(全面详细,照着敲就可以)

一.tushare简介 tushare是一个免费,开源的python财经数据接口包.主要实现对股票等金融数据从数据采集、清洗加工到数据存储的过程&#xff0c;能够为金融分析人员提供快速、整洁、和多样的便于分析的数据&#xff0c;为他们在数据获取方面极大地减轻工作量&#xff0c;使他们更…

【PostMan】PostMan可以打开但是窗口一直显示不出来问题

问题 如标题 解决方案&#xff1a; 1&#xff1a;关闭postman 2&#xff1a;打开如下路径 C:UsersUserNameAppDataRoamingPostman 找到一下window 文件删除该文件 说明&#xff1a;UserName 为你自己电脑上用户名称 其他情况的解决方案&#xff1a; https://github.com/postm…

开发避坑3——大鸟 pk Bug(使用postman测试POST接口遇到报错(ErrorMessage:Unauthorization request ......))

使用postman测试POST接口遇到报错&#xff08;ErrorMessage&#xff1a;Unauthorization request …) 不管你是前端、后端、测试还是运维等工程师&#xff0c;学会使用postman测试接口是工作中必不可少的。当我们使用前端页面调用接口发现浏览器报错我们就要排查是前端调用问题…

chatgpt赋能python:Python访问手机存储文件夹:移动设备编程新纪元

Python访问手机存储文件夹&#xff1a;移动设备编程新纪元 在移动设备时代&#xff0c;开发人员必须掌握能够访问手机存储文件夹的技能。Python是一种强大的编程语言&#xff0c;已成为许多应用程序和脚本的首选语言。Python为移动设备编程带来了新的可能性&#xff0c;例如可…

ChatGPT遭多国调查,OpenAI凌晨就安全问题发文,GPT-5要暂缓?

最近&#xff0c;意大利宣布禁用 ChatGPT&#xff0c;因为 OpenAI 违反了意大利相关的隐私规则和数据保护法&#xff0c;出现了用户数据丢失情况&#xff0c;而且未向用户告知。 消息出来后&#xff0c;德国、法国、爱尔兰、西班牙等国的监管部门都表示正在密切关注 ChatGPT 的…

通过AI算法预测彩票

最近工作上比较闲&#xff0c;于是抽时间写了个APP&#xff0c;运用一些AI算法&#xff0c;先排除一些明显不可能的号&#xff0c;然后结合历史数据&#xff0c;分析测算出可能得结果&#xff0c;试运行了大概10期&#xff0c;中了一个三等奖&#xff0c;蓝球概率有明显提高&am…

TOPIK 韩语考试历届考题下载

韩国语能力考试官网 http://www.topik.go.kr/ 历届考试真题下载。

5分钟带你学会MotionLayout 第二篇

1、前言 最近在开发中&#xff0c;同事居然对MontionLayout一知半解&#xff0c;那怎么行&#xff01;百里偷闲写出此文章&#xff0c;一起学习、一起进步。如果写的不好&#xff0c;或者有错误之处&#xff0c;恳请在评论、私信、邮箱指出&#xff0c;万分感谢&#x1f64f; …

重磅:宣布一件大事,大模型与 AIGC 专场来啦

文末有抽奖&#xff01; 6月30日-7月1日&#xff0c;在由稀土掘金开发者社区主办的稀土开发者大会上&#xff0c;邀你与最专业最前沿的嘉宾面对面交流&#xff01;6月30日上午的主会场&#xff0c;北京大学王选计算机研究所教授、CCF 自然语言处理专委会秘书长万小军&#xff0…

文末有抽奖|线下嗨聊 AIGC两整天!为什么我推荐你参加稀土开发者大会?!...

稀土开发者大会 6月30日-7月1日 北京新云南皇冠假日酒店&#xff08;近字节融中心工区&#xff09; &#x1f914; 若问今年谁最火&#xff1f;ChatGPT 答曰&#xff1a;AIGC 还有我&#xff01; 要问技术圈今年最火的话题是什么&#xff1f;无外乎这些关键词&#xff1a;AIGC、…

我用ChatGPT,给RabbitMQ加了个连接池

上次我把 RabbitMQ 集成到项目中&#xff0c;但是每次使用 RabbitMQ 时都去 New 一个连接&#xff0c;导致并发起不来&#xff0c;所以这次我们就给 RabbitMQ 加一个连接池。 为了偷个懒&#xff0c;我直接用 ChatGPT 教我加。 01 ChatGPT 生成的代码 我输入的关键字如下&am…

ClickPrompt

太长不看版&#xff1a; GitHub&#xff1a;github.com/prompt-engi…在线地址&#xff1a;www.clickprompt.org/ 欢迎来添加你的 AI Prompt 和使用心得。 再上个截图&#xff1a; ClickPrompt&#xff1a;简化你的 Prompt 设计之旅 上周末&#xff0c;为了更好地记录与分享…

线下嗨聊 AIGC两整天!为什么我推荐你参加稀土开发者大会?

&#x1f914; 若问今年谁最火&#xff1f; ChatGPT 答曰&#xff1a;AIGC 还有我&#xff01; 要问技术圈今年最火的话题是什么&#xff1f;无外乎这些关键词&#xff1a;AIGC、ChatGPT、某端已死、各行各业✖️ChatGPT…… 究其原因&#xff0c;是因为 AI 这些年在不断更新…

nodejs 获取微信小程序二维码

getQRCode(accessToken) {const { ctx } this;let parameters;let url https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token${accessToken};await axios({method: "post",url: url,responseEncoding: "base64", //重点data: {page: "pa…

我要开始在B站分享视频教程了

目录 前言一、精品网站分享ChatGPT菜鸟在线编辑器在线音乐网站 二、常用工具知识学习编程前端 视图文关于俺 前言 大家好&#xff0c;我是MIKE笔记&#xff0c;一名在CSDN经常分享技术文章和教程的博主。如果你也喜欢我的文章&#xff0c;那么我想向你推荐我的B站频道&#xf…

chatgpt赋能python:如何用Python做兼职的SEO

如何用Python做兼职的SEO SEO是指优化网站内容和结构&#xff0c;以便在搜索引擎排名中获得更高的排名。在今天的数字时代中&#xff0c;SEO对于许多企业和网站来说非常重要。Python作为一种简单易学的编程语言&#xff0c;可以用来帮助优化和管理网站。在本文中&#xff0c;我…

[经验教程]iPhone苹果手机Siri怎么设置?

iPhone苹果手机Siri怎么设置&#xff1f; 1、在iPhone苹果手机上打开手机设置&#xff1b; 2、在iPhone苹果手机设置内找到Siri与搜索&#xff0c;并点击进入&#xff1b; 3、进入后&#xff0c;在Siri与搜索内设置&#xff1b; 原文来源&#xff1a;https://www.caochai.com/…

siri快捷指令_入门的最佳Siri快捷方式

siri快捷指令 The new Shortcuts app that was introduced in iOS 12 lets you create shortcuts to automate any number of tasks. Here are a handful of good ones to get you started, with the hopes that it gets your creative juices flowing. iOS 12中引入的新的快捷…

练习四级英语听力推荐用哪个APP?

练习四级英语听力推荐用哪个APP&#xff1f;大学英语四级想必是大多数同学都要去追求的一个目标&#xff0c;今天给大家推荐几个对学习英语和四级考试帮助非常大的软件&#xff0c;希望能帮助到每一个面临英语四级考试的同学。 有道词典 大家都知道对于英语四级考试来说&#…

English Learning - L2-12 英音地道语音语调 音的同化 爆破技巧 2023.04.4 周二

English Learning - L2-12 英音地道语音语调 音的同化 爆破技巧 2023.04.4 周二 音的同化因声带影响发生同化因发音部位的影响而发生同化 失去爆破摆拍爆破&#xff08;爆破音&#xff0b;爆破音&#xff09;谦让型爆破爆破音摩擦音 与 爆破音破擦音爆破音鼻辅音/舌边音 爆破综…