龙听期货论坛's Archiver

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

MultiCharts投资组合交易者策略范例(MultiCharts Portfolio Trader Strategy Examples,PT范例):轮动策略(Rotation Strategy)

MultiCharts投资组合交易者策略范例(MultiCharts Portfolio Trader Strategy Examples,PT范例):轮动策略(Rotation Strategy)

该策略由 kbeary33 在 MultiCharts 论坛 ([url=http://www.multicharts.com/discussion/viewtopic.php?f=19&t=45413]http://www.multicharts.com/discussion/viewtopic.php?f=19&t=45413[/url]) 上提出。

策略描述

轮动策略是一种简单的策略,通过使用投资组合中的每种工具来计算特定指标。为指标值最佳的工具品种建仓。

以变化率指标为例。这组工具由用户在投资组合交易应用程序中确定。进入多头头寸的工具品种数量由 BuyBestX 输入配置。标准止损 + 盈利目标策略用于退出头寸。

策略开发

Portfolio_Rotation 信号

该信号为投资组合中的所有工具生成输入指令并计算指标值。

指标公式输入到输入栏中,并在每个条形图上进行计算。[code]inputs:
Formula (PercentChange(close, 14));
variables: formulaValue(0);
formulaValue = Formula;[/code]为了进一步比较并决定输入位置,然后将公式输入全局变量:[code]pmm_set_my_named_num ("RotationalValue", formulaValue);[/code]生成所有工具品种的进场:[code]buy("LE") next bar market;
sellshort("SE") next bar market;[/code]为了管理资本,将使用用户设置的标准投资组合设置,即每份合约保证金和每份合约潜在损失:[code]pmm_set_my_named_num("MoneyCostForInvestPerCtrct", pmms_to_portfolio_currency(MoneyCostForInvestPerCtrct));[/code][code]var: PotentialEntryPrice(close), MoneyCostForInvestPerCtrct(0);
if (entryprice > 0) then PotentialEntryPrice = entryprice;
MoneyCostForInvestPerCtrct =
pmms_calc_money_cost_for_entry_per_cntrct(PotentialEntryPrice, Portfolio_GetMarginPerContract)
+
pmms_calc_money_cost_for_entry_per_cntrct(PotentialEntryPrice, Portfolio_GetMaxPotentialLossPerContract);[/code]计算一手价格值时,该值将转换为投资组合货币,并写入投资组合全局变量。[code]pmm_set_my_named_num("MoneyCostForInvestPerCtrct", pmms_to_portfolio_currency(MoneyCostForInvestPerCtrct));[/code]以投资组合资本的百分比为单位设定的标准止损和盈利目标将用于退出。[code]inputs: StopLossPcntsOfPortfolio(0.1),
ProfitTargetPcntsOfPortfolio(0.1);
variable: value(0);
setstopposition;
value = StopLossPcntsOfPortfolio * 0.01 * Portfolio_Equity;
setstoploss(convert_currency(datetime[0], portfolio_CurrencyCode, SymbolCurrencyCode, value));
value = ProfitTargetPcntsOfPortfolio * 0.01 * Portfolio_Equity;
setprofittarget(convert_currency(datetime[0], portfolio_CurrencyCode, SymbolCurrencyCode, value));[/code]Portfolio_Rotation_MM 信号

该信号用作投资组合中的资金管理信号。该研究会验证所有投资组合工具的指标值,并管理开仓。开仓的投资组合工具数量由用户设定:[code]inputs:
BuyBestX(10),
SellWorstY(10);[/code]将提取所有策略的指标值,并创建每次计算的指标值排序列表。为此,我们需要使用包含指标值和策略索引的二维数组:[code]variables: idx(0), strategyIdx(0), strategyValue(0);
arrays: allStrategies[10000, 1](-1);[/code]在每次计算被拒绝之前生成进场指令:[code]pmms_strategies_deny_entries_all;[/code]在数组中填入指标值和每个策略的索引,然后按值对数组进行排序:[code]for strategyIdx = 0 to pmms_strategies_count - 1 begin
strategyValue = pmms_get_strategy_named_num(strategyIdx, "RotationalValue");
allStrategies[strategyIdx , 0] = strategyValue;
allStrategies[strategyIdx , 1] = strategyIdx;
end;
Sort2DArrayByKey(allStrategies, pmms_strategies_count, 1);[/code]让我们计算一下现在处于仓位的策略数量。根据最佳指标指数,BuyBestX 工具应持有多头头寸,SellWorstY 工具应持有空头头寸:[code]variables: inLong(0), inShort(0);
arrays: strategiesLong[](-1), strategiesShort[](-1);
inLong = pmms_strategies_in_long_count(strategiesLong);
inShort = pmms_strategies_in_short_count(strategiesShort);[/code]在计算过程中,我们会根据指标索引循环查看应处于多头位置的策略(其中,如果策略已经处于多头位置,我们会在 strategiesLong 数组中对其进行跟踪):[code]for idx = 0 to BuyBestX - 1 begin
cur_idx = allStrategies[idx, 1];
if (not array_contains(strategiesLong, cur_idx)) then
pmms_strategy_allow_long_entries(cur_idx)
else
strategiesLong[array_indexof(strategiesLong, cur_idx)] = -1;
if UsePortfolioMoneyPcnt then
pmms_strategy_set_entry_contracts(
cur_idx,
pmms_calc_contracts_for_entry( PortfolioMoneyPcntForEntry, cur_idx )
);
End;[/code]根据指标指数,已就位但未跻身最佳行列的策略将被强制平仓:[code]for idx = 0 to inLong - 1 begin
value1 = strategiesLong[idx];
if value1 >= 0 then begin
pmms_strategy_close_position(value1);
end;
end;[/code]空头入场策略也同样得到处理。

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

信号:Portfolio_Rotation[code]
inputs:
        Formula(PercentChange(close, 14));

variables: formulaValue(0);

formulaValue = Formula;

if getappinfo(aiisportfoliomode) <> 1 then
        raiseruntimeerror("Signal can be used in Portfolio only.");

pmm_set_my_named_num("RotationalValue", formulaValue);

buy("LE") next bar market;
sellshort("SE") next bar market;

pmm_set_my_status(
        iffstring(marketposition = 0, "Flat",
                iffstring(marketposition = 1, "Long", "Short")
        )
);

// money management
var: PotentialEntryPrice(close), MoneyCostForInvestPerCtrct(0);

if (entryprice > 0) then PotentialEntryPrice = entryprice;

MoneyCostForInvestPerCtrct =
        pmms_calc_money_cost_for_entry_per_cntrct(PotentialEntryPrice, Portfolio_GetMarginPerContract)
        +
        pmms_calc_money_cost_for_entry_per_cntrct(PotentialEntryPrice, Portfolio_GetMaxPotentialLossPerContract);
       
if 0 > MoneyCostForInvestPerCtrct then
        raiseruntimeerror( text("Error! Price = ", PotentialEntryPrice:0:6, ", PMargin = ", Portfolio_GetMarginPerContract, ", PMaxPLoss = ", Portfolio_GetMaxPotentialLossPerContract));
       
// MoneyCostForInvestPerCtrct in currency of the symbol. Convert it to portfolio currency ...
pmm_set_my_named_num("MoneyCostForInvestPerCtrct", pmms_to_portfolio_currency(MoneyCostForInvestPerCtrct));

// exits
inputs: StopLossPcntsOfPortfolio(0.1),
        ProfitTargetPcntsOfPortfolio(0.1);
variable: value(0);

setstopposition;
value = StopLossPcntsOfPortfolio * 0.01 * Portfolio_Equity;
setstoploss(convert_currency(datetime[0], portfolio_CurrencyCode, SymbolCurrencyCode, value));
value = ProfitTargetPcntsOfPortfolio * 0.01 * Portfolio_Equity;
setprofittarget(convert_currency(datetime[0], portfolio_CurrencyCode, SymbolCurrencyCode, value));
[/code]信号:Portfolio_Rotation_MM[code]once cleardebug;

inputs:
        BuyBestX(10),
        SellWorstY(10);
       
Input: use_logging(false);

variables: idx(0), strategyIdx(0), strategyValue(0);
arrays: allStrategies[10000, 1](-1);

if getappinfo(aiisportfoliomode) <> 1 then
        raiseruntimeerror("Signal can be applied (as Money Management Signal) in Portfolio only.");
       
if pmms_strategies_count < BuyBestX + SellWorstY then
        raiseruntimeerror(text("Portfolio has not enough instruments: instruments number = ", pmms_strategies_count, "; BuyBestX = ", BuyBestX, "; SellWorstY = ", SellWorstY));


pmms_strategies_deny_entries_all;

for strategyIdx = 0 to pmms_strategies_count - 1 begin
        strategyValue = pmms_get_strategy_named_num(strategyIdx, "RotationalValue");
        allStrategies[strategyIdx , 0] = strategyValue;
        allStrategies[strategyIdx , 1] = strategyIdx;
end;

Sort2DArrayByKey(allStrategies, pmms_strategies_count, 1);

variables: inLong(0), inShort(0);
arrays: strategiesLong[](-1), strategiesShort[](-1);
inLong = pmms_strategies_in_long_count(strategiesLong);
inShort = pmms_strategies_in_short_count(strategiesShort);

if use_logging then
        print( "strategies in position: long=",inLong, ", short=", inShort );

var : cur_idx(0);

for idx = 0 to BuyBestX - 1 begin
        cur_idx = allStrategies[idx, 1];
       
        if (not array_contains(strategiesLong, cur_idx)) then
                pmms_strategy_allow_long_entries(cur_idx)
        else
                strategiesLong[array_indexof(strategiesLong, cur_idx)] = -1;
               
        if use_logging then
                print( "strategy ", pmms_strategy_symbol(cur_idx), "long entry" );
               
        if UsePortfolioMoneyPcnt then
                pmms_strategy_set_entry_contracts(
                        cur_idx,
                        pmms_calc_contracts_for_entry( PortfolioMoneyPcntForEntry, cur_idx )
                );
end;

for idx = pmms_strategies_count - 1 downto pmms_strategies_count - SellWorstY begin
        cur_idx = allStrategies[idx, 1];

        if (not array_contains(strategiesShort, cur_idx)) then
                pmms_strategy_allow_short_entries(cur_idx)
        else
                strategiesShort[array_indexof(strategiesShort, cur_idx)] = -1;
               
        if use_logging then
                print( "strategy ", pmms_strategy_symbol(cur_idx), "short entry" );
               
        if UsePortfolioMoneyPcnt then
                pmms_strategy_set_entry_contracts(
                        cur_idx,
                        pmms_calc_contracts_for_entry( PortfolioMoneyPcntForEntry, cur_idx )
                );       
end;

// force positions close
for idx = 0 to inLong - 1 begin
        value1 = strategiesLong[idx];
        if value1 >= 0 then begin
                pmms_strategy_close_position(value1);               
                if use_logging then
                        print( "strategy ", pmms_strategy_symbol(value1), "force position close" );
        end;
end;

for idx = 0 to inShort - 1 begin
        value1 = strategiesShort[idx];
        if value1 >= 0 then begin
                pmms_strategy_close_position(value1);
                if use_logging then
                        print( "strategy ", pmms_strategy_symbol(value1), "force position close" );
        end;
end;


// money management
inputs:
        UsePortfolioMoneyPcnt(False),
        PortfolioMoneyPcntForEntry(1);

if use_logging then
        print("------------------------------------------------------------------")

[/code]

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

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

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

**** Hidden Message *****

页: [1]