日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

海龜交易系統(tǒng)的Python完全版 | RiceQuant米筐量化社區(qū) 交易策略論壇

 pangQ 2017-06-30

@zhaoyang-chen 海龜?shù)腜ython版出爐。
為方便對(duì)比,這里把java、python兩種語言代碼同時(shí)貼出,回測(cè)時(shí)間及初始資金均使用頁面默認(rèn)的20140104-20150104,100000.0軟妹幣。

turtle_java

public class TurtleOriginalStrategy implements IHStrategy {
  Core talibCore;

//定義全局變量
  static int tradedayNum = 0;
  static double unit = 0;
  static double atr = 0;
  static String tradingSignal = "start";
  static String preTradingSignal = "";
  static int units_hold_max = 4;
  static int units_hold = 0;
  static double quantity = 0;
  static double max_add = 0;
  static double firstOpenPrice = 0;
  
  //計(jì)算最大最小值
  public double[] getExtremem(double[] arrayHighPriceResult, double[] arrayLowPriceResult) {
      DescriptiveStatistics forMax = new DescriptiveStatistics();
      for (int i = 0; i < arrayHighPriceResult.length-1; i++) {
          forMax.addValue(arrayHighPriceResult[i]);
      }
      double maxResult = forMax.getMax();
      
      DescriptiveStatistics forMin = new DescriptiveStatistics();
      for (int i = 0; i < arrayLowPriceResult.length-1; i++) {
          forMin.addValue(arrayLowPriceResult[i]);
      }
      double minResult = forMin.getMin();
      
      double[] forExtremum = new double[2];
      forExtremum[0] = maxResult;
      forExtremum[1] = minResult;
      return forExtremum;
  }
  //計(jì)算Atr以及單位
  public double[] getAtrAndUnit(double[] atrArrayResult, MInteger atrLengthResult, double portfolioValueResult) {
      double atr = atrArrayResult[atrLengthResult.value-1];
      double unit = Math.floor(portfolioValueResult * .01 / atr);
      double[] atrAndUnit = new double[2];
      atrAndUnit[0] = atr;
      atrAndUnit[1] = unit;
      return atrAndUnit;
  }
  //計(jì)算止損線價(jià)位
  public double getStopPrice(double firstOpenPriceResult, int units_hold_result, double atrResult) {
      double stopPrice =  firstOpenPriceResult - 2*atrResult + (units_hold_result-1)*0.5*atrResult;
      return stopPrice;
  }
  
  
 
  @Override
  public void init(IHInformer informer, IHInitializers initializers) {
    
    talibCore = new Core();
    
    
    int openObserveTime = 55;
    int closeObserveTime = 20;
    int atrTime = 20;
    MInteger atrBegin = new MInteger();
    MInteger atrLength = new MInteger();

    
    String stockId = "CSI300.INDX";
    initializers.instruments((universe) -> universe.add(stockId));
    
    
    initializers.events().statistics((stats, info, trans) -> {

        //獲取組合總價(jià)值,包含市場(chǎng)價(jià)值與剩余資金
        double portfolioValue = info.portfolio().getPortfolioValue();
        
        
        double[] highPrice = stats.get(stockId).history(openObserveTime+1, HPeriod.Day).getHighPrice();
        double[] lowPriceForAtr = stats.get(stockId).history(openObserveTime+1, HPeriod.Day).getLowPrice();
        double[] lowPriceForExtremem = stats.get(stockId).history(closeObserveTime+1, HPeriod.Day).getLowPrice();
        double[] closePrice = stats.get(stockId).history(openObserveTime+2, HPeriod.Day).getClosingPrice();
        
        double closePriceForAtr[] = new double[closePrice.length-1];
        for (int i = 0; i < closePrice.length-1; i++) {
            closePriceForAtr[i] = closePrice[i];
        }
        
       
        double[] atrArray = new double[openObserveTime];
        //Talib計(jì)算N即ATR
        RetCode retCode = talibCore.atr(0, openObserveTime-1, highPrice, lowPriceForAtr, closePriceForAtr, atrTime, atrBegin, atrLength, atrArray);
        
        
        double max = getExtremem(highPrice, lowPriceForExtremem)[0];
        double min = getExtremem(highPrice, lowPriceForExtremem)[1];
        
        
        double atr = atrArray[atrLength.value-1];
        
        informer.info(lowPriceForExtremem[lowPriceForExtremem.length - 1]);
        informer.info("#######");
        informer.info(max);
        informer.info(min);
        informer.info(atr);
        informer.info("#######");
        
        if (tradingSignal != "start") {
            if (units_hold != 0) {
            max_add += 0.5 * getAtrAndUnit(atrArray, atrLength, portfolioValue)[0];
            }
        } else {
            max_add = stats.get(stockId).getLastPrice();
        }
        
        informer.info(units_hold);
        
        double curPosition = info.position(stockId).getNonClosedTradeQuantity();
        double availableCash = info.portfolio().getAvailableCash();
        double marketValue = info.portfolio().getMarketValue();
        
        
        if (curPosition > 0 & stats.get(stockId).getLastPrice() < getStopPrice(firstOpenPrice, units_hold, atr)) {
            tradingSignal = "stop";
        } else {
            if (curPosition > 0 & stats.get(stockId).getLastPrice() < min) {
                tradingSignal = "exit";
            } else {
                if (stats.get(stockId).getLastPrice() > max_add & units_hold != 0 & units_hold < units_hold_max & availableCash > stats.get(stockId).getLastPrice()*unit) {
                    tradingSignal = "entry_add";
                } else {
                    if (stats.get(stockId).getLastPrice() > max & units_hold == 0) {
                        max_add = stats.get(stockId).getLastPrice();
                        tradingSignal = "entry";
                    }
                }
            }
        }
        
        //informer.info(tradingSignal);
        
        atr = getAtrAndUnit(atrArray, atrLength, portfolioValue)[0];
        if (tradedayNum % 5 == 0) {
            unit = getAtrAndUnit(atrArray, atrLength, portfolioValue)[1];
        }
        tradedayNum += 1;
        
        double quantity = unit;
        
        
        if (tradingSignal != preTradingSignal | (units_hold < units_hold_max & units_hold > 1) | tradingSignal == "stop") {
            
            
            if (tradingSignal == "entry") {
                quantity = unit;
                if (availableCash > stats.get(stockId).getLastPrice()*quantity) {
                    trans.buy(stockId).shares(quantity).commit();
                    firstOpenPrice = stats.get(stockId).getLastPrice();
                    units_hold = 1;
                    informer.info("entrybuy" + quantity);
                }
            }
            if (tradingSignal == "entry_add") {
                quantity = unit;
                trans.buy(stockId).shares(quantity).commit();
                units_hold += 1;
                informer.info("entry_addbuy" + quantity);
            }
            
            
            if (tradingSignal == "stop") {
                if (/*curPosition marketValue*/ units_hold > 0) {
                    trans.sell(stockId).shares(quantity).commit();
                    units_hold -= 1;
                    informer.info("stop" + quantity);
                }
            }
            if (tradingSignal == "exit") {
                if (curPosition > 0) {
                    trans.sell(stockId).shares(curPosition).commit();
                    units_hold = 0;
                    informer.info("exitsell" + curPosition);
                }
            }
            
        }
        
        preTradingSignal = tradingSignal;
    
    });
      
  }
}

結(jié)果:

java.PNG

turtle_python

import numpy as np
import talib
import math

def getExtremem(arrayHighPriceResult, arrayLowPriceResult):
    np_arrayHighPriceResult = np.array(arrayHighPriceResult[:-1])
    np_arrayLowPriceResult = np.array(arrayLowPriceResult[:-1])
    maxResult = np_arrayHighPriceResult.max()
    minResult = np_arrayLowPriceResult.min()
    return [maxResult, minResult]
    
def getAtrAndUnit(atrArrayResult, atrLengthResult, portfolioValueResult):
    atr = atrArrayResult[atrLengthResult-1]
    unit = math.floor(portfolioValueResult * .01 / atr)
    return [atr, unit]
    
def getStopPrice(firstOpenPriceResult, units_hold_result, atrResult):
    stopPrice =  firstOpenPriceResult - 2*atrResult + (units_hold_result-1)*0.5*atrResult
    return stopPrice


def init(context):
    context.tradedayNum = 0
    context.unit = 0
    context.atr = 0
    context.tradingSignal = 'start' 
    context.preTradingSignal = ''
    context.units_hold_max = 4
    context.units_hold = 0
    context.quantity = 0
    context.max_add = 0
    context.firstOpenPrice = 0
    context.s = 'CSI300.INDX'
    update_universe([context.s])
    context.openObserveTime = 55;
    context.closeObserveTime = 20;
    context.atrTime = 20;

def handle_bar(context, bar_dict):
    portfolioValue = context.portfolio.portfolio_value
    highPrice = history(context.openObserveTime+1, '1d', 'high')[context.s]
    lowPriceForAtr = history(context.openObserveTime+1, '1d', 'low')[context.s]
    lowPriceForExtremem = history(context.closeObserveTime+1, '1d', 'low')[context.s]
    closePrice = history(context.openObserveTime+2, '1d', 'close')[context.s]
    closePriceForAtr = closePrice[:-1]
    
    atrArray = talib.ATR(highPrice.values, lowPriceForAtr.values, closePriceForAtr.values, timeperiod=context.atrTime)
    
    maxx = getExtremem(highPrice.values, lowPriceForExtremem.values)[0]
    minn = getExtremem(highPrice.values, lowPriceForExtremem.values)[1]
    atr = atrArray[-2]
    

    if (context.tradingSignal != 'start'):
        if (context.units_hold != 0):
            context.max_add += 0.5 * getAtrAndUnit(atrArray, atrArray.size, portfolioValue)[0]
    else:
        context.max_add = bar_dict[context.s].last
        
    
    curPosition = context.portfolio.positions[context.s].quantity
    availableCash = context.portfolio.cash
    marketValue = context.portfolio.market_value
    
    
    if (curPosition > 0 and bar_dict[context.s].last < minn):
        context.tradingSignal = 'exit'
    else:
        if (curPosition > 0 and bar_dict[context.s].last < getStopPrice(context.firstOpenPrice, context.units_hold, atr)):
            context.tradingSignal = 'stop'
        else:
            if (bar_dict[context.s].last > context.max_add and context.units_hold != 0 and context.units_hold < context.units_hold_max and availableCash > bar_dict[context.s].last*context.unit):
                context.tradingSignal = 'entry_add'
            else:
                if (bar_dict[context.s].last > maxx and context.units_hold == 0):
                    context.max_add = bar_dict[context.s].last
                    context.tradingSignal = 'entry'
                    
                
    atr = getAtrAndUnit(atrArray, atrArray.size, portfolioValue)[0]
    if context.tradedayNum % 5 == 0:
        context.unit = getAtrAndUnit(atrArray, atrArray.size, portfolioValue)[1]
    context.tradedayNum += 1
    context.quantity = context.unit
    
    
    
    if (context.tradingSignal != context.preTradingSignal or (context.units_hold < context.units_hold_max and context.units_hold > 1) or context.tradingSignal == 'stop'):
        
        if context.tradingSignal == 'entry':
            context.quantity = context.unit
            if availableCash > bar_dict[context.s].last*context.quantity:
                order_shares(context.s, context.quantity)
                context.firstOpenPrice = bar_dict[context.s].last
                context.units_hold = 1
                
                
        if context.tradingSignal == 'entry_add':
            context.quantity = context.unit
            order_shares(context.s, context.quantity)
            context.units_hold += 1
            
            
        if context.tradingSignal == 'stop':
            if (context.units_hold > 0):
                order_shares(context.s, -context.quantity)
                context.units_hold -= 1
                
                
        if context.tradingSignal == 'exit':
            if curPosition > 0:
                order_shares(context.s, -curPosition)
                context.units_hold = 0
                
                
    context.preTradingSignal = context.tradingSignal

結(jié)果:

python.PNG

PLUS:

1.沒用到python的一些黑法術(shù)的情況下java代碼190行,python代碼120行。
2.java編譯小貓耳朵猛抖8下,python編譯小貓耳朵猛抖了13下。
1391060635175.jpg

回測(cè)收益回測(cè)年化收益基準(zhǔn)收益AlphaBetaSharpe最大回撤
31.685%32.190%56.904%0.03660.45372.5366-3.720%
Created with Highstock 4.2.4縮放1月3月6月1年全部2014-01-062014-12-31 累計(jì)收益2014-022014-042014-062014-082014-102014-12-10.00%-5.00%0%5.00%10.00%15.00%20.00%25.00%30.00%35.00%40.00%45.00%50.00%55.00%60.00%65.00%

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多