• 一个完整的系统,必然会涉及到配置文件。配置文件可以是xml、属性文件等形式。大多数而言我们并不需要重写配置读取解析模块,只需要使用开源的即可,这里使用的是apapche.commons.configuration的。...

    转载须注明出处:http://blog.csdn.net/minimicall?viewmode=contentshttp://cloudtrade.top/

    一个完整的系统,必然会涉及到配置文件。配置文件可以是xml、属性文件等形式。大多数而言我们并不需要重写配置读取解析模块,只需要使用开源的即可,这里使用的是apapche.commons.configuration的。

    我们这里要说的是Cointrader的ConfigUtil类,它涉及到配置和注解成员之间的赋值等问题。

    下面通过代码学习:

    package org.cryptocoinpartners.util;
    
    import org.apache.commons.configuration.*;
    import org.apache.commons.configuration.tree.OverrideCombiner;
    import org.apache.commons.lang.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.annotation.Nullable;
    import java.io.File;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.io.StringWriter;
    import java.lang.reflect.Field;
    import java.lang.reflect.Modifier;
    import java.math.BigDecimal;
    import java.math.BigInteger;
    import java.net.URL;
    import java.util.*;
    
    
    /**
     * @author Tim Olson
     */
    @SuppressWarnings("UnusedDeclaration")
    public class ConfigUtil {
    
        public static CombinedConfiguration combined() { return combined; }
    
        public static PropertiesConfiguration defaults() { return defaultConfig; }
        public static PropertiesConfiguration user() { return userConfig; }
        public static PropertiesConfiguration buildtime() { return buildtimeConfig; }
        public static SystemConfiguration system() { return sysConfig; }
        public static MapConfiguration commandLine() { return clConfig; }
    
    
        /**
         * Finds all non-static members tagged with @Config and populates them with the current combined() configuration
         * 额,这个注释是错误的。不仅仅是@Config吧。就是素有的非静态成员的注解
         */
        public static void applyConfiguration( Object instance ) {
            Class<?> cls = instance.getClass();
            for( Field field : cls.getFields() ) {
                Config annotation = field.getAnnotation(Config.class);
                if( annotation != null )
                    inject(combined(), instance, field, annotation);
            }
        }
    
    
        /**
         * Examines injectee for any setters or fields marked with @Config, then sets those fields to values from the
         * Configuration object.
         */
        public static void applyConfiguration(Object injectee, Configuration config) {
            Class<?> cls = injectee.getClass();
            for( Field field : cls.getFields() ) {
                Config annotation = field.getAnnotation(Config.class);
                if( annotation != null )
                    inject((AbstractConfiguration) config, injectee, field, annotation);
            }
        }
    
    
        public static void init(String filename, Map<String,String> commandLine ) throws ConfigurationException {
            boolean loadUserPropertiesFile = new File(filename).exists();
            if( !loadUserPropertiesFile  )
                log.warn("Could not find configuration file \"" + filename + "\"");
            clConfig = new MapConfiguration(commandLine);
            sysConfig = new SystemConfiguration();
            if( loadUserPropertiesFile )
                userConfig = new PropertiesConfiguration(filename);
            else
                userConfig = new PropertiesConfiguration();
            URL defaultProps = ConfigUtil.class.getResource("/cointrader-default.properties");//加载配置文件
            if( defaultProps == null )
                throw new ConfigurationException("Could not load cointrader-default.properties");
            defaultConfig = new PropertiesConfiguration(defaultProps);
            URL buildtimeProps = ConfigUtil.class.getResource("/org/cryptocoinpartners/buildtime.properties");
            if( buildtimeProps == null )
                throw new ConfigurationException("Could not load buildtime.properties");
            buildtimeConfig = new PropertiesConfiguration(buildtimeProps);
            combined = buildConfig(Collections.<AbstractConfiguration>emptyList());
            if( log.isDebugEnabled() )
                log.debug("Combined Configuration:\n"+ asString(combined));
        }
    
    
        public static CombinedConfiguration forModule(Object... keyValuePairs) {
            if( keyValuePairs.length % 2 != 0 )
                throw new Error("Configuration parameters must be key-value pairs.  Found an odd number.");
            HashMap<String,Object> map = new HashMap<>();
            for( int i = 0; i < keyValuePairs.length; i++ )
                map.put(keyValuePairs[i++].toString(),keyValuePairs[i]);
            return forModule(Collections.singletonList(new MapConfiguration(map)));
        }
    
    
        public static CombinedConfiguration forModule(Collection<? extends AbstractConfiguration> moduleConfigs) {
            CombinedConfiguration result = buildConfig(moduleConfigs);
            if( log.isDebugEnabled() )
                log.debug("Module Configuration:\n"+ asString(result));
            return result;
        }
    
    
        public static List<String> getPathProperty(String pathProperty) {
            CombinedConfiguration config = combined();
            return getPathProperty(config, pathProperty);
        }
    
    
        public static List<String> getPathProperty(CombinedConfiguration config, String pathProperty) {
            String modulePath = config.getString(pathProperty, "");
            List<String> paths = new ArrayList<>(Arrays.asList(modulePath.split(":")));
            paths.add("org.cryptocoinpartners.module");
            paths.remove("");
            return paths;
        }
    
    
        private static CombinedConfiguration buildConfig(Collection<? extends AbstractConfiguration> intermediateConfigs) {
            final CombinedConfiguration result = new CombinedConfiguration(new OverrideCombiner());
            result.addConfiguration(buildtimeConfig); // buildtime config cannot be overridden
            result.addConfiguration(clConfig);
            result.addConfiguration(sysConfig);
            for( AbstractConfiguration moduleConfig : intermediateConfigs )
                result.addConfiguration(moduleConfig);
            if( !userConfig.isEmpty() )
                result.addConfiguration(userConfig);
            result.addConfiguration(defaultConfig);
            return result;
        }
    
    
        public static String asString(Configuration configuration) {
            StringWriter out = new StringWriter();
            PrintWriter pout = new PrintWriter(out);
            ConfigurationUtils.dump(configuration, pout);
            try {
                pout.close();
                out.close();
            }
            catch( IOException e ) {
                throw new Error(e);
            }
            ArrayList<String> outLines = new ArrayList<>();
            for( String line : out.toString().split("\n") ) {
                if( !isSecret(line) )
                    outLines.add(line);
            }
            Collections.sort(outLines);
            return StringUtils.join(outLines,"\n");
        }
    
    
        protected static boolean isSecret(String line) {
            return line.contains("password") || line.contains("secret");
        }
    
    
        private static void inject(@Nullable Object instance, Field field ) {
            inject(combined(), instance, field, null);
        }
    
    
        private static void inject(AbstractConfiguration configuration, @Nullable Object instance, Field field, @Nullable Config configAnnotation ) {
            if( instance == null && !Modifier.isStatic(field.getModifiers()) )//如果instance为null或者该数据成员为静态的,则不可赋值
                return;
    
            if( Modifier.isFinal(field.getModifiers()) ) {//该数据成员是final修饰的,不可以修改。
                log.warn("Field " + field.getDeclaringClass().getName()+"."+field.getName() + " is tagged with @Config but is declared final.  Config for this field failed.");
                return;
            }
            if( configAnnotation == null )//如果configAnnotation为null,则直接获取field的注解。
                configAnnotation = field.getAnnotation(Config.class);
            String key = null;
            if( configAnnotation != null )
                key = configAnnotation.value();//标注的值作为键
            if( key == null )
                key = field.getName();//如果标注没有值,那么直接拿数据成员的名字作为键
            Config classConfigAnnotation = field.getDeclaringClass().getAnnotation(Config.class);//获取成员声明所在类的注解,即类注解
            if( classConfigAnnotation != null )
                key = classConfigAnnotation.value() + "." + key;//用“.”号连接类注解和成员注解
            Object value = getDynamic(field.getType(), configuration, key);//获取该注解对应配置的值
            if( value != null ) {
                try {
                    field.set(instance, value);//将值反射注入到instance对象的改数据成员中。
                    if( log.isDebugEnabled() ) {
                        // hide values marked as passwords
                        String printValue = isSecret(key) ? "**-hidden-**" : field.get(instance).toString();
                        log.debug("Set field " + field.getDeclaringClass()
                                                      .getName() + "." + field.getName() + " to " + printValue);
                    }
                }
                catch( IllegalAccessException e ) {
                    log.error("Could not set config on field " + field.getDeclaringClass().getName() + "." + field.getName(),e);
                }
            }
        }
    
    
        public static <T> T getDynamic(Class<T> resultType, AbstractConfiguration configuration, String key) {
            return getDynamic(resultType, configuration, key, null);
        }
    
    //从配置文件中读取属性值
        @SuppressWarnings("unchecked")
        public static <T> T getDynamic(Class<T> resultType, AbstractConfiguration configuration, String key, T defaultValue) {
            if( resultType.isAssignableFrom(String.class) )
                return (T) configuration.getString(key, (String) defaultValue);
            else if( resultType.isAssignableFrom(Boolean.class) || resultType.isAssignableFrom(Boolean.TYPE) )
                return (T) configuration.getBoolean(key, (Boolean) defaultValue);
            else if( resultType.isAssignableFrom(Long.class) || resultType.isAssignableFrom(Long.TYPE) )
                return (T) configuration.getLong(key, (Long) defaultValue);
            else if( resultType.isAssignableFrom(Integer.class) || resultType.isAssignableFrom(Integer.TYPE) )
                return (T) configuration.getInteger(key, (Integer) defaultValue);
            else if( resultType.isAssignableFrom(Short.class) || resultType.isAssignableFrom(Short.TYPE) )
                return (T) configuration.getShort(key, (Short) defaultValue);
            else if( resultType.isAssignableFrom(Byte.class) || resultType.isAssignableFrom(Byte.TYPE) )
                return (T) configuration.getByte(key, (Byte) defaultValue);
            else if( resultType.isAssignableFrom(Double.class) || resultType.isAssignableFrom(Double.TYPE) )
                return (T) configuration.getDouble(key, (Double) defaultValue);
            else if( resultType.isAssignableFrom(Float.class) || resultType.isAssignableFrom(Float.TYPE) )
                return (T) configuration.getFloat(key, (Float) defaultValue);
            else if( resultType.isAssignableFrom(List.class) )
                return (T) configuration.getList(key, (List) defaultValue);
            else if( resultType.isAssignableFrom(BigDecimal.class) )
                return (T) configuration.getBigDecimal(key, (BigDecimal) defaultValue);
            else if( resultType.isAssignableFrom(BigInteger.class) )
                return (T) configuration.getBigInteger(key, (BigInteger) defaultValue);
    
            throw new IllegalArgumentException("Cannot cast configuration values to "+resultType.getName());
        }
    
    
        private static PropertiesConfiguration defaultConfig;
        private static PropertiesConfiguration buildtimeConfig;
        private static PropertiesConfiguration userConfig;
        private static MapConfiguration clConfig;
        private static SystemConfiguration sysConfig;
        private static CombinedConfiguration combined;
        private static Logger log = LoggerFactory.getLogger(ConfigUtil.class);
    }
    
    我们首先来分析inject函数,它实现的是一个将配置中值注入到对应对象的成员变量中去。

    在这里我们补一下获取一个成员的注解的知识:学习代码如下:

    package com.yiibai;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.reflect.Method;
    
    // declare a new annotation
    @Retention(RetentionPolicy.RUNTIME)
    @interface Demo {
    
       String str();
    
       int val();
    }
    
    public class PackageDemo {
    
       // set values for the annotation
       @Demo(str = "Demo Annotation", val = 100)
       // a method to call in the main
       public static void example() {
          PackageDemo ob = new PackageDemo();
    
          try {
             Class c = ob.getClass();
    
             // get the method example
             Method m = c.getMethod("example");
    
             // get the annotation for class Demo
             Demo annotation = m.getAnnotation(Demo.class);
    
             // print the annotation
             System.out.println(annotation.str() + " " + annotation.val());
          } catch (NoSuchMethodException exc) {
             exc.printStackTrace();
          }
       }
    
       public static void main(String args[]) {
          example();
       }
    }
    让我们来编译和运行上面的程序,这将产生以下结果:
    
    Demo Annotation 100


    下面还有一个getResource去读取一个文件:

    我们引用(抄袭)一个很好很简单的帖子:http://blog.csdn.net/lcj8/article/details/3502849

    class.getResource()的用法
    用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还是掌握颇浅,用起来感觉颇深,大常最经常用的,就是用JAVA的File类,如要取得c:/test.txt文件,就会这样用File file = newFile("c:/test.txt");这样用有什么问题,相信大家都知道,就是路径硬编码,对于JAVA精神来说,应用应该一次成型,到处可用,并且从现实应用来讲,最终生成的应用也会部署到Windows外的操作系统中,对于linux来说,在应用中用了c:/这样的字样,就是失败,所以,我们应该尽量避免使用硬编码,即直接使用绝对路径。 


      在Servlet应用中,有一个getRealPath(String str)的方法,这个方法尽管也可以动态地获得文件的路径,不秘直接手写绝对路径,但这也是一个不被建议使用的方法,那么,我们有什么方法可以更好地获得文件呢? 


         那就是Class.getResource()与Class.getResourceAsStream()方法,但很多人还是不太懂它的用法,因为很多人(比如不久前的我)都不知道应该传怎么样的参数给它,当然,有些人己经用得如火纯青,这些人是不需要照顾的,在此仅给不会或者还不是很熟的人解释一点点。 




    比如我们有以下目录 
    |--project 
        |--src 
            |--javaapplication 
                |--Test.java 
                |--file1.txt 
            |--file2.txt 
        |--build 
            |--javaapplication 
                |--Test.class 
                |--file3.txt 
            |--file4.txt 


    在上面的目录中,有一个src目录,这是JAVA源文件的目录,有一个build目录,这是JAVA编译后文件(.class文件等)的存放目录 
    那么,我们在Test类中应该如何分别获得 
    file1.txt file2.txt file3.txt file4.txt这四个文件呢? 


    首先讲file3.txt与file4.txt 
    file3.txt: 
    方法一:File file3 = new File(Test.class.getResource("file3.txt").getFile()); 
    方法二:File file3 = new File(Test.class.getResource("/javaapplication/file3.txt").getFile()); 
    方法三:File file3 = new File(Test.class.getClassLoader().getResource("javaapplication/file3.txt").getFile()); 


    file4.txt: 
    方法一:File file4 = new File(Test.class.getResource("/file4.txt").getFile()); 
    方法二:File file4 = new File(Test.class.getClassLoader().getResource("file4.txt").getFile()); 


    很好,我们可以有多种方法选择,但是file1与file2文件呢?如何获得? 
    答案是,你只能写上它们的绝对路径,不能像file3与file4一样用class.getResource()这种方法获得,它们的获取方法如下 
    假如整个project目录放在c:/下,那么file1与file2的获取方法分别为 
    file1.txt 
    方法一:File file1 = new File("c:/project/src/javaapplication/file1.txt"); 
    方法二:。。。没有 


    file2.txt 
    方法一:File file2 = new File("c:/project/src/file2.txt"); 
    方法二:。。。也没有 


    总结一下,就是你想获得文件,你得从最终生成的.class文件为着手点,不要以.java文件的路径为出发点,因为真正使用的就是.class,不会拿个.java文件就使用,因为java是编译型语言嘛 


    至于getResouce()方法的参数,你以class为出发点,再结合相对路径的概念,就可以准确地定位资源文件了,至于它的根目录嘛,你用不同的IDEbuild出来是不同的位置下的,不过都是以顶层package作为根目录,比如在Web应用中,有一个WEB-INF的目录,WEB-INF目录里面除了web.xml文件外,还有一个classes目录,没错了,它就是你这个WEB应用的package的顶层目录,也是所有.class的根目录“/”,假如clasaes目录下面有一个file.txt文件,它的相对路径就是"/file.txt",如果相对路径不是以"/"开头,那么它就是相对于.class的路径。。 


    还有一个getResourceAsStream()方法,参数是与getResouce()方法是一样的,它相当于你用getResource()取得File文件后,再new InputStream(file)一样的结果 


       


    class.getResource("/") --> 返回class文件所在的顶级目录,一般为包名的顶级目录。 --> file:/home/duanyong/workspace/cxxx/xxxx/bin/WEB-INF/classes/ 
    class.getResource("/xxx.txt") --> 返回顶级目录下的xxx.txt路径。 file://..../bin/WEB-INF/classes/xxx.txt 


    getResource(String path),path是以class文件的顶级目标所在的相对路径。如果顶级目录为classes,在classes/xxx/yyy.txt这样一个文件。取得yyy.txt的语法为:class.getResource("/xxx/yyy.txt"); 


    示例代码: 
    查看复制到剪切板打印
    //取得classes顶级目录下的/xxx/yyy.txt文件   
    System.out.println(Test.class.getResource("/xxx/yyy.txt"));   
    //取得本class的上路径   
    System.out.println(Test.class.getResource(Test.class.getSimpleName() + ".class"));          
    [Java] view plaincopy
    //取得classes顶级目录下的/xxx/yyy.txt文件  
    System.out.println(Test.class.getResource("/xxx/yyy.txt"));  
    //取得本class的上路径  
    System.out.println(Test.class.getResource(Test.class.getSimpleName() + ".class"));          






    结果: 
    file:/home/duanyong/workspace/test/bin/WEB-INF/classes/xxx/yyy.txt 
    file:/home/duanyong/workspace/test/bin/WEB-INF/classes/cn/duanyong/test/Test.class



    展开全文
  • 有人说如果能穿越时空,我炒股一定赚钱,花时间研究股票还不如研究高能物理。找找时空扭曲的虫洞,或者找找月光宝盒埋在哪里也行,穿梭回来肯定是赚大钱。 ...fm=170&s=D12AF65A7AA53932D7A50202030060D7&...
    有人说如果能穿越时空,我炒股一定赚钱,花时间研究股票还不如研究高能物理。找找时空扭曲的虫洞,或者找找月光宝盒埋在哪里也行,穿梭回来肯定是赚大钱。

    [img]http://f12.baidu.com/it/u=2054315231,4216850115&fm=170&s=D12AF65A7AA53932D7A50202030060D7&w=640&h=143&img.JPEG&access=215967316[/img]

    这里我抛出这样一个试验,假设我从一年前穿越到现在知道某只股票在某一个时间段里面走的很好,完全可以赚钱,然后我再穿越回去,模拟一般散户的炒股行为,遇到一点点风吹草动,或者自己心理上有些变化,就不断的进进出出,看看效果是怎样的。
    下图是中国平安601318,从16年2月到现在的日k线图:

    [img]http://f11.baidu.com/it/u=3173536069,1839165797&fm=170&s=21513BC2DBA4BB6004D1090B0200E0C2&w=640&h=186&img.JPEG&access=215967316[/img]

    显然是个主升浪,如果你从16年2月持有股票到现在,那你就赚到了一笔。然而这不现实,你在这么长时间里,免不了要进进出出。
    那随机的买卖会是什么效果呢,就让我来测试一下:
    这是在raquant平台上的Java代码,有兴趣可以瞅一眼:

    [img]http://f11.baidu.com/it/u=471118204,3573185945&fm=170&s=18C1A14C5AE4936C0C69540F0000E0C2&w=640&h=396&img.JPEG&access=215967316[/img]

    这段代码就好像模拟了一个像我这样的量化小白的交易过程,隔几天看一次股盘,自己瞎摸索一番,决定买进或卖出。这样随意的炒股能赚到的概率有多大呢?我拿这段代码来回溯一下,回溯十次,结果如下:
    第一次:

    [img]http://f10.baidu.com/it/u=1981941147,4216302915&fm=170&s=2350CD321F2A552000F405D6030070B3&w=640&h=227&img.JPEG&access=215967316[/img]


    第二次:
    [img]http://f12.baidu.com/it/u=833070782,4023866844&fm=170&s=6350C532852A652050D405C60300E0B3&w=640&h=228&img.JPEG&access=215967316[/img]

    第三次:
    [img]http://f11.baidu.com/it/u=2726867644,1287280975&fm=170&s=0350ED329F2A552258F405D60300F0B3&w=640&h=222&img.JPEG&access=215967316[/img]


    第四次:
    [img]http://f10.baidu.com/it/u=1274037264,3787485176&fm=170&s=4350CD328F2A452050F405D60300B0B3&w=640&h=230&img.JPEG&access=215967316[/img]

    第五次:
    [img]http://f11.baidu.com/it/u=643965757,3698845671&fm=170&s=5150CD33852A452000F415D6030070B3&w=640&h=228&img.JPEG&access=215967316[/img]


    可以看到,[b]几乎都是要亏的节奏啊,回溯5次亏了4次[/b],作为在A股当中表现相当好的股票如此,更别说普遍的情况下这个几率会是怎样。因此,选股固然重要,但选了上好的股之后仍不可随意买卖,没有理性的策略作为指导,结果还是亏钱。

    说到这里,我得说一说量化交易,量化交易之所以存在,是因为感觉往往是靠不住的,而量化交易则是不依赖直觉和情感的前提下总结股市的各种规律,寻找一种理性的交易策略。采用量化交易的方式,哪怕这次交易失败了,亏了,还可以总结原因,修改策略后不断尝试,直到找到适合自己的策略。我想,每个炒股爱好者都不应该拒绝学习和使用这种方式。

    [url]http://www.raquant.com/[/url] RaQuant镭矿是一个集量化交易策略的学习、研究、开发、交易于一体的强大平台。致力于帮助有简单编程基础或投资基础的投资者快速入门,并可以高效的开发量化交易策略,帮助投资者进行更有效的分析决策。
    www.raquant.com拥有自带的一系列拷贝即可使用的策略,在镭矿平台编写5个以上策略可拥有申请策略实盘的权利。快来试试吧。
    展开全文
  • 深度学习是机器学习的一个新的领域,它基于多层神经网络对数据中的高级抽象进行建模,其动机在于建立、模拟人脑进行分析学习的神经网络,模仿人脑的机制来解释数据。从市场微观结构的角度来说,股票价格的形成和变化

    阅读原文:club.jr.jd.com/quant/to


    京东金融官方资讯QQ:3414182370 有什么想问的想说的都可以来参与!还有机会获取奖品!

    深度学习是机器学习的一个新的领域,它基于多层神经网络对数据中的高级抽象进行建模,其动机在于建立、模拟人脑进行分析学习的神经网络,模仿人脑的机制来解释数据。从市场微观结构的角度来说,股票价格的形成和变化是由买卖双方的交易行为决定的,对高频市场行情数据利用深度学习方法进行挖掘可以获得对未来股票价格走势有预测能力的模式。借鉴广发证券《深度学习之股指期货日内交易策略大数据——深度学习系列之一》(下文简称为报告一)和《深度学习算法掘金ALPHA因子——大数据深度学习系列之二》(下文简称为报告二),分享一下深度学习在量化投资策略的两个方向——择时策略和Alpha策略上的应用。

    在短线预测方面,西蒙斯的壁虎式投资理论告诉我们,投资时在短线内是可以进行方向性预测,捕捉到短期套利机会的。基于深度学习的交易策略就是借助于深度学习对大量的历史交易数据进行学习,建立预测模型,从而在实际交易中捕捉到短期的交易机会。一般的,预测时间间隔越短的话,机器学习模型的预测能力会越强。报告一考虑股指期货的1秒级高频数据。在预测模型输入的选择上,选择短期内的股票价格,价格的变化范围,买卖盘价格和委卖委买量等。预测模型的输出是未来短期内的涨跌方向。当深度学习预测模型训练好之后,给出两条交易准则:第一,给定阈值,只有达到或超过阈值的预测得分才会触发买卖信号;第二,交易中的开仓和平仓都由买卖信号触发。具体的交易策略如图一所示。通过股指期货高频价格预测模型的实证研究,报告一验证了深度学习这一大数据时代的机器学习利器在股票价格预测上的有效性,基于预测模型提出的股指期货交易策略也取得了良好的效果。


    图1:基于深度学习的短线预测交易策略

    在Alpha策略方面,选取因子时要使得所选因子在一定的操作周期内具有较大的Alpha,即超额收益。如果某因子与股票未来一段时间内的投资收益直接相关,则该因子可以作为Alpha策略的备选因子。基于深度学习的交易策略就是借助于深度学习对大量的历史交易数据进行学习,建立预测模型,从而获取Alpha因子,即深度学习模型的预测得分。报告二提出的基于深度学习的Alpha策略如图二所示。综合考虑到模型预测的准确程度和交易成本,报告二考虑的是以周为换仓周期的多因子策略,预测模型也选择以周为预测周期,即在每天收盘的时刻进行预测,每次预测的对象都是该交易日之后第5个交易日收盘时刻股价相对于当前收盘价的涨跌情况。采取滚动预测的方式来建立深度学习模型,即每年训练一次模型,用来预测此后的股票涨跌幅,如图三。根据前面的预测模型,可以获得个股在T=5个交易日之后大幅上涨预测的得分ScoreUp和大幅下跌预测的得分ScoreDown,由此可以建立起类似多因子选股模型的交易策略。实证分析中,在组合规模为100的情况下,该多因子Alpha策略累积收益率超过120%,各年度收益率都超过15%,超越了传统的Alpha因子。


    图二:基于深度学习的Alpha因子策略


    图三:基于深度学习的滚动预测模型

    但是深度学习对于数据数量要求较大,对数据质量要求较高,并且可能存在过拟合问题,因而在策略构建时如何选取数据、调参、减小过拟合的问题是有待进一步探讨的。

    阅读原文:club.jr.jd.com/quant/to

    关注京东量化学院!获取更多最新最全面的量化交易知识!

    quant.jd.com/college/in

    展开全文
  • 开头先说好,这篇文章算是个广告 以上三张图是我目前用的参数跑的EOS品种的回测数据,分别是全年历史数据、18年1月开始的数据、6月开始的数据,回测数据是 bitfinex 交易所的。...强调下,策略最终收益那里不...

    开头先说好,这篇文章算是个广告

    历史数据
    一年数据
    半年数据

    以上三张图是我目前用的参数跑的EOS品种的回测数据,分别是全年历史数据、18年1月开始的数据、6月开始的数据,回测数据是 bitfinex 交易所的。

    强调下,策略最终收益那里不需要在后面加百分号,第二张图里面就是八个月多月的时间31倍…

    这几个指标的计算公式列在这里:

    年化收益率:(账户最终价值/账户初始价值)^(365/回测期间总天数)-1
    
    上涨概率:上涨天数 / 回测交易日数量
    
    收益波动率:账户日收益的年化标准差
    
    夏普比:(账户年化收益率-无风险利率)/ 收益波动率
    

    经历

    很早以前就听说过量化交易,却从来不知道这具体是什么,只知道,能赚钱。

    具体的情况还要推到七月份实习的时候,在公司没有很有挑战性的事情做,每天最大的盼头就是下班后逛吃逛吃,为了抑制住自己在上班的时候看电影,暗中决定找到一件具有挑战性的事情,思索中,想起来以前学习 CAPM 模型时的一个公众号打过的广告,遂再次打开去仔细看上面的文字,发现似乎很靠谱,然后发现居然还有数字货币的量化课程,这不专门就是为我准备的嘛,当然光看广告词是不行的,加上微信浏览作者的朋友圈,发现作者的确是一位实战经历丰富的人,在互联网时代如何快速地认识一个陌生人?浏览他的朋友圈、微博、文章等等。

    交学费后就开始学习,首先就开始学习 python ,这方面老师很贴心,课程中教我们下载 anaconda 和 pycharm ,这点要比什么优达的 python 课程好,一般网上的课程都是从入门到放弃,至少这个课程里入门很平易,其后就是教我们基础操作了,基础讲完后就是 pandas 这个库了,总体来说入门很平易,可能是我有基础的原因,不过毕竟我学校里开设的 C 语言课程期末得分61…不知道这个结果证明了学校老师无法吸引我兴趣还是这个课讲得好…

    第一个遇到的困难是SCI-SURF(科学上网),首先,我需要花钱买服务器,服务器是真的贵,买个好服务器都够我再买套课程送给正在阅读的你了。这个我是真的花了很长时间,首先它是必须的,大多数交易所都需要 SCI-SURF(bitfinex\binance), OKEX 的 API 也需要,其次现在网上对此比较敏感,我看了很多相关的 CSDN 都 404 了,阿里云的服务器是不让作为此用途使用的,这个东西我是扯到了九月初,将近一个月,课都看完了,就是无法实践,这个最终解决方法是录课的老师帮我远程服务器帮我搞定了,在此感谢这位老师。

    就这样我可以 SCI-SURF后很快就弄出了在 OKEX 上的自动交易系统,策略是均线策略,这个回测收益就一般般了,由于 OKEX 不提供杠杆的 API ,所以收益更加有限,主要是用来表示我能实盘跑策略了,跑了十几天可以正常运行就停了,将里面的钱转到 bitfinex 准备进行下一个战斗。

    说到 bitfinex ,这应该是第二个困难,大家有相关经验的都知道,这交易所不支持开户后就交易,你要想在这里新开户交易,账户余额就必须先达到 10000 美元的市值,资产品种不限,但是需要达到 10000 美元,这不是个小数啊,一万美刀,可是群里面就有提供相关服务的群友,手续费几百块钱而已,真的是市场中有需求就有供给。

    第三个困难就是搭建 bitfinex 的自动交易系统了,之前很快搭建了 OKEX 是因为本来就有示范代码,稍微改改就可以用,但是 bitfinex 的就不一样了,有这么几个点,一是 bitfinex 有两个版本的 API ,二是获取账户信息所需要的数据和 OKEX 大大不同,三是 margin 交易需要考虑的情况多了做空的选项,再加上实盘跑的时候暴露出来代码的问题有不少,有兴趣了解可以看我的 CSDN 。

    以上就是这两个月的经历了,从 python 的入门到服务器的搭建再到交易系统的实盘,还真是花了不少功夫,另外这个课程的讨论群氛围很好,既有技术方面的也是市场方面的,再放一张我为了问问题而截的图。

    收获

    1. python 入门,掌握 pandas 这个库(九月初还利用 python 摸索着解决了整合报名表信息的工作);
    2. 实盘量化交易,搭建了一个有效率的自动交易系统;
    3. 激发了对量化交易的兴趣,课程虽然只讲了布林线趋势策略,但燃起了对量化领域探索的兴趣;
    4. 更新了对市场的认知。

    P.S. 不代理财、保管资金
    在这里插入图片描述

    展开全文
  • 量化交易系统的开发

    2019-10-06 22:08:52
    量化投资策略与技术> 三.开发前思考 1.计算机-金融-数学,知识比重为1-3-6 2.用java还是python写都可以,架构方面没太大区别,java的interface用python的abc库一样可以实现。但是java的库比较少 3.对...

    一.架构

    我设计的架构图大概如下:

     

    二.参考

     

    <海龟交易法则>

    vnpy

    期货职业资格考试丛书

    <量化投资策略与技术>

     

    三.开发前思考

    1.计算机-金融-数学,知识比重为1-3-6
    2.用java还是python写都可以,架构方面没太大区别,java的interface用python的abc库一样可以实现。但是java的库比较少
    3.对于CTA交易,策略最重要,性能、代码不太重要。高频交易,性能比较重要.策略需要集中信号管理型和资金管理型的优点.
    4.经典的策略,比如Hans123和海龟交易法则及其优化方式,需要非常熟悉
    5.机器学习只是锦上添花,可以不考虑。
    6.实盘交易盈利的策略实现程序化才有价值.
    7.没有经历过几次爆仓的交易员是成长不起来的.
    8.谨记三条:第一,及时止损;第二,资金仓位管理;第三,纪律最重要,心态就是纪律.
    9.回测必须覆盖单边上涨,单边下跌,区间震荡三种走势
    10.策略在实盘使用前最好找历史上和期货的最近几天走势类似的回测下

     

    四.开发后思考


    1.回测框架怎么设计,兼容不同的第三方数据来源,不同的策略回测,下单交易引擎,不同的第三方实盘交易所,不同的数据存储方式
    2.回测框架需要考虑稳定,已读,扩展性。
    3.均线,海龟,多周期,多种指标信号,布林海盗系统,各种策略最好都回测一遍,熟悉内部实现。
    4.交易前需要判断当前是趋势还是震荡盘,趋势需要追涨杀跌,盘整盘做高抛低吸,策略正好相反。
    5.趋势盘是容易程序量化抓住的。盘整盘怎么做,比趋势难把握。
    6.选择合适的交易周期,1分钟线会频繁的交易,虽然大部分交易是盈利的,但是高昂的手续费会吞噬掉盈利,三分钟
    或者长一点的周期,根据交易品种判断,不是一致的。
    7.根据哪种指标做动态止盈,绝对值还是,均线,kd,需要考虑。
    8.资金管理根据技术信号做,还是固定手数,差别挺大的。建议固定手数。
    9.回测是否覆盖了牛市,熊市,猴市。大的震荡,小的震荡。
    10.同一时间,多个指标发出买入信号,是否同时加仓,控制加仓过快的问题。
    11.最麻烦的,回测数据来源的问题。RQData,JQData,Wind,还是EMQuantApi,数据的质量,脏数据是很头疼的问题。
    12.交易系统和券商交易软件计算出来的指标值不同,需要手动算下是数据的问题,还是计算方式,周期不同的问题。
    13.语言是用java,c++,还是python,R。大部分量化平台的接口,策略会给python,c++的接口,建议二选一。
    14.做CTA,Alpha选股还是套利,高频,需要一步步升级打怪,从易到难.

    展开全文
  • 开源量化交易框架整理: https://www.oschina.net/p/samaritan https://www.oschina.net/p/vn-py https://www.oschina.net/p/abu https://www.oschina.net/p/abuquant https://github.com/sun0x00/RedTorch ...
  • 完结篇:java学习心得 这是一篇与技术无关却是我最想写的博文,除了对这段时间写java的感触外还想表达一下我对学习的认知。 所思即所得,思想就是力量 我是看传智的课学的java,其中印象比较深的有张孝祥...
  • 1. java学习网站 之前在很多学习网站上学习过Java,踩过很多坑,今天给大家推荐一个比较好用的Java学习网站,希望大家能少踩坑 Java教程 | 项目实践一站式java学习 这个网站的针对性强,如果你是想学习Java,在这个...
  • http://how2j.cn?p=16567这是网址,网站里有Java基础,Java常用框架、Maven项目管理、Git版本管理、Redis缓存、Nginx负载均衡等,另外站长怕大家不...还有趋势投资量化项目,喜欢量化投资的可以学习这部分。 Ja...
  • 国内的量化交易发展也非常迅猛,机构在用,期货高手也在用,参与量化交易的人越来越多。但周围也有很多对量化交易感兴趣的手工交易者。刚开始信心满满,等看完即冗长又复杂的代码后,往往又望而却步,或者浅尝辄止。...
  • 下载: http://www.cis.hut.fi/research/lvq_pak/ 来源:http://www.cis.hut.fi/research/
  • 对于初接触java的童鞋,更快的掌握一些学习方法,对以后的java学习是很有用的。今天小编就为大家整理了Java学习的几个注意要点,概括了在Java开发、测试、部署、工程化方面一些需要注意的地方,相信一定对大家有帮助...
  • 阿布量化交易系统

    2018-07-27 11:41:19
    第0节 abupy量化环境 作者: 阿布 abu能够帮助用户自动完善策略,主动分析策略产生的交易行为,智能拦截策略生成的容易失败的交易单。 现阶段的量化策略还是人工编写的代码,abu量化交易系统的设计将会向着由计算机...
  • 量化的软件推荐:python常用的量化软件有python、matlab、java、C++。从开发难度而言python和matlab都比较容易,java和C++麻烦一些。从运行速度而言,C++、java要快于matlab和python。不过对于大部分人而言,尤其是...
  • 本课程主要分享从零搭建区块链量化交易平台(包括Java后端、Web端、App端)的过程、途中遇到的问题及解决方法,帮助想尝试量化交易的战友的少走弯路,更有效率的提升自己的能力。同时也分享一些个人在量化交易领域的...
  • [外链图片转存失败(img-DIoohcEI-1563773035585)(D:\Wangdb\Typora\Typora图片\量化交易平台.jpg)] 这是2016年的数据,现在呢? 排名 项目 Star 开发语言 分类 1 zipline 9180 Python 策略回测框架 2 vnpy...
  • 现在市面上比较流行的量化平台除了京东量化平台,还有优矿,聚宽,米筐等。这些平台大体上提供类似的服务,但在细节上又有所不同。 量化平台的服务本质在于通过封装好的回测函数和金融数据库,帮助用户快捷的实现...
  • 量化干货:量化交易系统设计的六大细节https://blog.csdn.net/myquant/article/details/86001858一、常见的入场模式 一般常用的入场模式不外乎两种,一种是事先确定一个价格,当盘中最新价格达到或者超过这个价格...
  • 当我们开发了一个交易策略,需要对...为了将之前学习量化交易的知识点贯穿起来,更好地巩固学习内容,也为了今后能够搭建适合自己的框架,本篇手记我们就来了解下如何自定义量化交易回测框架。 完成一个策略的回测...
  • Java学习路线

    2017-11-15 16:57:04
    2017年初BAT的JAVA面试题汇集互联网+的浪潮下诞生了大批量的O2O企业,2016年火了直播,红了AI,不管是产品还是技术,互联网行业热闹程度都不亚于时尚圈的潮流更替。互联网资本寒冬到第二年,有人冬眠有人冬泳。而IT技术...
1 2 3 4 5 ... 20
收藏数 9,648
精华内容 3,859