Giorgio Melon Luca Di Salvo Luca Pischedda

Simulation models for economics

Project work on

"Stop-loss strategy."

 

The applet requires Java 5 or higher. Java must be enabled in your browser settings. Mac users must have Mac OS X 10.4 or higher. Windows and Linux users may obtain the latest Java from Oracle's Java site.


Here you can find an introduction to the Stop-loss strategy application.


powered by NetLogo

view/download model file: stop-loss_strategy.nlogo

WHAT IS IT?

It is a simulation of a Stop-Loss strategy.

We wanted to compare the stop loss strategy with a winning random strategy. In order to make the random strategy winning we made random investors start with a long position in stocks. Plus, we gave random agents the possibility to purchase and sell at the same time, creating an asimmetry in the market.
The comparison with a pure random strategy would not have been significant since the stop-loss strategy tends to gain by costruction.

HOW IT WORKS

A new price is continuously formed in the market by Random Agents.
The Stop-Loss Strategy starts after 52 weeks, when also the StopLossAgents enter in the market.

HOW TO USE IT

Choose the number of Random Agents and Stop-loss Agents.

THINGS TO NOTICE

The strategy without transaction costs has always a gain.

THINGS TO TRY

Look at the gain of Stop-Loss Agents with different parameters, like checking time, shock, transaction costs, seed.

EXTENDING THE MODEL

It would be interesting implement different strategies in order to compare the different performances.

NETLOGO FEATURES

Since the cumulative distribution function of a Gaussian is not implemented in Netlogo by default, we exploited the job of an external we found on internet.
The link is the following:
http://stackoverflow.com/questions/809362/cumulative-normal-distribution-in-python

RELATED MODELS

Our model starts from the following:
http://eco83.econ.unito.it/terna/simoec13/NetLogo_examples/
g1_CDA_basic_model.nlogo

CREDITS AND REFERENCES

This model was created as a project work for the course of “Simulation Models for Economics” 2012-2013 by Professor Pietro Terna, School of Management and Economics, University of Turin
Pietro Terna: http://web.econ.unito.it/terna/

CODE

; Unlike most things you buy, both the buyer and seller set stock prices. 
; The buyer states what price they will pay for the stock: this is the bid price.
; The seller also has a price: the ask price.

; If you have access to the proper online pricing systems, you can see the bid and 
; ask prices. You will notice that the bid price and the ask price are never the same.
; The ask price is always a little higher than the bid price.

; What this means is if you are buying the stock you pay the ask price (the higher
; price) and if you are selling the stock you receive the bid price (the lower price).

;from http://stocks.about.com/od/tradingbasics/a/bidask101704.htm



breed [randomAgents randomAgent]
breed [slAgents slAgent]
randomAgents-own[buy sell pass price randomPtf randomBuy randomSell]
slAgents-own[buy sell pass price strike d1 d2 Nd1 Nd2 slPtf naked covered]
globals [logB logS exePrice out-of-market priceVector logVector sigma checkStrategy j k p n BScall] 

to setup
  
  clear-all
  if seed != 0 [random-seed seed]
  set exePrice 20000
  set logB []
  set logS []  
  set priceVector [] 
  set logVector []
  set k 1
  reset-ticks
  create-randomAgents nRandomAgents
  create-slAgents nslAgents
  
  
  
ask randomAgents
  [
    set shape "person"
    set out-of-market False
    set size 2
    set randomBuy 1
    set randomSell 0  
  ]
ask SLAgents
[
    set shape "person"
    set out-of-market False
    set buy false
    set sell false
    set size 2
    set strike 20000
    set covered false
    set naked false
    set pass false
  ]


end


to go


if check = "hour" [set checkStrategy 35 ] if check =  "week" [set checkStrategy 1 ] if check = "month" [set checkStrategy 0.25 ] 
ask randomAgents
  [
    ifelse out-of-market [set color white]
    
     [ifelse random-float 1 < passLevel [set pass True][set pass False]
      ifelse not pass
        [ifelse random-float 1 < 0.5 [set buy  True set sell False]
                                     [set sell True set buy  False] ]
        [set buy False set sell False]
       
  
    
     ;set price 501 + random 999
     ;set price random-normal 1000 100
     set price exePrice + (random-normal 0 shock)
     ]

  ]

;use these clearing operationa if a 'go cycle' is 'a day'
;commenting them logs are kept until the end of the simulation experiment
set logB []
set logS []  
    
tick
;show ticks
;NB in future implementation it would be interesting to make empty both the side of 
;   the market at regular intervals of more than one cycle
  
ask turtles
  [if not pass and not out-of-market
     [
       let tmp[]
       set tmp lput price tmp
       set tmp lput who tmp

       if buy [set logB lput tmp logB]
       set logB reverse sort-by [item 0 ?1 < item 0 ?2] logB
       ;show logB
       
       if (not empty? logB and not empty? logS) and
          item 0 (item 0 logB) >= item 0 (item 0 logS)
            [set exePrice item 0 (item 0 logS) 
             set j j + 1 set n n + 1 
             set k k + 1
             ;strategy based on random market prices: SELL
             
             
             
             
             
             set priceVector fput exePrice priceVector
             if length priceVector > 1 
             [let tmp2 ln ( item 0 priceVector / item 1 priceVector )  
             set logVector fput tmp2 logVector]
             if length logVector > 700
             [set logVector butlast logVector 
              set sigma standard-deviation (logVector) * sqrt (36400) 
              ]           

             if k = 700 * T [ ask SLAgents[
                                            set strike exePrice + (random-float 2 - 1) * 200 
                                            
                                                          
                                                         set d1 (ln (exeprice / strike) + (risk-free + ((sigma ^ 2) / 2)) * T) / ( sigma * sqrt ( T ))
                                                         set d2 d1 - sigma * sqrt (T) ;show d1 
                                                         ;show d2
                                                        
                                                         let a d1 / (2 ^ 0.5)
                                                         let b d2 / (2 ^ 0.5)
                                                         set Nd1 1 - 0.5 * erfcc a
                                                         set Nd2 1 - 0.5 * erfcc b
                                                         set BScall exePrice * Nd1 - strike * exp( - risk-free * T ) * Nd2
                                                         
                                                         ifelse exePrice < strike
                                                            [set slPtf slPtf + BScall * (1 - TransactionCost)   set naked true set covered false]
                                                            [set slPtf slPtf + BScall * (1 - TransactionCost)  - exePrice * (1 + TransactionCost)    
                                                             set covered true set naked false set price exePrice set buy true set sell false]
 
                                                        
                                           ]
                                set k 0
                                set p p + 1
                               ]
                                           
                                           
                                           
             
             if j = 700 / checkStrategy  [ ask SLAgents[
                                         
                                        
                                                       if naked and exeprice > strike
                                                         [ 
                                                           set covered true set naked false set slPtf slPtf - exePrice * (1 + TransactionCost)  
                                                           set price strike set buy true set sell false
                                                         ]
                                                       if covered and exeprice < strike
                                                         [
                                                           set naked true set covered false set slPtf slPtf + exeprice * (1 - TransactionCost) 
                                                           set price strike set sell true set buy false
                                                         ]
                  
                                       ]
                           set j 0
                           
                         
                         ]
  
  
   if k = 700 * (T - 1) and p > 0[ ask SLAgents[
                                                           if exePrice > strike
                                                            [
                                                              set slPtf slPtf + strike  * (1 - TransactionCost) 
                                                            ]
                                                        ]
                                          ]      
             
             let agB item 1 (item 0 logB)
             let agS item 1 (item 0 logS) 

             ask randomAgents [
                     if randomBuy >= 1 and random-float 1 < .5  [set randomPtf randomPtf + exeprice
                                        set randomSell randomSell + 1
                                        set randomBuy randomBuy - 1]]
            
             set logB but-first logB
             set logS but-first logS
             ]
       ;show exePrice
       
       if sell [set logS lput tmp logS]
       set logS sort-by [item 0 ?1 < item 0 ?2] logS
       ;show logS
       
       if (not empty? logB and not empty? logS) and
          item 0 (item 0 logB) >= item 0 (item 0 logS)
        [    set exePrice item 0 (item 0 logB) 
             set j j + 1 set n n + 1 
             set k k + 1
             ;strategy based on random market prices: BUY
 
             set priceVector fput exePrice priceVector 
             if length priceVector > 1 
             [let tmp2 ln ( item 0 priceVector / item 1 priceVector ) 
             set logVector fput tmp2 logVector]
             if length logVector > 700 
             [set logVector butlast logVector set sigma standard-deviation (logVector) * sqrt (36400) 
              ]
 
             
             
              if k = 700 * T [ ask SLAgents[
                                            set strike exePrice + (random-float 2 - 1) * 200 
                                            
                                                          
                                                         set d1 (ln (exeprice / strike) + (risk-free + ((sigma ^ 2) / 2)) * T) / ( sigma * sqrt ( T))
                                                         set d2 d1 - sigma * sqrt (T) ;show d1 
                                                         ;show d2
                                                        
                                                         let a d1 / (2 ^ 0.5)
                                                         let b d2 / (2 ^ 0.5)
                                                         set Nd1 1 - 0.5 * erfcc a
                                                         set Nd2 1 - 0.5 * erfcc b
                                                         set BScall exePrice * Nd1 - strike * exp( - risk-free * T ) * Nd2
                                                         
                                                         ifelse exePrice < strike
                                                            [set slPtf slPtf + BScall * (1 - TransactionCost)   set naked true set covered false]
                                                            [set slPtf slPtf + BScall * (1 - TransactionCost)   - exePrice * (1 + TransactionCost)    
                                                              set covered true set naked false set price exePrice set buy true set sell false]
 
                                                        
                                           ]
                                set k 0
                                set p p + 1
                               ]
                                           
                                           
                                           
             
             if j = 700 / checkStrategy  [ ask SLAgents[
                                         
                                        
                                                       if naked and exeprice > strike
                                                         [ 
                                                           set covered true set naked false set slPtf slPtf - exePrice * (1 + TransactionCost)  
                                                           set price strike set buy true set sell false
                                                         ]
                                                       if covered and exeprice < strike
                                                         [
                                                           set naked true set covered false set slPtf slPtf + exeprice * (1 - TransactionCost) 
                                                           set price strike set sell true set buy false
                                                         ]
                  
                                       ]
                           set j 0
                           
                         
                         ]
            
                         
             if k = 700 * (T - 1) and p > 0[ ask SLAgents[
                                                           if exePrice > strike
                                                            [
                                                              set slPtf slPtf + strike * (1 - TransactionCost)   
                                                            ]
                                                        ]
                                          ]      
             
             
             
             let agB item 1 (item 0 logB)
             let agS item 1 (item 0 logS) 
             
             ask randomAgents [
                   if randomSell >= 1 and random-float 1 < .5 [set randomPtf randomPtf - exeprice
                                       set randomSell randomSell - 1
                                       set randomBuy randomBuy + 1]] 
            
             set logB but-first logB
             set logS but-first logS
             ]
       ;show exePrice
        ]
           
     if random-float 1 < out-of-marketLevel 
      [if exePrice > 1500 [set out-of-market False]
      if exePrice <  500 [set out-of-market True]
       ]
     
                   
    graph
  ]
     
end
     


;; Complementary error function
to-report erfcc [x]
        let z abs x
        let q 1.0 / (1.0 + 0.5 * z)
        let r q *  exp ( - z * z - 1.26551223 + q * (1.00002368 + q * (0.37409196 +
            q * (0.09678418 + q * ( - 0.18628806 + q * (0.27886807 +
            q * ( - 1.13520398 + q * (1.48851587 + q * ( - 0.82215223 +
            q * 0.17087277 )))))))))
        ifelse (x >= 0) [ report r ] [report 2.0 - r]
    end

to graph
 
set-current-plot "exePrice"
plot exePrice 

end