[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Gen - system indicators continued



PureBytes Links

Trading Reference Links

At 12:44 PM -0700 7/7/99, ROBERT ROESKE wrote:

>Is Sharp ratio code available for TS4 or PS2000i, or is it too complex to
>implement in .ela?


Below is a copy of a previous post containing my Sharpe Ratio 
function. The ELA file is also attached.

Bob Fulks


-----
Mime-Version: 1.0
Date: Tue, 24 Nov 1998 19:19:12 -0500
To: "Code-List" <code-list@xxxxxxxxxxxxx>
From: Bob Fulks <bfulks@xxxxxxxxxxxx>
Subject: RE: CL_Sharpe Ratio?


Attached is code for a function to calculate the Sharpe Ratio of a trading
system. In addition, I have included two Demo trading systems to illustrate
the use of the function - one for futures and one for stocks.

The text is appended below. The ELA file is attached.

I have written many posts on the use of Sharpe Ratio. One of the more
complete ones was posted by Lorenzo Vercesi on his web site in Italy.

You can access it at  http://www.venus.it/homes/ik2hlb/sr.htm

If you find any errors in this code please notify me.

Bob Fulks

{ *******************************************************************

   System:       Sharpe Demo (Futures)

   Last Edit:    11/24/98

   Coded By:     Bob Fulks

   Description:  Sample usage of the SharpeRatio function for
     futures trading. The InitValue variable should be equal to
     the total equity controlled, not the margin balance in the
     account.


********************************************************************}

Inputs:   NoOfCont(2),      {Number of contracts to trade}
          PrMode(0);        {Print mode}

Vars:     InitValue(0),     {Initial value of trading account}
          NetValue(0),      {Value of trading account over time}
          Sharpe(0);        {Sharpe Ratio}

{Establish value for initial account value}
if CurrentBar = 1 then
   InitValue = Close * BigPointValue * NoOfCont;

{Simple trading system}
if Close > Close[1] then Buy  NoOfCont Contracts next bar at market;
if Close < Close[1] then ExitLong next bar at market;

{Calculate Sharpe Ratio - using monthly samples}
NetValue = InitValue + NetProfit + OpenPositionProfit;
Sharpe   = SharpeRatio(4, NetValue, 0, PrMode, TRUE);

-----------

{ *******************************************************************

   System:       Sharpe Demo (Stocks)

   Last Edit:    11/24/98

   Coded By:     Bob Fulks

   Description:  Sample usage of the SharpeRatio function for
     equities trading. The InitValue variable should be equal to
     the total account value that will be invested.


********************************************************************}

Inputs:   NoOfShrs(100),    {Number of shares to trade}
          PrMode(0);        {Print mode}

Vars:     InitValue(0),     {Initial value of trading account}
          NetValue(0),      {Value of trading account over time}
          Sharpe(0);        {Sharpe Ratio}

{Establish value for initial account value}
if CurrentBar = 1 then
   InitValue = Close * NoOfShrs;

{Simple trading system}
if Close > Close[1] then Buy NoOfShrs Shares next bar at market;
if Close < Close[1] then ExitLong next bar at market;

{Calculate Sharpe Ratio - using monthly samples}
NetValue = InitValue + NetProfit + OpenPositionProfit;
Sharpe   = SharpeRatio(4, NetValue, 0, PrMode, FALSE);

---------------

{ *******************************************************************

  Function     : SharpeRatio

  Last Edit    : 11/24/98

  Provided By  : Bob Fulks

  Description  : This function calculates and returns the Sharpe Ratio
     of a series of account values. It samples the series of values
     on a yearly, quarterly, monthly, weekly, or daily basis as
     determined by an input. It also calculates average return and
     standard deviation. It prints the results in a form suitable for
     importing into an Excel spreadsheet for plotting.

  Inputs:
     Mode - Sampling period (0=yearly, 1=quarterly, 2=monthly,
       3=weekly, 4=daily
     NetValue - The series of values to be sampled. It should be
       equal to the beginning equity plus accumulated net profits.
     Periods - The number of yearly, quarterly, etc., periods to
       include in the calculation. If this value is zero, the
       function will use all periods up to a maximum of 1500.
     PrntMode:
       zero   - Print one line summary only on last bar
       > zero - Print values as stored in array plus summary
       < zero - Do not print anything
     Futures:
       TRUE  - For futures trading (Sharpe = Ave / SDev)
       FALSE - For Stocks (Sharpe = (Ave - 5) / SDev)

  Method: The function samples the value of the trading account at
     periodic intervals, calculates returns in each period, then
     calculates the average and standard deviation of returns and
     annualizes them. It then calculates to Sharpe Ratio as noted
     above.

  Assumptions: The usage for stocks assumes a constant value of 5%
     for the risk-free return (T-Bill interest rate). This is a good
     assumption for recent times but may be incorrect for the distant
     past. The Sharpe Ratio is independent of the sampling interval
     if the returns are normally distributed. Returns are typically
     not strictly normally distributed so the sampling interval will
     affect the results somewhat. There should be more than about 25
     samples to get reasonable accuracy so use daily samples for 1
     to 6 months of trades, weekly samples for 6 months to 24 months
     of trades, etc.


     © 1998 Robert G. Fulks, All rights reserved.

********************************************************************}

Input: Mode(NumericSimple),
          {0=yearly, 1=quarterly, 2=monthly, 3=weekly, 4=daily}
       NetValue(NumericSimple),
          {Net value of account = Beginning Equity + NetProfit}
       Periods(NumericSimple),
          {Number of periods to use in calculation, zero = all}
       PrntMode(NumericSimple),
          {0 = print summary, 1 = include detail, -1 = don't print}
       Futures(TrueFalse);
          {TRUE for Futures, FALSE for Stocks}

Vars:  Index(0),         {Index used to index Return array}
       SIndex(0),        {Index used to sum Return array}
       LNetVal(0),       {NetValue at end of previous period}
       LClose(0),        {Close at end of previous period}
       YClose(0),        {Close at end of previous bar}
       Size(0),          {Sixe of data to be stored in array}
       ILast(0),         {Number of entries in array}
       Ave(0),           {Average return}
       ASum(0),          {Used to calc Average}
       SSum(0),          {Used to calc Standard Deviation}
       SDev(0),          {Standard Deviation}
       SDMult(0),        {Multiplier to annualize Standard Deviation}
       Mo(0),            {Month for bar}
       MP(0),            {MarketPosition}
       MPX(0),           {MarketPosition flag becomes 1 on first trade}
       YMo(0),           {Month for previous bar}
       Yr(-99),          {Year for bar}
       YYr(0),           {Year for previous bar}
       YDate(0),         {Date for previous bar}
       AvMult(0),        {Multiplier to annualize Average}
       NetVal(0),        {NetValue series}
       YNetVal(0),       {Netval for previous bar}
       Active(FALSE),    {False for first calc then true thereafter}
       Record(FALSE),    {Flag to trigger calculation at end of period}
       Summary(FALSE),   {Flag set if summary printed}
       StDate(0),        {Start date}
       Sharpe(0);        {Sharpe Ratio}

Array: Return[1500](0);  {Table of returns as a percent}

Size   = iff(Periods > 0, Periods, 1500);
Size   = MinList(Size, 1500);
NetVal = Netvalue;
Mo     = Month(Date);
Yr     = Year(Date);

{This determines marketposition in either systems or indicators}
if MarketPosition <> 0 then
   MP = MarketPosition
else
   MP = I_MarketPosition;

MPX = iff(MP <> 0, 1, MPX);

Condition1  = Mo = 1 or Mo = 4 or Mo = 7 or Mo = 10;

begin

   {Initialize for yearly}

   if Mode = 0 and Yr <> YYr then begin
      SDMult    = 1;
      AvMult    = 1;
      Record    = TRUE;
   end;

   {Initialize for quarterly}

   if Mode = 1 and Mo <> YMo and Condition1 then begin
      SDMult    = 2;
      AvMult    = 4;
      Record    = TRUE;
   end;

   {Initialize for monthly}

   if Mode = 2 and Mo <> YMo then begin
      SDMult    = SquareRoot(12);
      AvMult    = 12;
      Record    = TRUE;
   end;

   {Initialize for weekly}

   if Mode = 3 and DayOfWeek(Date) < DayOfWeek(YDate) then begin
      SDMult    = SquareRoot(52);
      AvMult    = 52;
      Record    = TRUE;
   end;

   {Initialize for daily}

   if Mode = 4 and Date <> YDate then begin
      SDMult    = SquareRoot(253);
      AvMult    = 253;
      Record    = TRUE;
   end;
end;

{Action if new year, quarter, month, week, or day}

if Record = TRUE then begin
   if Active = TRUE then begin
      {Each time except first time}
      begin
         ILast = ILast + 1;
         if LNetVal <> 0 then Value1 = YNetVal / LNetVal;
         if Value1 > 0 then Return[Index] = 100 * Log(Value1);
         if PrntMode > 0 then Print(Index:5:0, Date:7:0, YClose:6:2,
            LClose:6:2, YNetVal:7:0, LNetVal:7:0, Return[Index]:4:2);
         Index = Mod(Index + 1, Size);
      end;
   end else
      {First time only after initial position}
      if MPX > 0 then begin
         Active = TRUE;
         StDate = Date;
         if PrntMode > 0 then Print(Index:5:0, Date:7:0, YClose:6:2,
            LClose:6:2, YNetVal:7:0, LNetVal:7:0, Return[Index]:4:2);
      end;

   LClose  = YClose;
   LNetVal = YNetVal;
   Record  = FALSE;
end;

{Calculate and print summary}

if Active = TRUE and Summary = FALSE and
   (LastBarOnChart or ILast >= Size) then begin

   {Calculate average return in period}
   Summary = TRUE;
   ASum = 0;
   ILast = MinList(Size, ILast);
   for SIndex = 0 to ILast - 1 begin
      ASum = ASum + Return[SIndex];
   end;
   Ave = ASum / ILast;

   {Calculate annualized standard deviation}
   SSum = 0;
   for SIndex = 0 to ILast - 1 begin
      SSum = SSum + Square(Return[SIndex] - Ave);
   end;
   SDev = SDMult * SquareRoot(SSum / ILast);

   {Annualize average}
   Ave  = AvMult * Ave;

   {Convert back to ratios from logarithms}
   SDev = 100 * (ExpValue(SDev / 100) - 1);
   Ave  = 100 * (ExpValue(Ave  / 100) - 1);

   {Calculate Sharpe Ratio}
   if SDev <> 0 then begin
      if Futures then
         Sharpe = Ave / SDev
      else
         Sharpe = (Ave - 5) / SDev;
   end;

   if PrntMode >= 0 then
      Print( ",", StDate:6:0, ",", ILast:6:0, ",", SDev:6:1, "%,",
         Ave:6:1, "%,", Sharpe:3:2, ",  ",GetSymbolName, ",");

end;

{Print(Date:6:0, NetVal, Sharpe:4:2, MP:2:0, Active);}

YMo     = Mo;
YYr     = Yr;
YDate   = Date;
YClose  = Close;
YNetVal = NetVal;

SharpeRatio = Sharpe;

-------------------------

Attachment Converted: "c:\eudora\attach\SHARPRAT.ELA"