基金的募集与认购

基金的募集与认购

程序

申请

  1. 基金申请报告
  2. 基金合同草案
  3. 基金托管协议草案
  4. 招募说明书草案

申请的注册

  1. 自申请日期六个月内做出决议
  2. 常规产品做简易程序注册,原则上不超过20个工作日
  3. 简易产品为常规股票基金、混合基金、债券基金、指数基金、货币基金、发起式基金、合格境内机构投资者(QDII)基金、理财基金和交易型指数基金(含单市场、跨市场/跨境ETF)及其联接基金

发售

  1. 自收到核准文件六个月内进行发售
  2. 发售日开始计算募集时间不超过三个月

合同生效

  1. 母鸡期满,封闭基金达到核准的80%,持有人数少于200人
  2. 开放基金募集总额不少于两亿份,金额不少于两亿元人民币,持有人不少于200人
  3. 母鸡期满十日内验资,验资结束提交备案申请和验资报告
  4. 证监会自收到备案申请及验资报告三个工作日内书面确认,合同自确认之日起生效,次日发布公告

募集失败

  1. 固有财产承担债务费用
  2. 三十天内返还投资者本金及期间产生的银行同期存款利息

证券投资基金的类型

证券投资基金的类型

意义

  • 有助于投资者选择适合自己的风险偏好的基金
  • 有助于评价基金的业绩
  • 是基金评级的基础
  • 有助于分类监管

按对象分

  • 股票基金:基金资产80%投入股票
  • 债券基金:基金急产80%投入债券
  • 货币市场基金:仅投资货币市场工具
  • 混合基金:除了投资基金外,且比例不满足上述基金属于混合基金
  • 基金中的基金:投资基金的基金

按投资目标分

  • 增长型:追求增值为目标,较少考虑当期收益,风险高,收益大
  • 收入型:追求稳定经常性收入,风险小,收益低
  • 平衡性:以上两种的中间形态

投资理念

  • 主动型:力图超越基准表现
  • 被动性:一般是跟踪或者复制指数

募集方式

  • 公募型:面向不特定人群,强监管
  • 私募型:面向合格投资者

投资基金的法律形式及运作方式

投资基金的法律形式及运作方式

公司型/契约型

契约型

只有两方参与,投资人和基金管理人,没有法人

公司型

组建法人,成立股东会,按公司运营

区别

法律地位不同:公司型投资人是以股东形式存在,并可以行使股东权利,对投资可以有较大的干预权限,契约型的则是委托代为投资,没有太多对投资行为干预的权限

封闭式/开放式

封闭式基金

  1. 有固定存续期
  2. 份额在封闭期内是固定的
  3. 直接与基金管理人之间完成交易
  4. 交易价格会受到二级市场影响
  5. 不会因为标的价格波动而面临直接压力
  6. 比较适合中长期投资

开放式

  1. 无固定存续期
  2. 份额随时增减
  3. 上市之后仅能在二级市场买卖
  4. 价格仅与净值挂钩
  5. 会直接面临赎回压力
  6. 要保持资产的流动性

证券投资基金的概览

证券投资基金的概览

定义

证券投资基金(特指公募基金)是将众多不特定的投资者资金汇集形成独立财产,委托基金管理人(发产品的人)投资管理,基金托管人进行财产托管

参与主体

  • 份额持有人,也就是投资者类似你我这样普通的买基金的人
  • 基金管理人,是负责基金运作的角色,是基金产品设计的人士
  • 基金托管人,是负责监管资金运作和实际资金指令执行的机构,并需要与基金管理人完全独立

基金市场服务机构

  • 销售(可以销售)
  • 销售支付(只能参与结算)
  • 份额登记
  • 估值核算
  • 投资顾问
  • 评级
  • 基金信息技术系统服务
  • 法律支持

监管机构和自律组织

  • 基金监管机构(中国证券监督管理委员会、中国人民银行、证券交易所、证券业协会)
  • 自律组织:证券交易所,中国证券投资基金业协会

金融、资产管理、投资基金

金融、资产管理、投资基金

金融市场与资产管理行业

  1. 什么是金融资产
    金融资产就是代表未来收益或资产合法权的凭证
    标识了明确的价值和交易双方的关系
  2. 金融与居民理财
    金融就是货币资金的融通
    货币资金来源于居民通过生产劳动产生
    理财是通过对货币资金/资本进行管理以其保值或增值
  3. 金融市场是资金货币融通的市场
    市场分类:
    交易工具期限分类:货币市场、资本市场
    标的物分类:证券、票据、衍生物、外汇、黄金
    交易交割期限分类:期货、现货
    市场构成:
    市场参与者:政府、中央银行、企业或个人居民、金融机构
    金融工具:证明债权债务关系并据此进行货币资金交易的合法凭证
    交易组织方式:固定场所集中式、柜台双方面议、电信网络交易

  4. 资产管理与资产管理行业
    资产管理:受投资人委托,为达成投资人特定目标代理投资人对投资人资本进行管理,并以此收取服务费用
    资产管理行业:基金管理公司、私募机构、信托公司、证券公司、期货公司、保险公司、商业银行

投资基金

  1. 是资产管理的主要方式
  2. 是组合投资、专业管理、利益共享、风险共担的投资方式
  3. 有证券投资、私募股权、分线投资、对冲基金、其他

如何建立一个回测系统(四)

如何建立一个回测系统(四)

搜索任务处理

一个好的量化交易,是对于一个函数的极值的搜索及规则的搜索

但因为函数的复杂性,无法得到函数的性质,有时候可以采用暴力搜索极值点的方式

类似于sum(f(g(x,y),z),t) = alpha其中z是外部响应,z与g(x,y)之间接近线性无关(我们的交易量远达不到影响结果的情景)t是时间序列下标

定义任务

g(x,y)中不同的系数对于f的的影响不同,又因为g(x,y)不是一个显函数,只能通过代入数据计算

我们定义每组(x,y,ts,te)为搜索任务,将数据及计算函数交由每个线程完成,此时不会涉及多线程问题,任务之间线性无关

支撑部件

第一版本我本想通过序列化为字符串形式来作为存储

但因为字符串是变长形式,难以在文件层级进行读写

故而想到如对象存储一般,因为实现难度高,工程量巨大(修改操作占主要),故转而投向SQLite作为持久化操作

最终

我以SQL作为存储端,将任务分发至多台机器形成集群,可以极大的加快搜索进度,且任意机器死亡可以在另一台机器上恢复,无需从头开始

如何建立回测系统(三)

如何建立回测系统(三)

优化版本


public class MarketPlace { private Map<String, WriteLockMap<Long, OrderQueen>> sellOrderChannel; private Map<String, WriteLockMap<Long, OrderQueen>> buyOrderChannel; private Map<String, Long> lastComplete; public MarketPlace() { this.sellOrderChannel = new ConcurrentHashMap<>(); this.buyOrderChannel = new ConcurrentHashMap<>(); this.lastComplete = new ConcurrentHashMap<>(); } public void order(Order order) { OrderQueen orderQueen; WriteLockMap<Long, OrderQueen> longOrderQueenMap; String fixCacheString = order.getTradeCode().intern(); if (order.sell()) { longOrderQueenMap = buyOrderChannel.get(order.getTradeCode()); if (longOrderQueenMap == null) { synchronized (fixCacheString) { longOrderQueenMap = new WriteLockMap<>(new ConcurrentHashMap<>()); buyOrderChannel.put(order.getTradeCode(), longOrderQueenMap); } } } else { longOrderQueenMap = sellOrderChannel.get(order.getTradeCode()); if (longOrderQueenMap == null) { synchronized (fixCacheString) { longOrderQueenMap = new WriteLockMap<>(new ConcurrentHashMap<>()); sellOrderChannel.put(order.getTradeCode(), longOrderQueenMap); } } } orderQueen = longOrderQueenMap.get(order.getPrice()); if (orderQueen == null) { longOrderQueenMap.lock(); orderQueen = new OrderQueen(order.getPrice()); longOrderQueenMap.put(order.getPrice(), orderQueen); longOrderQueenMap.unlock(); } Long price = orderQueen.try2ClinchOrder(order); if (price != null) { this.lastComplete.put(order.getTradeCode(), price); } if (!order.isComplete()) { if (order.sell()) { WriteLockMap<Long, OrderQueen> tm = this.sellOrderChannel .get(order.getTradeCode()); if (tm == null) { synchronized (fixCacheString) { WriteLockMap<Long, OrderQueen> writeLockMap = new WriteLockMap<>( new ConcurrentHashMap<>()); OrderQueen newOne = new OrderQueen(order.getPrice()); newOne.addOrder(order); writeLockMap.put(order.getPrice(), newOne); this.sellOrderChannel.put(order.getTradeCode(), writeLockMap); } } else { OrderQueen orderQueen1 = tm.get(order.getPrice()); if (orderQueen1 == null) { tm.lock(); orderQueen1 = new OrderQueen(order.getPrice()); orderQueen1.addOrder(order); tm.put(order.getPrice(), orderQueen1); tm.unlock(); } } } else { WriteLockMap<Long, OrderQueen> tm = this.buyOrderChannel .get(order.getTradeCode()); if (tm == null) { synchronized (fixCacheString) { WriteLockMap<Long, OrderQueen> writeLockMap = new WriteLockMap<>( new ConcurrentHashMap<>()); OrderQueen newOne = new OrderQueen(order.getPrice()); newOne.addOrder(order); writeLockMap.put(order.getPrice(), newOne); this.buyOrderChannel.put(order.getTradeCode(), writeLockMap); } } else { OrderQueen orderQueen1 = tm.get(order.getPrice()); if (orderQueen1 == null) { tm.lock(); orderQueen1 = new OrderQueen(order.getPrice()); orderQueen1.addOrder(order); tm.put(order.getPrice(), orderQueen1); tm.unlock(); } else { orderQueen1.addOrder(order); } } } } } public Long getLastPrice(String security) { return this.lastComplete.get(security); } }

public class OrderQueen { //最近完成的订单位置 private int lastCompleteIndex; private int lastInsertIndex; private int lastInsertCacheIndex; //归属价格级别 private long priceLevel; //订单队列 private Order[] orders; private Order[][] finishCache; public OrderQueen(long priceLevel) { this.priceLevel = priceLevel; orders = new Order[5000]; finishCache = new Order[500][]; lastCompleteIndex = -1; lastInsertIndex = 0; } private boolean needExpendOrderList() { return orders.length <= lastInsertIndex; } private void expand() { Order[] orders = new Order[5000]; this.finishCache[lastInsertCacheIndex] = this.orders; lastInsertCacheIndex++; this.orders = orders; lastInsertIndex = 0; lastCompleteIndex = -1; } public long getPriceLevel() { return priceLevel; } public synchronized void addOrder(Order order) { if (needExpendOrderList()) { expand(); } this.orders[lastInsertIndex] = order; lastInsertIndex++; } public synchronized Long try2ClinchOrder(Order order2Clinch) { Long clinchPrice = null; for (int index = lastCompleteIndex + 1; index < lastInsertIndex; index++) { Order order = this.orders[index]; long count; try { count = order2Clinch.getRemainCount() - order.getRemainCount(); } catch (NullPointerException e) { throw new NullPointerException(); } if (count < 0) { long completeCount = order.getRemainCount() - Math.abs(count); order2Clinch.addCompleteCount(completeCount); order2Clinch.complete(); order.addCompleteCount(completeCount); clinchPrice = order.getPrice(); break; } else if (count == 0) { order2Clinch.addCompleteCount(order.getRemainCount()); order2Clinch.complete(); order.addCompleteCount(order.getRemainCount()); order.complete(); clinchPrice = order.getPrice(); lastCompleteIndex++; break; } else { order2Clinch.addCompleteCount(order.getRemainCount()); order.addCompleteCount(order.getRemainCount()); order.complete(); clinchPrice = order.getPrice(); lastCompleteIndex++; } } return clinchPrice; } }

性能分析

  1. 减少每次对全部订单进行筛选排序,分出买卖单
  2. 针对国内涨跌幅限制,对价格进行分级,每个价格中订单按照时间排序

测试发现,50W的数据从原来的80000ms降低到100ms,效果显著,多线程测试亦无问题

如何建立回测系统(二)

如何建立回测系统(二)

一个简单的回放市场实现

public class MarketPlace {

    private Map<String, List<Order>> orderChannel;
    private Map<String, Long> lastComplete;

    public MarketPlace() {
        orderChannel = new ConcurrentHashMap<>();
        lastComplete = new ConcurrentHashMap<>();
    }

    public void order(Order order) {
        List<Order> list = orderChannel.get(order.getTradeCode());
        if (Objects.isNull(list)) {
            list = new ArrayList<>();
            orderChannel.put(order.getTradeCode(), list);
        }
        synchronized (list) {
            List<Order> targetPriceOrder;
            List<Order> sellOrder = list.stream()
                .filter(order1 -> !order1.isComplete())
                .filter(Order::sell)
                .sorted(Comparator.comparing(Order::getPrice)
                    .thenComparing(Order::getTimestamp))
                .collect(Collectors.toList());
            List<Order> buyOrder = list.stream()
                .filter(order1 -> !order1.isComplete())
                .filter(order1 -> !order1.sell())
                .sorted(Comparator.comparing(Order::getPrice, Comparator.reverseOrder())
                    .thenComparing(Order::getTimestamp))
                .collect(Collectors.toList());
            //进来的是买单
            if (!order.sell()) {
                if (!buyOrder.isEmpty() && buyOrder.get(0).getPrice() > order.getPrice()) {
                    list.add(order);
                    return;
                }
                //处理好后,是按照价格小,时间先排列
                targetPriceOrder = sellOrder.stream()
                    //需要找到挂单中比当前订单要价低或者相等的
                    .filter(order1 -> order.getPrice() <= order1.getPrice())
                    .collect(Collectors.toList());
            } else {
                if (!sellOrder.isEmpty() && sellOrder.get(0).getPrice() < order.getPrice()) {
                    list.add(order);
                    return;
                }
                //进来的是卖单,找买单 , 卖单进来,先开始撮合最高价的买单
                targetPriceOrder = buyOrder.stream()
                    //需要找到买单中比当前订单要价高的
                    .filter(order1 -> order.getPrice() <= order1.getPrice())
                    .collect(Collectors.toList());
                //新入订单需要撮合的数量
            }
            //新入订单需要撮合的数量
            long count = order.getRemainCount();
            //连续竞价,买单进来,开始先撮合最低价的卖单
            for (Order order1 : targetPriceOrder) {
                count = count - order1.getRemainCount();
                if (count < 0) {
                    //说明当前订单已经满足,order不需要进入队列排队,order1更新成交数,中断循环
                    order1.addCompleteCount(order1.getCount() - Math.abs(count));
                    order.addCompleteCount(order.getCount());
                    order.complete();
                    this.lastComplete.put(order.getTradeCode(), order.getPrice());
                    break;
                } else if (count == 0) {
                    //说明订单恰好满足,中断循环,将order1添加移除队列
                    order.addCompleteCount(order.getCount());
                    order1.addCompleteCount(order1.getCount());
                    order1.complete();
                    order.complete();
                    this.lastComplete.put(order.getTradeCode(), order.getPrice());
                } else {
                    //说明订单未满足,将order1添加移除队列,并继续循环
                    order1.complete();
                    order.addCompleteCount(order1.getRemainCount());
                }
                count = order.getRemainCount();
            }
            if (!order.isComplete()) {
                list.add(order);
            }
        }
    }

    public Long getLastPrice(String security) {
        return this.lastComplete.get(security);
    }

性能分析

最高对单个标的物单线程,且订单越多,处理速度越慢

T = f(m*n)

可能的优化点

  1. 减少每次对全部订单进行筛选排序,分出买卖单
  2. 针对国内涨跌幅限制,对价格进行分级,每个价格中订单按照实践排序
  3. 尽可能用基础类型

如何建立回测系统

如何建立回测系统

什么是回测

就是对市场的变化进行回放,加入我们的策略得出,如果我们参与其中会有怎么样的结果

如何回放

首先要了解平时我们说的股票当日价格是如何形成的

股票一旦出售后本身是没有价格的,在每个交易日开始前,交易所会进行集中竞价,最后取买卖集合中的笔数最多的价格作为当日的开盘价

紧接着开始连续竞价

连续竞价中,股票价格为股票的成交价,成交价如下定义:

1. 最高买进申报与最低卖出申报相同,则该价格即为成交价格;

2. 买入申报价格高于即时揭示的最低卖出申报价格时,以即时揭示的最低卖出申报价格为成交价

3. 卖出申报价格低于即时揭示的最高买入申报价格时,以即时揭示的最高买入申报价格为成交价

总结

若需要对股市状况进行回测,首先应该保存当日所有的订单情况,然后对价格进行撮合,若撮合成功,则此时可以算出当前价格

平时我们接受的数据成为股市交易的快照

其中记录着一段时间内的成交量,成交均价,成交总价格等的信息

近期总结

近期总结

问题

  1. 每个人都感觉自己非常忙却产出非常的少
  2. 从我这个角度观察,每天有大量的废话时间,尽管废话时间是与客户交流的
  3. 主管人员缺少决断却没有人能够站出来说背起责任
  4. 我仍然是缺少项目管理经验,同时还有分出时间来分析任务和分派任务至开发人员

问题的分析

  1. 从产出少的角度举个例子
    首先是我们的需求没有人做管理,每个人都围着需求说明书在转圈,没有一个富有项目管理经验的人能够明确的说,好的,我们这个文档做到这里,可以了,更多的情况是,你们这个文档不行啊,太不丰满,继续去摘要输入输出流程描述,不然对不起那几百万的钱。
    以上事实得出一个结论是,缺少文档管理及写作方面的人才
  2. 每个人都感觉自己非常忙
    这个的问题是我们前期参与项目的几个人,对着同一个文档,各自不同的部分,做了非常多的重复工作,举个例子是,客户的商品管理,前后出了十个版本,没有一个版本是和客户核对过的。
    这个问题的结论是,在缺乏项目管理经验的状态下,对于项目进度及内容的失控
  3. 废话时间这个问题
    废话指的是什么呢,是客户自己无意识中在发散,但是我们这边需求调研人员没有抓住自己的工作主要目的,亦即确认客户需求,客户天花乱坠的吹,我们静静的旁边听,或者是在旁边,嗯,是的,好的,没问题,您听我解释,而正常的情况应该是,大家针对目前的目标,针对性的,比如说630我们只要A需求落地上线,而A中需要拆分成几个不同的过程或者是需求,主导权应该要在我们开发系统的人手上。
    这个问题的结论是,主导项目管理开发的人员缺少决断,并且没有意识到整个项目的拖延是因为自己的没有决断导致的
  4. 缺少决断,没人背起责任,这就很清晰了,我在项目开展的第三周,反复提出,已有的不成熟的文档也最好能尽快和客户对接,通过客户的帮助来完成我们的文档,我的提议不一定是好的方案,但是却被很粗暴的驳回(三次),同组另一个同事也曾提出和我一样的意见,驳回的理由很苍白,我的做法是互联网做法,在我们公司不成立的,不能这样搞,在项目依旧进展缓慢的情况下,我其实也已经心灰意冷了,正常来说,在事情出了风险的情况下,只要能推进项目进度的做法都应该是可取的
    这个问题,我认为是领导在制度缺失的情况下,在压力下做出了不正确的做法,他在沿用了他曾经经历过的安全的做法
  5. 缺少项目管理经验,这个责任在我,我在这一个月内没有成长起来,例如CMMI实践操作文档我也是最近一周才去看

我提出的解决方案

  1. 从总公司抽调两个具有专门技能的人才
    1. 具有丰富的项目管理经验的人一名
    2. 具有现有框架开发及设计经验的人一名
  2. 需要以上人员扮演保姆或者是老师的角色
  3. 需要有个人提出来,出错在我,你们放心干