Торговая стратегия на активном движении средств

Цена либо вверх, либо вниз. В долгосрочной перспективе вероятность роста и падения цены должна составлять 50%, поэтому, чтобы правильно спрогнозировать будущую цену, вам необходимо получить все факторы, влияющие на цену в режиме реального времени, а затем придать каждому фактору правильный вес и, наконец, провести объективный и рациональный анализ. Если перечислить все факторы, влияющие на цену, то она может заполнить всю вселенную.

Кратко изложены как: глобальная экономическая среда, национальная макрополитика, соответствующая промышленная политика, отношения спроса и предложения, международные события, процентные ставки и обменные курсы, инфляция и дефляция, рыночная психология и другие неизвестные факторы и т. д. Предсказание стало огромной и невыполнимой задачей. Так рано я понял, что рынок непредсказуем. Тогда все прогнозы на рынке превратились в гипотезы, а трейдинг превратился в игру на вероятности, что интересно.

Зачем использовать движение капитала

Поскольку рынок непредсказуем, неужели он безразличен? Нет, все макро- и микрофакторы были отражены в цене, а это значит, что цена является результатом взаимодействия всех факторов. Нам нужно только проанализировать цену, чтобы составить полноценную торговую стратегию.

Сначала подумайте, почему цена растет?

Вы можете сказать, потому что: страна поддерживает соответствующую промышленную политику, страна происхождения — проливной дождь, международная торговая война, золотая вилка MACD куплена, другие купили ее и т. Д. Конечно, они не могут ошибаться. Оглядываясь назад, мы всегда можем выяснить причины роста цен.

На самом деле, рост и падение цен похожи на приливы и отливы. Рост цен неотделим от продвижения средств. На рынке, если покупателей будет больше, чем продавцов, цена вырастет. И наоборот, если продавцов больше, чем покупателей, цена упадет. С помощью этой концепции мы можем дать разумные ожидания в отношении будущих ценовых тенденций, основанных на соотношении спроса и предложения, отраженном в чистом потоке средств.

Принцип движения фондов

В отличие от традиционного анализа, анализ движения средств анализирует, какие операции являются активным притоком средств, а какие — активным оттоком средств на основе данных о транзакциях за определенный период времени. Затем, вычитая объем активного оттока из объема активного притока за этот период, мы можем узнать чистый приток средств за этот период. Если чистый приток средств положительный, это означает, что предложение этого продукта в дефиците; Если чистый отток средств означает, что предложение этого продукта является избыточным.

Прочитав это, некоторые люди могут задаться вопросом, что в реальных сделках сделка будет заключена только тогда, когда кто-то покупает, а кто-то продает. Ордер на транзакцию должен иметь такой же объем продаж, как и объем покупки, и средства должны входить и выходить из одной и той же суммы. Откуда берутся приток и отток капитала? На самом деле, строго говоря, каждый ордер на покупку должен соответствовать соответствующему ордеру на продажу, а приток и отток капитала должны быть равны. Если мы хотим рассчитать, какие ордера активно покупаются, а какие активно продаются, мы можем использовать только компромиссный метод, используя данные линейного бара K, основанные на объеме сделки и цене.

Метод расчета движения средств

Изменение потока средств точно соответствует рыночному поведению в реальном времени, а чистый поток средств рассчитывается в режиме реального времени путем интегрирования данных k линейных баров. Существует два алгоритма расчета активного потока средств:

Во-первых, если текущая цена сделки текущего ордера исполняется по цене контрагента или по завышенной цене, цена сделки покупки >= цена сделки продажи, что означает, что покупатель более охотно завершает сделку по более высокой цене, которая включается в активный приток средств.

Во-вторых, если текущая цена сделки > цену последней сделки, то можно понять, что текущий объем сделки активно толкает вверх рост цены, который включается в активный приток средств.

Возьмем в качестве примера приведенный выше второй алгоритм:

Цена закрытия определенного продукта в 10:00 составляет 3450, а цена закрытия в 11:00 — 3455, поэтому мы включим объем сделки с 10:00 до 11:00 в качестве активного притока капитала. В противном случае он включается в инициативный отток средств. Эта статья основана на втором методе, добавляющем фактор волатильности цены. Сравнивая цену закрытия k line bar до и после, объем восходящего или падающего k line bar* волатильности включается в последовательность, а затем далее по последовательности Вычисляют коэффициент активного притока средств.

Торговая логика

В этой статье описывается движение средств на фьючерсном рынке с точки зрения «объема» и устанавливается торговая модель для оценки краткосрочных ценовых тенденций посредством анализа данных линейных баров K в режиме реального времени. При нормальных обстоятельствах движение капитала и ценовые тенденции можно разделить на четыре основных условия:

Цена растет и активный чистый приток средств в единицу времени: эта ситуация сильна, и будущая цена будет продолжать расти более вероятно;

Цена акций растет, и активный чистый отток средств в единицу времени: в этом случае это средне-сильная позиция, и скорость будущего роста цен будет сильно снижена;

Цена акций падает, при этом активный чистый приток средств в единицу времени: это слабая ситуация, и будущая цена продолжает падать более вероятно;

Цена акций падает, и в то же время активный чистый отток средств в единицу времени: в этом случае это умеренно слабая позиция, и скорость будущего снижения цены будет сильно снижена;

Основными переменными являются:

Предыдущий минимум (ll)
Предыдущий максимум (hh)
Активная покупка (barIn)
Активные продажи (barOut)
Отношение активного притока средств к активному оттоку средств (barRatio)
Порог положения открытия (openValve)
Текущая удерживающая позиция (myAmount)
Последняя цена закрытия K-line (закрытие)

Условия въезда и выезда

Хорошая количественная торговая стратегия требует не только стабильной доходности, но и умения контролировать риски и избегать больших потерь при небольшой вероятности. Здесь мы используем стратегию отслеживания потока активных средств с помощью краткосрочных прогнозов цен для анализа направления товарных фьючерсов, чтобы достичь эффектов высокой прибыли и низкого риска.

  • Открытие длинной позиции: если нет текущей позиции удержания, а barRatio > openValve, откройте длинную позицию;
  • Открытие короткой позиции: если нет текущей позиции удержания и коэффициента баров < 1 / открытого клапана, откройте короткую позицию;
  • Закрытие длинной позиции: Если текущая длинная позиция удерживается и закрывается < ll, продайте и закройте длинную позицию;
  • Закрытие короткой позиции: Если текущая короткая позиция удерживается и закрывается > hh, покупайте и закрывайте короткую позицию;

Написание исходного кода стратегии

Получение и расчет данныхfunction data() {
var self = {};
var barVol = [];
var bars = _C(exchange.GetRecords); //Get K line bar data
if (bars.length < len * 2) { //Control the length of the K line bar data array
return;
}
for (var i = len; i > 0; i—) {
var barSub_1 = bars[bars.length — (i + 1)].Close — bars[bars.length — (i + 2)].Close; //Calculate the difference between the current closing price and the previous K line bar closing price
if (barSub_1 > 0) { //If the price rises, add a positive number to the array
barVol.push(bars[bars.length — (i + 1)].Volume * (bars[bars.length — (i + 1)].High — bars[bars.length — (i + 1)].Low));
} else if (barSub_1 < 0) { //If the price drops, add a negative number to the array
barVol.push(-bars[bars.length — (i + 1)].Volume * (bars[bars.length — (i + 1)].High — bars[bars.length — (i + 1)].Low));
}
}
if (barVol.length > len) {
barVol.shift(); //Free up excess data
}
self.barIn = 0;
self.barOut = 0;
for (var v = 0; v < barVol.length; v++) {
if (barVol[v] > 0) {
self.barIn += barVol[v]; //Consolidate all active inflows funds
} else {
self.barOut -= barVol[v]; //Consolidate all active outflow funds
}
}
self.barRatio = self.barIn / Math.abs(self.barOut); //Calculate the ratio of active inflows to active outflows
bars.pop(); //Delete unfinished K line bar data
self.close = bars[bars.length — 1].Close; //Get the closing price of the pervious bar
self.hh = TA.Highest(bars, hgLen, ‘High’); //Get the previous high price
self.ll = TA.Lowest(bars, hgLen, ‘Low’); //Get the previous low price
return self;
}

Получите данные линейного столбца K непосредственно с помощью метода GetRecords в API FMZ. Содержит самую высокую цену, самую низкую цену, цену открытия, цену закрытия, объем и стандартную метку времени. Если цена последней сделки больше, чем цена последней сделки, то последний объем сделки * (самая высокая цена — самая низкая цена) включается в активную покупку; если цена последней сделки меньше цены последней сделки, то последний объем * (самая высокая цена — самая низкая цена) включается в активные продажи;

Получение данных о местоположении

function positions(name) {
var self = {};
var mp = _C(exchange.GetPosition); //Get positions
if (mp.length == 0) {
self.amount = 0;
}
for (var i = 0; i < mp.length; i++) { //Position data processing
if (mp[i].ContractType == name) {
if (mp[i].Type == PD_LONG || mp[i].Type == PD_LONG_YD) {
self.amount = mp[i].Amount;
} else if (mp[i].Type == PD_SHORT || mp[i].Type == PD_SHORT_YD) {
self.amount = -mp[i].Amount;
}
self.profit = mp[i].Profit;
} else {
self.amount = 0;
}
}
return self;
}

Получить базовые данные о местоположении с помощью метода GetPosition в API платформы FMZ, и далее обработать базовые данные. Если текущая длинная позиция удерживается, то возвращается количество положительной позиции; Если текущая позиция короткая, то возвращается отрицательное количество позиций. Цель этого — облегчить расчет логики открытия и закрытия позиций.

Размещение заказов

function trade() {
var myData = data(); //Execute data function
if (!myData) {
return;
}
var mp = positions(contractType); //Get position information
var myAmount = mp.amount; //Get the number of positions
var myProfit = mp.profit; //Get floating profit and loss
if (myAmount > 0 && myData.close < myData.ll) {
p.Cover(contractType, unit); //close long position
}
if (myAmount < 0 && myData.close > myData.hh) {
p.Cover(contractType, unit); //close short position
}
if (myAmount == 0) {
if (myData.barRatio > openValve) {
p.OpenLong(contractType, unit); //open long position
} else if (myData.barRatio < 1 / openValve) {
p.OpenShort(contractType, unit); //open short position
}
}
}

Стратегические характеристики

  • Функции:

Несколько основных параметров: Модель имеет четкую дизайнерскую идею, всего с тремя основными параметрами. Пространство для оптимизации невелико, и переобучения можно эффективно избежать.
Сильная универсальность: стратегия проста по логике и обладает высокой универсальностью. Он может адаптироваться к большинству сортов, кроме сельскохозяйственных продуктов, и может сочетаться с несколькими сортами.

  • Улучшения:

Добавление условий удержания позиции: односторонний (фондовый) рыночный поток средств может определять приток или отток средств на основе таких факторов, как колебания цен и объем торгов. Однако, поскольку стратегия не включает условие удержания позиции, статистический активный поток капитала может быть искажен.

Добавление условия стандартного отклонения: полагаясь только на поток средств в качестве условия для открытия позиции, могут быть частые ложные сигналы, приводящие к частому открытию и закрытию позиций. Фильтруйте ложные сигналы, подсчитывая среднее значение чистого оттока средств за заданное время и складывая стандартное отклонение в большую и меньшую сторону.

Полный исходный код стратегии:

/*backtest
start: 2016-01-01 09:00:00
end: 2019-12-31 15:00:00
period: 1h
exchanges: [{«eid»:»Futures_CTP»,»currency»:»FUTURES»}]
*/

var p = $.NewPositionManager(); //Call commodity futures trading library

//Holding Position data processing
function positions(name) {
var self = {};
var mp = _C(exchange.GetPosition); //Get positions
if (mp.length == 0) {
self.amount = 0;
}
for (var i = 0; i < mp.length; i++) { //Holding Position data processing
if (mp[i].ContractType == name) {
if (mp[i].Type == PD_LONG || mp[i].Type == PD_LONG_YD) {
self.amount = mp[i].Amount;
} else if (mp[i].Type == PD_SHORT || mp[i].Type == PD_SHORT_YD) {
self.amount = -mp[i].Amount;
}
self.profit = mp[i].Profit;
} else {
self.amount = 0;
}
}
return self;
}

//Market data processing function
function data() {
var self = {};
var barVol = [];
var bars = _C(exchange.GetRecords); //Get K line bar data
if (bars.length < len * 2) { //Control the length of the K line bar data array
return;
}
for (var i = len; i > 0; i—) {
var barSub_1 = bars[bars.length — (i + 1)].Close — bars[bars.length — (i + 2)].Close; //Calculate the difference between the current closing price and the previous K line bar closing price
if (barSub_1 > 0) { //If the price rises, add a positive number to the array
barVol.push(bars[bars.length — (i + 1)].Volume * (bars[bars.length — (i + 1)].High — bars[bars.length — (i + 1)].Low));
} else if (barSub_1 < 0) { //If the price drops, add a negative number to the array
barVol.push(-bars[bars.length — (i + 1)].Volume * (bars[bars.length — (i + 1)].High — bars[bars.length — (i + 1)].Low));
}
}
if (barVol.length > len) {
barVol.shift(); //Free up excess data
}
self.barIn = 0;
self.barOut = 0;
for (var v = 0; v < barVol.length; v++) {
if (barVol[v] > 0) {
self.barIn += barVol[v]; //Consolidate all active inflows funds
} else {
self.barOut -= barVol[v]; //Consolidate all active outflow funds
}
}
self.barRatio = self.barIn / Math.abs(self.barOut); //Calculate the ratio of active inflows to active outflows
bars.pop(); //Delete unfinished K line bar data
self.close = bars[bars.length — 1].Close; //Get the closing price of the last K line bar
self.hh = TA.Highest(bars, hgLen, ‘High’); //Get the previous high price
self.ll = TA.Lowest(bars, hgLen, ‘Low’); //Get the previous low price
return self;
}

//Trading function
function trade() {
var myData = data(); //Execute data function
if (!myData) {
return;
}
var mp = positions(contractType); //Get position information
var myAmount = mp.amount; //Get the number of positions
var myProfit = mp.profit; //Get floating profit and loss
if (myAmount > 0 && myData.close < myData.ll) {
p.Cover(contractType, unit); //close long position
}
if (myAmount < 0 && myData.close > myData.hh) {
p.Cover(contractType, unit); //close short position
}
if (myAmount == 0) {
if (myData.barRatio > openValve) {
p.OpenLong(contractType, unit); //open long position
} else if (myData.barRatio < 1 / openValve) {
p.OpenShort(contractType, unit); //open short position
}
}
}

//The main entrance of the program, start from here
function main() {
while (true) { //Enter the loop
if (exchange.IO(«status»)) { //If it is the market opening time
_C(exchange.SetContractType, contractType); //Subscription contract
trade(); //Execute trade function
}
}
}

Стратегический адрес:
https://www.fmz.com/strategy/87698

Бэктест стратегии

Конфигурация стратегии:

Производительность бэктеста:

Подведем итоги

Посредством моделирования в этой статье используются данные линейных баров товарных фьючерсов K, предоставленные торговой платформой FMZ, для создания модели чистого потока капитала посредством сбора данных, соответствующего анализа и технологии прогнозирования. Используйте анализ временных рядов для прогнозирования будущих цен на товарные фьючерсы и разработки количественной торговой стратегии для товарных фьючерсов.

Следует отметить, что движение средств, упомянутое в этой статье, относится к активному движению средств. Это относится к силе продавца и покупателя на рынке, а не к входу или выходу средств. Суждение о будущих ценах путем анализа поведения покупателей и продавцов на рынке не имеет краткосрочного эталонного значения.

Источник