UID 2 积分 2874674 威望 1387366 布 龙e币 1487308 刀 在线时间 13156 小时 注册时间 2009-12-3 最后登录 2024-11-24
为方便对比,这里把java、python两种语言代码同时贴出,回测时间及初始资金均使用页面默认的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;
//计算最大最小值
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;
}
//计算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;
}
//计算止损线价位
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) -> {
//获取组合总价值,包含市场价值与剩余资金
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计算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;
});
}
} 复制代码
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 复制代码
论坛官方微信、群(期货热点、量化探讨、开户与绑定实盘)
期货论坛 - 版权/免责声明
1.本站发布源码(包括函数、指标、策略等)均属开放源码,用意在于让使用者学习程序化语法撰写,使用者可以任意修改语法內容并调整参数。仅限用于个人学习使用,请勿转载、滥用,严禁私自连接实盘账户交易 。
2.本站发布资讯(包括文章、视频、历史记录、教材、评论、资讯、交易方案等)均系转载自网络主流媒体,内容仅为作者当日个人观点,本网转载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网不对该类信息或数据做任何保证。不对您构成任何投资建议,不能依靠信息而取代自身独立判断,不对因使用本篇文章所诉信息或观点等导致的损失承担任何责任。
3.本站发布资源(包括书籍、杂志、文档、软件等)均从互联网搜索而来,仅供个人免费交流学习,不可用作商业用途,本站不对显示的内容承担任何责任。请在下载后24小时内删除。如果喜欢,请购买正版,谢谢合作!
4.龙听期货论坛原创文章属本网版权作品,转载须注明来源“龙听期货论坛”,违者本网将保留追究其相关法律责任的权力。本论坛除发布原创文章外,亦致力于优秀财经文章的交流分享,部分文章推送时若未能及时与原作者取得联系并涉及版权问题时,请及时联系删除。联系方式:http://www.qhlt.cn/thread-262-1-1.html