龙听期货论坛's Archiver

龙听 发表于 2024-1-29 16:21

MultiCharts投资组合交易者策略范例(MultiCharts Portfolio Trader Strategy Examples,PT范例):对冲策略(Spread Trading Strategy)

MultiCharts投资组合交易者策略范例(MultiCharts Portfolio Trader Strategy Examples,PT范例):对冲策略(Spread Trading Strategy)

策略描述

价差交易是一种将交易工具分成对,以相反方向进行交易的交易类型。这种类型的交易是指为一种工具开立多头头寸,同时开立另一种相反方向的头寸(空头)。这两个头寸同步开仓和平仓。

下面是一个例子。一个投资组合有两对工具: QQQ 对 SPY,KO 对 PEP。

当最近 20 个交易日的点差超过标准偏差值时,该策略将开立头寸。第二对工具同步进入与主要工具(第一对)相反的持仓。

策略开发

[b]Portfolio_SpreadTradingSystem.Master 信号[/b]

该信号根据品种的数据序列计算得出。它包含开仓和平仓逻辑持仓:[code]inputs: Ratio(c / c data2), Length(10), PercentOfEquity(10);
var: AvgRatio(0), StdDevRatio(0);
var: intrabarpersist cur_pos(0);
var: Contracts_(0);
Contracts_ = Portfolio_Equity * PercentOfEquity / 100;
if 1 < currentbar then begin
if AvgRatio + StdDevRatio < Ratio then begin// short data1, long data2
if -1 <> cur_pos then begin
sellshort Contracts_ contracts this bar at c;
cur_pos = -1;
end;
end else if AvgRatio - StdDevRatio > Ratio then begin// buy data1, short data2
if 1 <> cur_pos then begin
buy Contracts_ contracts this bar at c;
cur_pos = 1;
end;
end else begin
cur_pos = 0;
sell this bar c;
buytocover this bar c;
end;
end;
AvgRatio = XAverage(Ratio, Length);
StdDevRatio = StdDev(Ratio, Length);[/code]其他计算要求将该策略应用于符号组合,因此我们需要检查一下情况是否如此:[code]if 1 = getappinfo(aiisportfoliomode) then begin
// code
end;[/code]对于基本策略,我们需要返回第二个工具的策略索引,并检查是否已应用:[code]var: slave_idx(pmms_strategies_get_by_symbol_name(symbolname data2));
once if 0 > slave_idx then
raiseruntimeerror(text("specified slave trader on instrument", doublequote, symbolname data2, doublequote, "not found"));[/code]为了使两种工具的仓位投资资本同步,我们需要将主要工具当前仓位的价格发送到配对策略中:[code]value22 = absvalue(cur_pos*Contracts_) * c * bigpointvalue;
if 0 < value22 then
value22 = pmms_to_portfolio_currency(value22);
pmms_set_strategy_named_num(slave_idx, "MPMoney", -cur_pos * value22);[/code][b]Portfolio_SpreadTradingSystem.Slave 信号[/b]

该信号Portfolio_SpreadTradingSystem.Slave Signal是为交易对中的第二个工具计算的。它监控前一个信号 Portfolio_SpreadTradingSystem.Master Signal 为交易对主工具生成的所有进入和退出,并以相反方向进行交易。首先,当主策略返回的 MPMoney 变量发生变化时,所有同步工作都会完成。[code]value1 = pmms_from_portfolio_currency(pmm_get_my_named_num("MPMoney") );[/code]我们提取这一变量,并将其从投资组合货币转换为工具货币。然后,根据其值,我们计算潜在入市头寸的合约数:[code]value33 = c;
if marketposition <> 0 then
value33 = entryprice;
master_mp = IntPortion( value1 / ( value33 * bigpointvalue) );[/code]品种当前的持仓:[code]my_mp = currentcontracts*marketposition;[/code]现在,我们将检查其位置是否不同步。如果是,我们就将其与主策略同步:[code]if sign(my_mp) <> sign(master_mp) then begin
...
end;[/code]我们将检查品种的主持仓是否已结束:[code]if 0 = value1 then begin // need to close position
if my_mp > 0 then
sell all contracts this bar c
else
buytocover all contracts this bar c;
#return;
end;[/code]如果已经平仓,我们也将关闭第二个工具的仓位。如果主交易品种未平仓,我们将确定第二个交易品种的仓位方向:[code]if 0 < value1 then begin // buy[/code]Value1 > 0 表示我们应该同步买入头寸。可能有两种情况:

1.当前平仓或空头头寸应该变为多头头寸,即主策略反转了头寸或从平仓状态进入了多头头寸。
2.当前仓位已经是多头,这意味着第一个交易品种部分关闭了空头仓位,这意味着我们需要部分关闭第二个交易品种的仓位。[code]if Sign(master_mp) <> Sign(my_mp) then
buy absvalue(master_mp) contracts this bar c
else
buytocover value1 contracts this bar c;[/code]反之亦然:[code]end else begin
if Sign(master_mp) <> Sign(my_mp) then
sell short absvalue(master_mp) contracts this bar c
else
sell absvalue(value1) contracts this bar c;
end;[/code]Value1 < 0 表示我们需要卖出以同步仓位;也有两种情况:

1.当前平仓或多头头寸应变为空头头寸,即主策略已反转头寸或已从平仓状态进入空头头寸。
2.当前仓位已经是空头,这意味着第一个交易品种部分关闭了多头仓位,这意味着我们需要部分关闭第二个交易品种的仓位。

附录

默认情况下,投资组合信号脚本会添加到 MultiCharts 和 MultiCharts64 中。

龙听 发表于 2024-1-29 16:23

信号:Portfolio_SpreadTradingSystem.Master[code]inputs: Ratio(c / c data2), Length(10), PercentOfEquity(10);

var: AvgRatio(0), StdDevRatio(0);
var: intrabarpersist cur_pos(0);
var: Contracts_(0);

if (currentbar < Length) then #return;

Contracts_ = Portfolio_Equity * PercentOfEquity / 100;

if 1 < currentbar then begin
        if AvgRatio + StdDevRatio < Ratio then begin// short data1, long data2
                if -1 <> cur_pos then begin
                        sellshort Contracts_ contracts this bar at c;
                        cur_pos = -1;
                end;
        end else if AvgRatio - StdDevRatio > Ratio then begin// buy data1, short data2
                if 1 <> cur_pos then begin
                        buy Contracts_ contracts this bar at c;
                        cur_pos = 1;
                end;
        end else begin
                cur_pos = 0;
                sell this bar c;
                buytocover this bar c;
        end;
end;

AvgRatio = XAverage(Ratio, Length);
StdDevRatio = StdDev(Ratio, Length);

if 1 = getappinfo(aiisportfoliomode) then begin

        var: slave_idx(pmms_strategies_get_by_symbol_name(symbolname data2));
        once if 0 > slave_idx then
                raiseruntimeerror(text("specified slave trader on instrument ", doublequote, symbolname data2, doublequote, "not found"));

        value22 = absvalue(cur_pos*Contracts_) * c * bigpointvalue;
        if 0 < value22 then
                value22 = pmms_to_portfolio_currency(value22);

        pmms_set_strategy_named_num(slave_idx, "MPMoney", -cur_pos * value22);
end;
[/code]信号:Portfolio_SpreadTradingSystem.Slave[code]var: master_mp(0), my_mp(0);

value1 = pmms_from_portfolio_currency( pmm_get_my_named_num("MPMoney") ); // master's position cost. convert it to my contracts

value33 = c;
if marketposition <> 0 then
        value33 = entryprice;

master_mp = IntPortion( value1 / ( value33 * bigpointvalue) );
my_mp = currentcontracts*marketposition;

if sign(my_mp) <> sign(master_mp) then begin

        if 0 = value1 then begin // need close position
                if my_mp > 0 then
                        sell all contracts this bar c
                else
                        buytocover all contracts this bar c;
                #return;
        end;

        value2 = master_mp - my_mp;
       
        if 0 < value2 then begin // we must to buy
                if Sign(master_mp) <> Sign(my_mp) then // master in long, we are in short/flat
                        buy absvalue(master_mp) contracts this bar c
                else
                        buytocover value1 contracts this bar c;
        end else begin // we must sell
                if Sign(master_mp) <> Sign(my_mp) then // master in short, we are in long/flat
                        sell short absvalue(master_mp) contracts this bar c
                else
                        sell absvalue(value2) contracts this bar c;
        end;
end;


[/code]

龙听 发表于 2024-2-1 12:36

为了防止中文表达不到位,下面附上英文原文

龙听 发表于 2024-2-1 12:42

**** Hidden Message *****

页: [1]