- 在线时间
- 1 小时
- 最后登录
- 2017-3-24
- 注册时间
- 2017-3-23
- 听众数
- 7
- 收听数
- 1
- 能力
- 0 分
- 体力
- 2 点
- 威望
- 0 点
- 阅读权限
- 10
- 积分
- 1
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 0
- 主题
- 0
- 精华
- 0
- 分享
- 0
- 好友
- 1
升级   20% 该用户从未签到 - 自我介绍
- 程序员
 |
本帖最后由 littleDream 于 2017-3-23 18:11 编辑 / O f' ]) X* X0 D2 ` B4 g
. u6 C: c0 A- s" K5 ?& x1 h
### 实现一个多品种并发的商品期货策略(8)2 g* |1 U8 y* x( W- s/ @0 _
[: z4 I3 O. v4 W0 S# a> 当一把造物主,做个程序员真好!实现 《商品期货多品种海龟策略》机器人
8 g; B# E- @6 }9 Z" C( p& S% I) E2 @4 ]% q6 S
- #### 海龟交易法起源
$ O: z9 v4 W' F2 X0 T+ M, a' E) B" e( y7 M: t+ V! a
这个交易系统的诞生来源与两个交易老手的争论,一方觉得交易这种技能是后天习得的,另一方觉得这是先天所决定的。1983年,在新加坡海龟农场,两位神一样的交易员Dennis、Eckhardt有了分歧。E神说,交易员是天生的;D神说,就像这一大缸海龟一样,交易员可以培养。( T. c4 P/ i: a' S- V1 c8 m0 T8 c
+ v* I7 O9 K$ i- c( p2 P$ ]4 w: ?8 A 于是,D神掏出来白花花的银子,要做实验,要打赌。他们在华尔街日报、纽约时报等等放出广告,说D神要搞培训班了,给每个人100万美元的账户,手把手地教,不限专业,无须经验,皆可报名。有千余人投了简历,40人进入面试,23人被留下考察,13人进入培训班。- x$ z8 E6 T+ s
% m# m& R' U: A5 |7 A 这13个人来自各行各业,多数都没有交易经验,是一群尚未成功的普通人。他们被培训了两个星期,然后放出去交易,在接下来的四年半里,创出了80%的年均收益率。培训内容,叫做《海龟交易法则》;培训学员,被称为“海龟”。& r4 o$ T, q9 s( f* D. N4 a" L
7 |! |% F1 b3 z6 C# z7 Z7 ` 尽管有人质疑样本的随机性,这场试验应该算D神胜利了。
% ?6 L! T% N6 P2 c1 f& l: e" ~% h( ?4 y7 ^
- #### 海龟交易系统是一个完整的交易系统,它有一个完整的交易系统所应该有的所有成分,涵盖了成功交易中的每一个必要决策:
: {; l/ Q& E$ Y# p; N0 O! v3 h9 l+ E0 R c0 T3 l. d1 q8 _* w
市场:买卖什么?/ U+ q. z! E/ H2 E/ e
头寸规模:买卖多少? Unit=(1%∗Account)/N* e, D/ [: P: j0 r
入市:什么时候买卖?
# @$ b7 J3 A# z# t- s 止损:什么时候放弃一个亏损的头寸?
1 S: C5 R6 M" z, b: o# r 退出:什么时候退出一个盈利的头寸?
3 l/ g. H/ N0 l; U X: k( P 战术:怎么买卖?
! j; c \8 _4 V8 Z! O; x 核心围绕: N值,海龟的止损、加仓、头寸规模 都是基于N值计算, 有些海龟交易系统用的是ATR来代替N值,ATR为真实波幅的20日平均。
L0 m* {9 F7 ` `& Y8 ?& d& Z6 \ “海龟们从不去预测市场的动向,而是会寻找市场处于某种特定状态的指示信号。优秀的交易者不会试着预测市场下一步会怎么样;相反,他们会观察指示信号,判断市场现在正处于什么样的状态中。”
% Z6 p7 X# c: Z. C8 s
7 P8 {1 ~. l/ A W 对于 “海龟交易法”感到陌生的读者可以看这篇文章:
4 S8 }6 o7 O. q8 [ 也可以 知乎 或者 百度 搜索,有很多文章介绍,老白就不做赘述了。
: e8 i, |# k8 D# q
! \4 z8 {! W; m0 }# Y% t - #### 作为 本系列文章的最后收尾一篇,我们就来动手实践一个海龟策略,当然我们要有创新,我们实现一个“海龟群”。 E0 x3 ^ x) |7 _5 {% b5 T; v
* R( X; D& \: ]6 B( D 说点题外的,之前的几篇文章记录的都是老白当时学习时的心路历程,学习量化、程序化没办法一蹴而就,只能脚踏实地,耐住性子一点点进步。老白开始的时候也感觉思考问题、找BUG 、写程序晕头转向的。但是,慢慢的我发现学习是个加速度,开始很慢,积累越多越轻松。一个完全零基础的朋友经常和我说:“越是感觉自己要放弃的时候,越是应该跟困难死磕的时候!”
& N- q+ n- y% C! o$ Y7 ?
- Q7 @' f, ?) F0 k 言归正传, 为什么我们要使用海龟群呢?
9 Y$ H9 c2 ^) z1 G6 K$ k. \ 当然是为了尽可能的分散风险,即使是大名鼎鼎的海龟策略,当年也曾经有过大幅回撤,甚至亏损本金。任何交易系统都是有一定风险的。多品种的好处就是“把鸡蛋放在不同的篮子里”。当然也有缺点,那就是需要不小的资金量。资金量小了,可能只能交易几个品种,降低了分散风险的能力。
4 r' T/ _3 i5 L3 c 还有一点需要牢记:任何时候都可能飞出一只黑天鹅! (如商品期货 16年底黑色星期五 全线暴跌。)( K1 c9 v1 G! V: P" }
) w8 b- f% o j+ s* G+ |
注释版源代码:# q) @: \+ F4 \: e- y8 [( D
```
3 k7 L) y5 d g, @- s6 Q( p9 P2 D/*
w2 q/ { a2 m# p9 y( h/ t3 h参数:
, d2 Y$ q9 g+ WInstruments 合约列表 字符串(string) MA701,CF701,zn1701,SR701,pp1701,l1701,hc1610,ni1701,i1701,v1701,rb1610,jm1701,ag1612,al1701,jd1701,cs1701,p1701
5 l I8 K- A) m m# G8 S& @LoopInterval 轮询周期(秒) 数字型(number) 3
' ~/ G7 q d6 @/ r- R& O( WRiskRatio % Risk Per N ( 0 - 100) 数字型(number) 1
% _4 h5 g. K2 b) gATRLength ATR计算周期 数字型(number) 20
: D W3 ]1 W* g+ z z, E' c- bEnterPeriodA 系统一入市周期 数字型(number) 20& I) Y" O" \" `% r( E1 M* B8 h
LeavePeriodA 系统一离市周期 数字型(number) 105 H; G- Q! |9 C6 w3 a$ D
EnterPeriodB 系统二入市周期 数字型(number) 55
* p) \5 ~/ a7 x1 h) q$ V' jLeavePeriodB 系统二离市周期 数字型(number) 20
( K, F& \: d1 C1 q$ U# B: i5 kUseEnterFilter 使用入市过滤 布尔型(true/false) true
7 `8 l( W" s. jIncSpace 加仓间隔(N的倍数) 数字型(number) 0.5+ }, B8 h9 E5 T. R. J7 G
StopLossRatio 止损系数(N的倍数) 数字型(number) 2
6 D! C* d5 O& [$ r. WMaxLots 单品种加仓次数 数字型(number) 4" z, N \* ~; y
RMode 进度恢复模式 下拉框(selected) 自动|手动
8 o# U5 q: }1 [/ i% W2 iVMStatus@RMode==1 手动恢复字符串 字符串(string) {}* B2 u9 |+ r, a0 \1 u6 Q
WXPush 推送交易信息 布尔型(true/false) true
4 l7 p3 O8 z& e, C7 FMaxTaskRetry 开仓最多重试次数 数字型(number) 5
( ?6 }. [# v' N( G" FKeepRatio 预留保证金比例 数字型(number) 10
6 a! h* }7 p7 }7 b( r3 S" L2 a7 ~*/
% U+ H* y* b3 \8 r3 N# l# V4 o
6 A1 C7 \) q" M. z7 Q8 O* I' mvar _bot = $.NewPositionManager(); // 调用CTP商品期货交易类库 的导出函数 生成一个用于单个品种交易的对象
4 m4 X. k; p; u* |8 _: f) s% q2 H# P5 Y {" S, L
var TTManager = { // 海龟策略 控制器
! W( w+ I7 d/ d0 ~! N" A New: function(needRestore, symbol, keepBalance, riskRatio, atrLen, enterPeriodA, leavePeriodA, enterPeriodB, leavePeriodB, useFilter,
1 B* S2 ]2 U6 A0 T multiplierN, multiplierS, maxLots) {4 v% s2 O, a4 P* U) O& V! T$ @
// 该控制器对象 TTManager 的属性 New 赋值一个 匿名函数(构造海龟的函数,即:构造函数),用于创建 海龟任务,参数分别是:2 |$ f+ z$ ^( P, j7 B( r* K
// needRestore: 是否需要恢复,symbol:合约代码,keepBalance:必要的预留的资金,riskRatio:风险系数, atrLen:ATR指标(参数)周期。enterPeriodA:入市周期A
7 Y" P! T3 T- _ `( r8 O9 s // leavePeriodA:离市周期A , enterPeriodB:入市周期B, leavePeriodB:离市周期B,useFilter:使用过滤,multiplierN:加仓系数,multiplierS:止损系数,maxLots:最大加仓次数
; Z+ |0 W5 g$ p3 j1 m
`( h2 h4 u" H3 M( U, a // subscribe
# R# P, H: a5 P9 j% e9 q var symbolDetail = _C(exchange.SetContractType, symbol); 2 x- O2 Y5 u- @- ?1 j0 R
// 声明一个局部变量 symbolDetail 用于接受API SetContractType 函数的返回值(值为symbol的合约的详细信息,symbol 是 "MA709",返回的就是甲醇709合约的详细信息),
7 f, H4 j! g9 Z // 调用API SetContractType 订阅并切换合约为 symbol 变量值的合约。 _C() 函数的作用是 对 SetContractType 合约容错处理,即如果 SetContractType返回null 会循环重试。
5 J" ]0 B* x5 Y# i2 n if (symbolDetail.VolumeMultiple == 0 || symbolDetail.MaxLimitOrderVolume == 0 || symbolDetail.MinLimitOrderVolume == 0 || symbolDetail.LongMarginRatio == 0 || symbolDetail.ShortMarginRatio == 0) {1 d2 A% U8 r" g; y A0 |) _
// 如果 返回的合约信息对象symbolDetail 中 VolumeMultiple、MaxLimitOrderVolume 等数据异常,则调用 throw 抛出错误,终止程序。0 ^% x+ r2 s# O# ^4 A5 i: p
Log(symbolDetail);" a5 Z" z: D: G
throw "合约信息异常";
[" f7 i8 L+ f0 H6 z/ v/ C } else { // 检索的数据没有异常则,输出部分合约信息。
+ c: h, O- e1 R7 K$ ~! J% g* U; ^ Log("合约", symbolDetail.InstrumentName, "一手", symbolDetail.VolumeMultiple, "份, 最大下单量", symbolDetail.MaxLimitOrderVolume, "保证金率:", _N(symbolDetail.LongMarginRatio), _N(symbolDetail.ShortMarginRatio), "交割日期", symbolDetail.StartDelivDate);$ S7 \0 \% q x. n* M9 t2 k7 e. |& h
}* }( M0 X. x1 W; d4 S
( S$ {* T, \3 e' p4 H var ACT_IDLE = 0; // 定义一些宏 (标记), P, T- ~/ w* Y4 f( ^
var ACT_LONG = 1;* x0 \) \6 v) ~. m& r6 @
var ACT_SHORT = 2;
( t1 q5 J5 b4 \ var ACT_COVER = 3; // 动作宏
2 W0 I* R: d, l6 L3 E3 `
- I/ ^. `8 X3 y9 ~2 R( X
' u7 p- h* J! d% [ var ERR_SUCCESS = 0; // 错误宏; L% Y S: k3 W
var ERR_SET_SYMBOL = 1;! n" @8 o0 L9 M" ]' j
var ERR_GET_ORDERS = 2;% z) |: q9 N/ d) c6 B- A6 o% T
var ERR_GET_POS = 3;
& S& W4 k/ R ` var ERR_TRADE = 4;
, S. _" N- e1 z3 g* H9 q+ e* W7 y1 e var ERR_GET_DEPTH = 5;
! {5 D2 {2 v- T var ERR_NOT_TRADING = 6;7 n9 g! J5 L1 I4 D% F
var errMsg = ["成功", "切换合约失败", "获取订单失败", "获取持仓失败", "交易下单失败", "获取深度失败", "不在交易时间"]; // 错误宏的值 对应该数组的索引,对应索引的值就是翻译# X3 Z) X+ L* u7 x, }* s* ^6 M9 @
2 p- L4 T M8 \ var obj = { // 声明一个对象,构造完成后返回。单个的海龟策略控制对象。
5 _5 Y2 V+ o, ^& x x: Q5 T: z: s& S symbol: symbol, // 合约代码 构造函数执行时的参数传入6 }" t L& `, u: I+ T9 m! R( [
keepBalance: keepBalance, // 预留的资金 构造函数执行时的参数传入6 z' M) t# O* m. t& \
riskRatio: riskRatio, // 风险系数 构造函数执行时的参数传入
& r1 ?: b9 ]( k7 G0 k% I: \ q0 F atrLen: atrLen, // ATR 长度 构造函数执行时的参数传入
) K h6 L3 O7 E' N enterPeriodA: enterPeriodA, // 入市周期A 构造函数执行时的参数传入
$ V* n5 e% `% _ leavePeriodA: leavePeriodA, // 离市周期A 构造函数执行时的参数传入# f* h. ^0 q3 N6 _; v; k5 v
enterPeriodB: enterPeriodB, // 入市周期B 构造函数执行时的参数传入2 u1 g% p# r/ \% Y" u
leavePeriodB: leavePeriodB, // 离市周期B 构造函数执行时的参数传入' m* W6 _4 Y. Q- k% L+ ~" E
useFilter: useFilter, // 使用入市过滤条件 构造函数执行时的参数传入
2 N6 j7 r- j0 q% d$ L+ L. [, ~ multiplierN: multiplierN, // 加仓系数 基于N 构造函数执行时的参数传入; d$ \7 p' X# T- t+ w. _
multiplierS: multiplierS // 止损系数 基于N 构造函数执行时的参数传入
8 K( b$ F! B' G/ J& c9 L };
. M ^! j5 M2 v# ] 代码太长,限制发不了,喜欢的可以看原文 : ![]()
; R2 c+ a% ?9 S# o' l3 G
& X" G: H0 y* k l0 Z4 v$ q) _# M4 {+ U* o
, `# |4 c1 {( o/ v: c$ d |
zan
|