Joomla 3.1 Templates by FatCow Coupon

SQL и биржевой график (Создание торговой системы)

Категория: Блог Опубликовано 24.05.2017

Публикация пятая
Создание торговой системы

Подготовим необходимую инфраструктуру для разработки и отладки торговых стратегий

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

 

 

-- Create table
create table TRADES
(
    ticker VARCHAR2(5)
  , opendate DATE
  , openprice NUMBER
  , closedate DATE
  , closeprice NUMBER
  , position NUMBER
)
;
-- Add comments to the table 
comment on table TRADES
  is 'Сделки';
-- Add comments to the columns 
comment on column TRADES.ticker is 'Тикер инструмента';
comment on column TRADES.opendate is 'Дата открытия сделки';
comment on column TRADES.openprice is 'Цена открытия';
comment on column TRADES.closedate is 'Дата закрытия';
comment on column TRADES.closeprice is 'Цена закрытия';
comment on column TRADES.position is 'Позиция';

-- Create/Recreate indexes 
create unique index TRADES_IDX on TRADES (TICKER, opendate);


-- Create table
create table POSITIONS
(
    ticker VARCHAR2(5)
  , position NUMBER
  , positionprice NUMBER
)
;
-- Add comments to the table 
comment on table POSITIONS
  is 'Позиции';
-- Add comments to the columns 
comment on column POSITIONS.ticker is 'Тикер инструмента';
comment on column POSITIONS.position is 'Дата открытия сделки';
comment on column POSITIONS.positionprice is 'Позиция в рублях';

-- Create/Recreate indexes 
create unique index POSITIONS_IDX on POSITIONS (ticker);

drop table BALANCE;
-- Create table
create table BALANCE
(
    ticker VARCHAR2(5)
  , tradedate date
  , balancedelta NUMBER
  , balanceall NUMBER
  , balanceallticker NUMBER
  , balancedeltarur NUMBER
  , balanceallrur NUMBER
  , balancealltickerrur NUMBER

)
;
-- Add comments to the table 
comment on table BALANCE
  is 'Баланс';
-- Add comments to the columns 
comment on column BALANCE.ticker is 'Тикер инструмента';
comment on column BALANCE.tradedate is 'Дата трейда';
comment on column BALANCE.balancedelta is 'Дельта баланса';
comment on column BALANCE.balanceall is 'Накопительная сумма баланса';
comment on column BALANCE.balanceallticker is 'Накопительная сумма баланса по инструментам';
comment on column BALANCE.balancedeltarur is 'Дельта баланса в рублях';
comment on column BALANCE.balanceallrur is 'Накопительная сумма баланса в рублях';
comment on column BALANCE.balancealltickerrur is 'Накопительная сумма баланса по инструментам в рублях';

-- Create/Recreate indexes 
create unique index BALANCE_IDX on BALANCE (ticker, tradedate);



далее создадим необходимые нам в работе сервисные функции

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

create or replace function priorind(priceticker varchar2,
                                       operdate    date
                                      )
  return priceind%rowtype
-- строка индикатора на n дней назад
 is
  vr_return priceind%rowtype;
begin
 vr_return := null;
-- открываем позицию только в случае , если не позиции по данному инструменту
 select * into vr_return from priceind
 where priceind.ticker = priceticker
   and priceind.dateprice = (
  select max(priceind.dateprice) nc
    from priceind where priceind.dateprice<operdate
   ) ;
   return vr_return;

   exception 
     when others then dbms_output.put_line(operdate); return null;
end priorind;

create or replace function getpriceind(priceticker varchar2,
                                       operdate    date,
                                       n           number)
  return priceind%rowtype
-- строка инддикатора на n дней назад
 is
  vr_return priceind%rowtype;
begin
 vr_return := null;
-- открываем позицию только в случае , если не позиции по данному инструменту
 select * into vr_return from priceind
 where priceind.ticker = priceticker
   and priceind.dateprice = (
  select nc
    from (select priceind.dateprice dateprice,
                 Lead(dateprice, n, priceind.dateprice) over(order by dateprice desc) nc
            from priceind
           where ticker = priceticker and priceind.dateprice <= operdate and priceind.dateprice > operdate - n*2 )
   where dateprice = operdate 
   ) ;
   return vr_return;
end getpriceind;

create or replace function ind(priceticker varchar2 , operdate date)
  return priceind%rowtype
-- строка индикатора текущая дата
 is
  vr_return priceind%rowtype;
begin
 vr_return := null;
-- открываем позицию только в случае , если не позиции по данному инструменту
 select * into vr_return from priceind
 where priceind.ticker = priceticker
   and priceind.dateprice = operdate ;
   return vr_return;
end ind;

create or replace function closerules(priceticker varchar2, operdate date) return number
-- правила закрытия позиции
    is
    vr_return number;
    rind  priceind%rowtype;
    price priceind%rowtype;
begin
   vr_return := 0;
   for i in (select * from trades where trades.ticker = priceticker and trades.closedate is null)
   loop
     -- проверка только в том случае если есть открытые трейды
     rind := priorind(priceticker , operdate);
     price := ind(priceticker, operdate);
     if price.c < rind.min20 then vr_return := 1; end if; 
   end loop;
   return vr_return;
end closerules;

create or replace function openrules(priceticker varchar2, operdate date) return number
-- правила открытия позиции
    is
    vr_return number;
    vr_count number;
    rind  priceind%rowtype;
    price priceind%rowtype;
begin
   vr_return := 0;
     -- проверка только в том случае если есть открытые трейды
     select /* +first_rows(1)*/ count(1) into vr_count from trades 
      where trades.ticker = priceticker and trades.closedate is null and rownum<2;
   if vr_count=0 then   
     rind := priorind(priceticker , operdate);
     price := tradesystem_pkg.indnow;
     if price.c > price.avg200 and rind.vti5 < rind.vti20/3 
       and price.c > rind.c and price.v > rind.v
        then vr_return := 1; end if; 
   end if;
   return vr_return;
end openrules;


create or replace function moneyposition(priceticker varchar2, operdate date) return number
-- правил управления капиталом , возвращает позицию в количестве акций которые можно купить
    is
    vr_return number;
    rw priceind%rowtype;
begin
    vr_return := 0;
    -- открываем позицию только в случае , если не позиции по данному инструменту
    rw := tradesystem_pkg.indnow;
    vr_return := trunc(tradesystem_pkg.moneybalance / 10 / rw.c);
    return vr_return;
end moneyposition;



создадим пакет обеспечивающий инфраструктуру для обеспечения наших торговых стратегий

create or replace package body report_pkg is

 -- Function and procedure implementations
 
 
  -- Общая прибыль
  function getsumwin(priceticker varchar2 default null) return number
    is
     vr_return number; 
  begin
    select sum(balance.balancedeltarur) into vr_return from balance 
    where (balance.ticker = priceticker or priceticker is null);
    return vr_return;
  end getsumwin;
  
  -- Средняя прибыльная сделка
  function getavgwintrade(priceticker varchar2 default null) return number
     is
     vr_return number;
   begin
     select avg(balance.balancedeltarur) into vr_return from balance 
     where (balance.balancedelta>0) and (balance.ticker = priceticker or priceticker is null);
     return vr_return;
   end getavgwintrade;

  
  -- Средняя убыточная сделка
  function getavglosstrade(priceticker varchar2 default null) return number
   is
     vr_return number;
   begin
     select avg(balance.balancedeltarur) into vr_return from balance 
     where (balance.balancedelta<0) and (balance.ticker = priceticker or priceticker is null);
     return vr_return;
   end getavglosstrade;
   
  
  -- Максимальная просадка
  function getmaxloss(priceticker varchar2 default null) return number
   is
     vr_return number;
   begin
     if priceticker is null then
       select max(balance.balanceallrur)-min(balance.balanceallrur) 
         into vr_return from balance;
     else 
      select max(balance.balancealltickerrur)-min(balance.balancealltickerrur)  into vr_return from balance 
       where balance.ticker = priceticker;
     end if;
     return vr_return;
   end getmaxloss;
  
  -- Общее количество сделок
  function gettradescount(priceticker varchar2 default null) return number
  is
     vr_return number;
  begin
   select count(1) into vr_return from balance 
     where  (balance.ticker = priceticker or priceticker is null);
     return vr_return;
  end gettradescount;
  
  -- Общее прибыльных сделок
  function gettradeswincount(priceticker varchar2 default null) return number
  is
     vr_return number;
  begin
    select count(1) into vr_return from balance 
     where  balance.balancedelta>0 and (balance.ticker = priceticker or priceticker is null);
     return vr_return;
  end gettradeswincount;
  
  -- Общее количество убыточных сделок
  function getlosscount(priceticker varchar2 default null) return number
  is
     vr_return number;
  begin
    select count(1) into vr_return from balance 
     where  balance.balancedelta<0 and (balance.ticker = priceticker or priceticker is null);
     return vr_return;
  end getlosscount;
  
  -- макс Количество убыточных сделок подряд
  function gettradeslosscount(priceticker varchar2 default null) return number
  is
     vr_return number:=0;
     vr_count number:=0;
  begin
    for i in 
    (
     select balance.balancedeltarur r from balance 
      where (balance.ticker = priceticker or priceticker is null)
      order by balance.tradedate  
     )
    loop
      if i.r > 0 then vr_count:=0; end if; 
      if i.r < 0 then vr_count:=vr_count+1 ; 
        if vr_count>vr_return then vr_return := vr_count; end if;
      end if; 
    end loop;  
    return vr_return;
  end gettradeslosscount;
  
  -- Максимальный убыток
  function gettradeslosstrade(priceticker varchar2 default null) return number
  is
     vr_return number;
  begin
    select min(balance.balancedeltarur) into vr_return from balance 
     where  balance.balancedelta<0 and (balance.ticker = priceticker or priceticker is null);
     return vr_return;
  end gettradeslosstrade;


begin
  -- Initialization
  null;
end report_pkg;



очистим таблицы и запустим тестирование стратегии на исторических данных для инструмента сбербанк


проверим сформированные торговые сделки позиции и баланс.

select * from positions
select * from balance
select * from trades
Просмотров: 56